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",
72 if (d->position >= d->dataLength)
78 size_t bytesToRead =
MIN(d->dataLength - d->position, size*count);
79 memcpy(buffer, d->data + d->position, bytesToRead);
81 d->position += bytesToRead;
101 return d->dataLength;
112 size_t proposedPosition;
113 if (origin == aiOrigin_SET)
114 proposedPosition = p;
115 else if (origin == aiOrigin_CUR)
116 proposedPosition = d->position + p;
117 else if (origin == aiOrigin_END)
118 proposedPosition = d->dataLength - p;
120 return aiReturn_FAILURE;
122 if (proposedPosition >= d->dataLength)
123 return aiReturn_FAILURE;
125 d->position = proposedPosition;
126 return aiReturn_SUCCESS;
136 if (strcmp(mode,
"rb") != 0)
138 VUserLog(
"Error: Unknown file mode '%s'",mode);
143 unsigned int dataLength;
150 VUserLog(
"Warning: '%s' is empty", filename);
156 d->dataLength = dataLength;
159 aiFile *af = (aiFile *)malloc(
sizeof(aiFile));
160 af->UserData = (aiUserData)d;
166 af->WriteProc = NULL;
167 af->FlushProc = NULL;
193 struct aiMatrix4x4 m = node->mTransformation;
194 struct aiVector3D scaling;
195 struct aiQuaternion rotation;
196 struct aiVector3D position;
197 aiDecomposeMatrix(&m, &scaling, &rotation, &position);
199 (VuoPoint3d){position.x, position.y, position.z},
200 (VuoPoint4d){rotation.x, rotation.y, rotation.z, rotation.w},
201 (VuoPoint3d){scaling.x, scaling.y, scaling.z}));
206 if (node->mNumMeshes && node->mNumMeshes == 1 && node->mNumChildren == 0)
213 for (
unsigned int meshIndex = 0; meshIndex < node->mNumMeshes; ++meshIndex)
215 const struct aiMesh *meshObj = scene->mMeshes[node->mMeshes[meshIndex]];
217 if (!meshObj->mVertices)
219 VUserLog(
"Error: Mesh '%s' doesn't contain any positions. Skipping.", meshObj->mName.data);
223 if (!meshObj->mNormals || !meshObj->mTextureCoords[0])
224 VUserLog(
"Warning: Mesh '%s' is missing%s%s. These channels will be automatically generated, but lighting and 3D object filters may not work correctly.",
226 meshObj->mNormals ?
"" :
" [normals]",
227 meshObj->mTextureCoords[0] ?
"" :
" [texture coordinates]");
229 float *positions, *normals = NULL, *textureCoordinates = NULL, *colors = NULL;
230 unsigned int *elements;
233 meshObj->mNormals ? &normals : NULL,
234 meshObj->mTextureCoords[0] ? &textureCoordinates : NULL,
235 meshObj->mColors[0] ? &colors : NULL,
236 meshObj->mNumFaces * 3, &elements);
238 for (
unsigned int vertex = 0; vertex < meshObj->mNumVertices; ++vertex)
240 struct aiVector3D position = meshObj->mVertices[vertex];
241 positions[vertex * 3 ] = position.x;
242 positions[vertex * 3 + 1] = position.y;
243 positions[vertex * 3 + 2] = position.z;
245 if (meshObj->mNormals)
247 struct aiVector3D normal = meshObj->mNormals[vertex];
248 normals[vertex * 3 ] = normal.x;
249 normals[vertex * 3 + 1] = normal.y;
250 normals[vertex * 3 + 2] = normal.z;
253 if (meshObj->mTextureCoords[0])
255 struct aiVector3D textureCoordinate = meshObj->mTextureCoords[0][vertex];
256 textureCoordinates[vertex * 2 ] = textureCoordinate.x;
257 textureCoordinates[vertex * 2 + 1] = textureCoordinate.y;
260 if (meshObj->mColors[0])
262 struct aiColor4D color = meshObj->mColors[0][vertex];
263 colors[vertex * 4 ] = color.r;
264 colors[vertex * 4 + 1] = color.g;
265 colors[vertex * 4 + 2] = color.b;
266 colors[vertex * 4 + 3] = color.a;
270 unsigned int numValidElements = 0;
271 for (
unsigned int face = 0; face < meshObj->mNumFaces; ++face)
273 const struct aiFace *faceObj = &meshObj->mFaces[face];
274 if (faceObj->mNumIndices != 3)
276 VUserLog(
"Warning: Face %u isn't a triangle (it has %u indices); skipping.",face,faceObj->mNumIndices);
280 elements[numValidElements++] = faceObj->mIndices[0];
281 elements[numValidElements++] = faceObj->mIndices[1];
282 elements[numValidElements++] = faceObj->mIndices[2];
288 if (!meshObj->mTextureCoords[0])
291 if (node->mNumMeshes == 1 && node->mNumChildren == 0)
295 shadersUsed[meshObj->mMaterialIndex] =
true;
302 shadersUsed[meshObj->mMaterialIndex] =
true;
306 for (
unsigned int child = 0; child < node->mNumChildren; ++child)
327 struct aiPropertyStore *props = aiCreatePropertyStore();
330 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices);
331 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, maxIndices/3);
334 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices);
335 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_VERTEX_LIMIT, maxVertices);
337 static bool limitsLogged =
false;
341 VDebugLog(
"OpenGL driver reports maxIndices=%d, maxVertices=%d", maxIndices, maxVertices);
345 struct aiFileIO fileHandlers;
349 const struct aiScene *ais = aiImportFileExWithProperties(
351 aiProcess_Triangulate
354 | aiProcess_GenSmoothNormals
355 | aiProcess_SplitLargeMeshes
356 | aiProcess_GenUVCoords,
361 aiReleasePropertyStore(props);
364 VUserLog(
"Error: %s", aiGetErrorString());
368 if (ais->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
369 VUserLog(
"Warning: Open Asset Import wasn't able to parse everything in this file.");
379 bool shadersUsed[ais->mNumMaterials];
380 for (
int i=0; i<ais->mNumMaterials; ++i)
382 struct aiMaterial *m = ais->mMaterials[i];
384 struct aiString name;
385 aiGetMaterialString(m, AI_MATKEY_NAME, &name);
396 struct aiColor4D diffuseColorAI = {1,1,1,1};
397 aiGetMaterialColor(m, AI_MATKEY_COLOR_DIFFUSE, &diffuseColorAI);
401 struct aiColor4D specularColorAI = {1,1,1,1};
402 aiGetMaterialColor(m, AI_MATKEY_COLOR_SPECULAR, &specularColorAI);
406 float shininess = 10;
407 aiGetMaterialFloatArray(m, AI_MATKEY_SHININESS, &shininess, NULL);
409 shininess =
MAX(1.0001 - 1./shininess, 0);
412 int diffuseTextures = aiGetMaterialTextureCount(m, aiTextureType_DIFFUSE);
417 struct aiString path;
418 aiGetMaterialTexture(m, aiTextureType_DIFFUSE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
420 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
430 int normalTextures = aiGetMaterialTextureCount(m, aiTextureType_NORMALS);
434 struct aiString path;
435 aiGetMaterialTexture(m, aiTextureType_NORMALS, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
437 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
447 int specularTextures = aiGetMaterialTextureCount(m, aiTextureType_SPECULAR);
449 if (specularTextures)
451 struct aiString path;
452 aiGetMaterialTexture(m, aiTextureType_SPECULAR, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
454 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
466 int ambientTextures = aiGetMaterialTextureCount(m, aiTextureType_AMBIENT);
469 struct aiString path;
470 aiGetMaterialTexture(m, aiTextureType_AMBIENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
471 VUserLog(
"\tambient: %s",path.data);
474 int emissiveTextures = aiGetMaterialTextureCount(m, aiTextureType_EMISSIVE);
475 if (emissiveTextures)
477 struct aiString path;
478 aiGetMaterialTexture(m, aiTextureType_EMISSIVE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
479 VUserLog(
"\temissive: %s",path.data);
482 int opacityTextures = aiGetMaterialTextureCount(m, aiTextureType_OPACITY);
485 struct aiString path;
486 aiGetMaterialTexture(m, aiTextureType_OPACITY, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
487 VUserLog(
"\topacity: %s",path.data);
490 int lightmapTextures = aiGetMaterialTextureCount(m, aiTextureType_LIGHTMAP);
491 if (lightmapTextures)
493 struct aiString path;
494 aiGetMaterialTexture(m, aiTextureType_LIGHTMAP, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
495 VUserLog(
"\tlightmap: %s",path.data);
498 int reflectionTextures = aiGetMaterialTextureCount(m, aiTextureType_REFLECTION);
499 if (reflectionTextures)
501 struct aiString path;
502 aiGetMaterialTexture(m, aiTextureType_REFLECTION, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
503 VUserLog(
"\treflection: %s",path.data);
506 int displacementTextures = aiGetMaterialTextureCount(m, aiTextureType_DISPLACEMENT);
507 if (displacementTextures)
509 struct aiString path;
510 aiGetMaterialTexture(m, aiTextureType_DISPLACEMENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
511 VUserLog(
"\tdisplacement: %s",path.data);
514 int heightTextures = aiGetMaterialTextureCount(m, aiTextureType_HEIGHT);
517 struct aiString path;
518 aiGetMaterialTexture(m, aiTextureType_HEIGHT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
522 int unknownTextures = aiGetMaterialTextureCount(m, aiTextureType_UNKNOWN);
525 struct aiString path;
526 aiGetMaterialTexture(m, aiTextureType_UNKNOWN, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
527 VUserLog(
"\tunknown: %s",path.data);
531 if (normalImage || specularImage)
547 else if (diffuseImage)
562 shadersUsed[i] =
false;
569 for (
unsigned int i = 0; i < ais->mNumMaterials; ++i)
582 if(hasLeftHandedCoordinates)
593 unsigned int vertexCount, elementCount, *elements;
597 for (
int n = 0; n < vertexCount; n++)
598 positions[n * 3] *= -1;
604 for(
int i = 0; i < elementCount; i+= 3)
606 unsigned int tmp = elements[i];
607 elements[i] = elements[i+2];
647 aiReleaseImport(ais);