forked from AcademySoftwareFoundation/MaterialX
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.cpp
More file actions
322 lines (303 loc) · 12.7 KB
/
Main.cpp
File metadata and controls
322 lines (303 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#include <MaterialXView/Viewer.h>
#include <MaterialXRender/Util.h>
#include <MaterialXCore/Util.h>
#include <iostream>
NANOGUI_FORCE_DISCRETE_GPU();
const std::string options =
" Options: \n"
" --material [FILENAME] Specify the filename of the MTLX document to be displayed in the viewer\n"
" --mesh [FILENAME] Specify the filename of the OBJ mesh to be displayed in the viewer\n"
" --meshRotation [VECTOR3] Specify the rotation of the displayed mesh as three comma-separated floats, representing rotations in degrees about the X, Y, and Z axes (defaults to 0,0,0)\n"
" --meshScale [FLOAT] Specify the uniform scale of the displayed mesh\n"
" --enableTurntable[BOOLEAN] Specify whether to enable turntable rendering of the scene\n"
" --turntableSteps [INTEGER] Specify the number of steps for a complete turntable rotation. Defaults to 360\n"
" --cameraPosition [VECTOR3] Specify the position of the camera as three comma-separated floats (defaults to 0,0,5)\n"
" --cameraTarget [VECTOR3] Specify the position of the camera target as three comma-separated floats (defaults to 0,0,0)\n"
" --cameraViewAngle [FLOAT] Specify the view angle of the camera, or zero for an orthographic projection (defaults to 45)\n"
" --cameraZoom [FLOAT] Specify the zoom factor for the camera, implemented as a mesh scale multiplier (defaults to 1)\n"
" --envRad [FILENAME] Specify the filename of the environment light to display, stored as HDR environment radiance in the latitude-longitude format\n"
" --envMethod [INTEGER] Specify the environment lighting method (0 = filtered importance sampling, 1 = prefiltered environment maps, defaults to 0)\n"
" --envSampleCount [INTEGER] Specify the environment sample count (defaults to 16)\n"
" --lightRotation [FLOAT] Specify the rotation in degrees of the lighting environment about the Y axis (defaults to 0)\n"
" --shadowMap [BOOLEAN] Specify whether shadow mapping is enabled (defaults to true)\n"
" --path [FILEPATH] Specify an additional absolute search path location (e.g. '/projects/MaterialX'). This path will be queried when locating standard data libraries, XInclude references, and referenced images.\n"
" --library [FILEPATH] Specify an additional relative path to a custom data library folder (e.g. 'libraries/custom'). MaterialX files at the root of this folder will be included in all content documents.\n"
" --screenWidth [INTEGER] Specify the width of the screen image in pixels (defaults to 1280)\n"
" --screenHeight [INTEGER] Specify the height of the screen image in pixels (defaults to 960)\n"
" --screenColor [VECTOR3] Specify the background color of the viewer as three comma-separated floats (defaults to 0.3,0.3,0.32)\n"
" --drawEnvironment [BOOLEAN] Specify whether to render the environment as the background (defaults to false)\n"
" --captureFilename [FILENAME] Specify the filename to which the first rendered frame should be written\n"
" --bakeWidth [INTEGER] Specify the target width for texture baking (defaults to maximum image width of the source document)\n"
" --bakeHeight [INTEGER] Specify the target height for texture baking (defaults to maximum image height of the source document)\n"
" --bakeFilename [STRING] Specify the output document filename for texture baking\n"
" --refresh [FLOAT] Specify the refresh period for the viewer in milliseconds (defaults to 50, set to -1 to disable)\n"
" --remap [TOKEN1:TOKEN2] Specify the remapping from one token to another when MaterialX document is loaded\n"
" --skip [NAME] Specify to skip elements matching the given name attribute\n"
" --terminator [STRING] Specify to enforce the given terminator string for file prefixes\n"
" --help Display the complete list of command-line options\n";
template<class T> void parseToken(std::string token, std::string type, T& res)
{
if (token.empty())
{
return;
}
mx::ValuePtr value = mx::Value::createValueFromStrings(token, type);
if (!value)
{
std::cout << "Unable to parse token " << token << " as type " << type << std::endl;
return;
}
res = value->asA<T>();
}
mx::FileSearchPath getDefaultSearchPath()
{
mx::FilePath modulePath = mx::FilePath::getModulePath();
mx::FilePath installRootPath = modulePath.getParentPath();
mx::FilePath devRootPath = installRootPath.getParentPath().getParentPath();
mx::FileSearchPath searchPath;
if ((devRootPath / "libraries").exists())
{
searchPath.append(devRootPath);
}
else
{
searchPath.append(installRootPath);
}
return searchPath;
}
int main(int argc, char* const argv[])
{
std::vector<std::string> tokens;
for (int i = 1; i < argc; i++)
{
tokens.emplace_back(argv[i]);
}
std::string materialFilename = "resources/Materials/Examples/StandardSurface/standard_surface_default.mtlx";
std::string meshFilename = "resources/Geometry/shaderball.glb";
std::string envRadianceFilename = "resources/Lights/san_giuseppe_bridge_split.hdr";
mx::FileSearchPath searchPath = getDefaultSearchPath();
mx::FilePathVec libraryFolders;
mx::Vector3 meshRotation;
float meshScale = 1.0f;
bool turntableEnabled = false;
int turntableSteps = 360;
mx::Vector3 cameraPosition(DEFAULT_CAMERA_POSITION);
mx::Vector3 cameraTarget;
float cameraViewAngle(DEFAULT_CAMERA_VIEW_ANGLE);
float cameraZoom(DEFAULT_CAMERA_ZOOM);
mx::HwSpecularEnvironmentMethod specularEnvironmentMethod = mx::SPECULAR_ENVIRONMENT_FIS;
int envSampleCount = mx::DEFAULT_ENV_SAMPLE_COUNT;
float lightRotation = 0.0f;
bool shadowMap = true;
DocumentModifiers modifiers;
int screenWidth = 1280;
int screenHeight = 960;
mx::Color3 screenColor(mx::DEFAULT_SCREEN_COLOR_SRGB);
bool drawEnvironment = false;
std::string captureFilename;
int bakeWidth = 0;
int bakeHeight = 0;
std::string bakeFilename;
float refresh = 50.0f;
for (size_t i = 0; i < tokens.size(); i++)
{
const std::string& token = tokens[i];
const std::string& nextToken = i + 1 < tokens.size() ? tokens[i + 1] : mx::EMPTY_STRING;
if (token == "--material")
{
materialFilename = nextToken;
}
else if (token == "--mesh")
{
meshFilename = nextToken;
}
else if (token == "--envRad")
{
envRadianceFilename = nextToken;
}
else if (token == "--meshRotation")
{
parseToken(nextToken, "vector3", meshRotation);
}
else if (token == "--meshScale")
{
parseToken(nextToken, "float", meshScale);
}
else if (token == "--enableTurntable")
{
parseToken(nextToken, "boolean", turntableEnabled);
}
else if (token == "--turntableSteps")
{
parseToken(nextToken, "integer", turntableSteps);
turntableSteps = std::clamp(turntableSteps, 2, 360);;
}
else if (token == "--cameraPosition")
{
parseToken(nextToken, "vector3", cameraPosition);
}
else if (token == "--cameraTarget")
{
parseToken(nextToken, "vector3", cameraTarget);
}
else if (token == "--cameraViewAngle")
{
parseToken(nextToken, "float", cameraViewAngle);
}
else if (token == "--cameraZoom")
{
parseToken(nextToken, "float", cameraZoom);
}
else if (token == "--envMethod")
{
if (std::stoi(nextToken) == 1)
{
specularEnvironmentMethod = mx::SPECULAR_ENVIRONMENT_PREFILTER;
}
}
else if (token == "--envSampleCount")
{
parseToken(nextToken, "integer", envSampleCount);
}
else if (token == "--lightRotation")
{
parseToken(nextToken, "float", lightRotation);
}
else if (token == "--shadowMap")
{
parseToken(nextToken, "boolean", shadowMap);
}
else if (token == "--path")
{
searchPath.append(mx::FileSearchPath(nextToken));
}
else if (token == "--library")
{
libraryFolders.push_back(nextToken);
}
else if (token == "--screenWidth")
{
parseToken(nextToken, "integer", screenWidth);
}
else if (token == "--screenHeight")
{
parseToken(nextToken, "integer", screenHeight);
}
else if (token == "--screenColor")
{
parseToken(nextToken, "color3", screenColor);
}
else if (token == "--drawEnvironment")
{
parseToken(nextToken, "boolean", drawEnvironment);
}
else if (token == "--captureFilename")
{
parseToken(nextToken, "string", captureFilename);
}
else if (token == "--bakeWidth")
{
parseToken(nextToken, "integer", bakeWidth);
}
else if (token == "--bakeHeight")
{
parseToken(nextToken, "integer", bakeHeight);
}
else if (token == "--bakeFilename")
{
parseToken(nextToken, "string", bakeFilename);
}
else if (token == "--refresh")
{
parseToken(nextToken, "float", refresh);
}
else if (token == "--remap")
{
mx::StringVec vec = mx::splitString(nextToken, ":");
if (vec.size() == 2)
{
modifiers.remapElements[vec[0]] = vec[1];
}
else if (!nextToken.empty())
{
std::cout << "Unable to parse token following command-line option: " << token << std::endl;
}
}
else if (token == "--skip")
{
modifiers.skipElements.insert(nextToken);
}
else if (token == "--terminator")
{
modifiers.filePrefixTerminator = nextToken;
}
else if (token == "--help")
{
std::cout << " MaterialXView version " << mx::getVersionString() << std::endl;
std::cout << options << std::endl;
return 0;
}
else
{
std::cout << "Unrecognized command-line option: " << token << std::endl;
std::cout << "Launch the viewer with '--help' for a complete list of supported options." << std::endl;
continue;
}
if (nextToken.empty())
{
std::cout << "Expected another token following command-line option: " << token << std::endl;
}
else
{
i++;
}
}
// Append the standard library folder, giving it a lower precedence than user-supplied libraries.
libraryFolders.push_back("libraries");
ng::init();
{
ng::ref<Viewer> viewer = new Viewer(materialFilename,
meshFilename,
envRadianceFilename,
searchPath,
libraryFolders,
screenWidth,
screenHeight,
screenColor);
viewer->setMeshRotation(meshRotation);
viewer->setMeshScale(meshScale);
viewer->setTurntableEnabled(turntableEnabled);
viewer->setTurntableSteps(turntableSteps);
viewer->setCameraPosition(cameraPosition);
viewer->setCameraTarget(cameraTarget);
viewer->setCameraViewAngle(cameraViewAngle);
viewer->setCameraZoom(cameraZoom);
viewer->setSpecularEnvironmentMethod(specularEnvironmentMethod);
viewer->setEnvSampleCount(envSampleCount);
viewer->setLightRotation(lightRotation);
viewer->setShadowMapEnable(shadowMap);
viewer->setDrawEnvironment(drawEnvironment);
viewer->setDocumentModifiers(modifiers);
viewer->setBakeWidth(bakeWidth);
viewer->setBakeHeight(bakeHeight);
viewer->setBakeFilename(bakeFilename);
viewer->initialize();
if (!bakeFilename.empty())
{
viewer->bakeTextures();
viewer->requestExit();
}
else
{
viewer->set_visible(true);
}
if (!captureFilename.empty())
{
viewer->requestFrameCapture(captureFilename);
viewer->requestExit();
}
ng::mainloop(refresh);
}
ng::shutdown();
return 0;
}