16#include <OpenGL/CGLMacro.h>
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wdocumentation"
23 #include <postprocess.h>
27 typedef enum aiOrigin aiOrigin;
28 typedef struct aiFile aiFile;
29 typedef struct aiFileIO aiFileIO;
32#pragma clang diagnostic pop
38 "title" :
"VuoSceneGet",
73 if (d->position >= d->dataLength)
79 size_t bytesToRead =
MIN(d->dataLength - d->position, size*count);
80 memcpy(buffer, d->data + d->position, bytesToRead);
82 d->position += bytesToRead;
102 return d->dataLength;
113 size_t proposedPosition;
114 if (origin == aiOrigin_SET)
115 proposedPosition = p;
116 else if (origin == aiOrigin_CUR)
117 proposedPosition = d->position + p;
118 else if (origin == aiOrigin_END)
119 proposedPosition = d->dataLength - p;
121 return aiReturn_FAILURE;
123 if (proposedPosition >= d->dataLength)
124 return aiReturn_FAILURE;
126 d->position = proposedPosition;
127 return aiReturn_SUCCESS;
137 if (strcmp(mode,
"rb") != 0)
139 VUserLog(
"Error: Unknown file mode '%s'",mode);
144 unsigned int dataLength;
153 VUserLog(
"Warning: '%s' is empty", filename);
159 d->dataLength = dataLength;
162 aiFile *af = (aiFile *)malloc(
sizeof(aiFile));
163 af->UserData = (aiUserData)d;
169 af->WriteProc = NULL;
170 af->FlushProc = NULL;
196 struct aiMatrix4x4 m = node->mTransformation;
197 struct aiVector3D scaling;
198 struct aiQuaternion rotation;
199 struct aiVector3D position;
200 aiDecomposeMatrix(&m, &scaling, &rotation, &position);
202 (VuoPoint3d){position.x, position.y, position.z},
203 (VuoPoint4d){rotation.x, rotation.y, rotation.z, rotation.w},
204 (VuoPoint3d){scaling.x, scaling.y, scaling.z}));
209 if (node->mNumMeshes && node->mNumMeshes == 1 && node->mNumChildren == 0)
216 for (
unsigned int meshIndex = 0; meshIndex < node->mNumMeshes; ++meshIndex)
218 const struct aiMesh *meshObj = scene->mMeshes[node->mMeshes[meshIndex]];
220 if (!meshObj->mVertices)
222 VUserLog(
"Error: Mesh '%s' doesn't contain any positions. Skipping.", meshObj->mName.data);
226 if (!meshObj->mNormals || !meshObj->mTextureCoords[0])
227 VUserLog(
"Warning: Mesh '%s' is missing%s%s. These channels will be automatically generated, but lighting and 3D object filters may not work correctly.",
229 meshObj->mNormals ?
"" :
" [normals]",
230 meshObj->mTextureCoords[0] ?
"" :
" [texture coordinates]");
232 float *positions, *normals = NULL, *textureCoordinates = NULL, *colors = NULL;
233 unsigned int *elements;
236 meshObj->mNormals ? &normals : NULL,
237 meshObj->mTextureCoords[0] ? &textureCoordinates : NULL,
238 meshObj->mColors[0] ? &colors : NULL,
239 meshObj->mNumFaces * 3, &elements);
241 for (
unsigned int vertex = 0; vertex < meshObj->mNumVertices; ++vertex)
243 struct aiVector3D position = meshObj->mVertices[vertex];
244 positions[vertex * 3 ] = position.x;
245 positions[vertex * 3 + 1] = position.y;
246 positions[vertex * 3 + 2] = position.z;
248 if (meshObj->mNormals)
250 struct aiVector3D normal = meshObj->mNormals[vertex];
251 normals[vertex * 3 ] = normal.x;
252 normals[vertex * 3 + 1] = normal.y;
253 normals[vertex * 3 + 2] = normal.z;
256 if (meshObj->mTextureCoords[0])
258 struct aiVector3D textureCoordinate = meshObj->mTextureCoords[0][vertex];
259 textureCoordinates[vertex * 2 ] = textureCoordinate.x;
260 textureCoordinates[vertex * 2 + 1] = textureCoordinate.y;
263 if (meshObj->mColors[0])
265 struct aiColor4D color = meshObj->mColors[0][vertex];
266 colors[vertex * 4 ] = color.r;
267 colors[vertex * 4 + 1] = color.g;
268 colors[vertex * 4 + 2] = color.b;
269 colors[vertex * 4 + 3] = color.a;
273 unsigned int numValidElements = 0;
274 for (
unsigned int face = 0; face < meshObj->mNumFaces; ++face)
276 const struct aiFace *faceObj = &meshObj->mFaces[face];
277 if (faceObj->mNumIndices != 3)
279 VUserLog(
"Warning: Face %u isn't a triangle (it has %u indices); skipping.",face,faceObj->mNumIndices);
283 elements[numValidElements++] = faceObj->mIndices[0];
284 elements[numValidElements++] = faceObj->mIndices[1];
285 elements[numValidElements++] = faceObj->mIndices[2];
291 if (!meshObj->mTextureCoords[0])
294 if (node->mNumMeshes == 1 && node->mNumChildren == 0)
298 shadersUsed[meshObj->mMaterialIndex] =
true;
305 shadersUsed[meshObj->mMaterialIndex] =
true;
309 for (
unsigned int child = 0; child < node->mNumChildren; ++child)
330 struct aiPropertyStore *props = aiCreatePropertyStore();
333 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices);
334 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, maxIndices/3);
337 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices);
338 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_VERTEX_LIMIT, maxVertices);
340 static bool limitsLogged =
false;
344 VDebugLog(
"OpenGL driver reports maxIndices=%d, maxVertices=%d", maxIndices, maxVertices);
348 struct aiFileIO fileHandlers;
352 const struct aiScene *ais = aiImportFileExWithProperties(
354 aiProcess_Triangulate
357 | aiProcess_GenSmoothNormals
358 | aiProcess_SplitLargeMeshes
359 | aiProcess_GenUVCoords,
364 aiReleasePropertyStore(props);
367 VUserLog(
"Error: %s", aiGetErrorString());
371 if (ais->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
372 VUserLog(
"Warning: Open Asset Import wasn't able to parse everything in this file.");
382 bool shadersUsed[ais->mNumMaterials];
383 for (
int i=0; i<ais->mNumMaterials; ++i)
385 struct aiMaterial *m = ais->mMaterials[i];
387 struct aiString name;
388 aiGetMaterialString(m, AI_MATKEY_NAME, &name);
399 struct aiColor4D diffuseColorAI = {1,1,1,1};
400 aiGetMaterialColor(m, AI_MATKEY_COLOR_DIFFUSE, &diffuseColorAI);
404 struct aiColor4D specularColorAI = {1,1,1,1};
405 aiGetMaterialColor(m, AI_MATKEY_COLOR_SPECULAR, &specularColorAI);
409 float shininess = 10;
410 aiGetMaterialFloatArray(m, AI_MATKEY_SHININESS, &shininess, NULL);
412 shininess =
MAX(1.0001 - 1./shininess, 0);
415 int diffuseTextures = aiGetMaterialTextureCount(m, aiTextureType_DIFFUSE);
420 struct aiString path;
421 aiGetMaterialTexture(m, aiTextureType_DIFFUSE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
423 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
433 int normalTextures = aiGetMaterialTextureCount(m, aiTextureType_NORMALS);
437 struct aiString path;
438 aiGetMaterialTexture(m, aiTextureType_NORMALS, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
440 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
450 int specularTextures = aiGetMaterialTextureCount(m, aiTextureType_SPECULAR);
452 if (specularTextures)
454 struct aiString path;
455 aiGetMaterialTexture(m, aiTextureType_SPECULAR, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
457 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
469 int ambientTextures = aiGetMaterialTextureCount(m, aiTextureType_AMBIENT);
472 struct aiString path;
473 aiGetMaterialTexture(m, aiTextureType_AMBIENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
474 VUserLog(
"\tambient: %s",path.data);
477 int emissiveTextures = aiGetMaterialTextureCount(m, aiTextureType_EMISSIVE);
478 if (emissiveTextures)
480 struct aiString path;
481 aiGetMaterialTexture(m, aiTextureType_EMISSIVE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
482 VUserLog(
"\temissive: %s",path.data);
485 int opacityTextures = aiGetMaterialTextureCount(m, aiTextureType_OPACITY);
488 struct aiString path;
489 aiGetMaterialTexture(m, aiTextureType_OPACITY, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
490 VUserLog(
"\topacity: %s",path.data);
493 int lightmapTextures = aiGetMaterialTextureCount(m, aiTextureType_LIGHTMAP);
494 if (lightmapTextures)
496 struct aiString path;
497 aiGetMaterialTexture(m, aiTextureType_LIGHTMAP, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
498 VUserLog(
"\tlightmap: %s",path.data);
501 int reflectionTextures = aiGetMaterialTextureCount(m, aiTextureType_REFLECTION);
502 if (reflectionTextures)
504 struct aiString path;
505 aiGetMaterialTexture(m, aiTextureType_REFLECTION, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
506 VUserLog(
"\treflection: %s",path.data);
509 int displacementTextures = aiGetMaterialTextureCount(m, aiTextureType_DISPLACEMENT);
510 if (displacementTextures)
512 struct aiString path;
513 aiGetMaterialTexture(m, aiTextureType_DISPLACEMENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
514 VUserLog(
"\tdisplacement: %s",path.data);
517 int heightTextures = aiGetMaterialTextureCount(m, aiTextureType_HEIGHT);
520 struct aiString path;
521 aiGetMaterialTexture(m, aiTextureType_HEIGHT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
525 int unknownTextures = aiGetMaterialTextureCount(m, aiTextureType_UNKNOWN);
528 struct aiString path;
529 aiGetMaterialTexture(m, aiTextureType_UNKNOWN, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
530 VUserLog(
"\tunknown: %s",path.data);
534 if (normalImage || specularImage)
550 else if (diffuseImage)
565 shadersUsed[i] =
false;
572 for (
unsigned int i = 0; i < ais->mNumMaterials; ++i)
585 if(hasLeftHandedCoordinates)
596 unsigned int vertexCount, elementCount, *elements;
600 for (
int n = 0; n < vertexCount; n++)
601 positions[n * 3] *= -1;
607 for(
int i = 0; i < elementCount; i+= 3)
609 unsigned int tmp = elements[i];
610 elements[i] = elements[i+2];
650 aiReleaseImport(ais);