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);
207 if (node->mNumMeshes)
209 if (node->mNumMeshes == 1)
211 sceneObject->type = VuoSceneObjectSubType_Mesh;
216 sceneObject->type = VuoSceneObjectSubType_Group;
220 for (
unsigned int meshIndex = 0; meshIndex < node->mNumMeshes; ++meshIndex)
222 const struct aiMesh *meshObj = scene->mMeshes[node->mMeshes[meshIndex]];
224 if (!meshObj->mVertices)
226 VUserLog(
"Error: Mesh '%s' doesn't contain any positions. Skipping.", meshObj->mName.data);
230 if (!meshObj->mNormals || !meshObj->mTangents || !meshObj->mBitangents || !meshObj->mTextureCoords[0])
231 VUserLog(
"Warning: Mesh '%s' is missing%s%s%s%s. These channels will be automatically generated, but lighting and 3D object filters may not work correctly.",
233 meshObj->mNormals ?
"" :
" [normals]",
234 meshObj->mTangents ?
"" :
" [tangents]",
235 meshObj->mBitangents ?
"" :
" [bitangents]",
236 meshObj->mTextureCoords[0] ?
"" :
" [texture coordinates]");
241 for (
unsigned int vertex = 0; vertex < meshObj->mNumVertices; ++vertex)
243 struct aiVector3D position = meshObj->mVertices[vertex];
246 if (meshObj->mNormals)
248 struct aiVector3D normal = meshObj->mNormals[vertex];
252 if (meshObj->mNormals && meshObj->mTangents)
254 struct aiVector3D normal = meshObj->mNormals[vertex];
255 struct aiVector3D tangent = meshObj->mTangents[vertex];
264 if (meshObj->mTextureCoords[0])
266 struct aiVector3D textureCoordinate = meshObj->mTextureCoords[0][vertex];
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 sm.
elements[numValidElements++] = faceObj->mIndices[0];
284 sm.
elements[numValidElements++] = faceObj->mIndices[1];
285 sm.
elements[numValidElements++] = faceObj->mIndices[2];
300 if (node->mNumMeshes == 1)
305 sceneObject->shader = shaders[meshObj->mMaterialIndex];
306 shadersUsed[meshObj->mMaterialIndex] =
true;
316 shadersUsed[meshObj->mMaterialIndex] =
true;
320 if (node->mNumChildren)
322 if (!sceneObject->childObjects)
324 if (sceneObject->type == VuoSceneObjectSubType_Empty)
325 sceneObject->type = VuoSceneObjectSubType_Group;
327 for (
unsigned int child = 0; child < node->mNumChildren; ++child)
331 if (childSceneObject.type != VuoSceneObjectSubType_Empty)
349 struct aiPropertyStore *props = aiCreatePropertyStore();
352 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices);
353 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, maxIndices/3);
356 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices);
357 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_VERTEX_LIMIT, maxVertices);
360 struct aiFileIO fileHandlers;
364 const struct aiScene *ais = aiImportFileExWithProperties(
366 aiProcess_Triangulate
368 | aiProcess_CalcTangentSpace
369 | aiProcess_GenSmoothNormals
370 | aiProcess_SplitLargeMeshes
371 | aiProcess_GenUVCoords,
376 aiReleasePropertyStore(props);
379 VUserLog(
"Error: %s\n", aiGetErrorString());
383 if (ais->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
384 VUserLog(
"Warning: Open Asset Import wasn't able to parse everything in this file.");
394 bool shadersUsed[ais->mNumMaterials];
395 for (
int i=0; i<ais->mNumMaterials; ++i)
397 struct aiMaterial *m = ais->mMaterials[i];
399 struct aiString name;
400 aiGetMaterialString(m, AI_MATKEY_NAME, &name);
411 struct aiColor4D diffuseColorAI = {1,1,1,1};
412 aiGetMaterialColor(m, AI_MATKEY_COLOR_DIFFUSE, &diffuseColorAI);
416 struct aiColor4D specularColorAI = {1,1,1,1};
417 aiGetMaterialColor(m, AI_MATKEY_COLOR_SPECULAR, &specularColorAI);
421 float shininess = 10;
422 aiGetMaterialFloatArray(m, AI_MATKEY_SHININESS, &shininess, NULL);
424 shininess =
MAX(1.0001 - 1./shininess, 0);
427 int diffuseTextures = aiGetMaterialTextureCount(m, aiTextureType_DIFFUSE);
432 struct aiString path;
433 aiGetMaterialTexture(m, aiTextureType_DIFFUSE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
435 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
445 int normalTextures = aiGetMaterialTextureCount(m, aiTextureType_NORMALS);
449 struct aiString path;
450 aiGetMaterialTexture(m, aiTextureType_NORMALS, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
452 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
462 int specularTextures = aiGetMaterialTextureCount(m, aiTextureType_SPECULAR);
464 if (specularTextures)
466 struct aiString path;
467 aiGetMaterialTexture(m, aiTextureType_SPECULAR, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
469 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
481 int ambientTextures = aiGetMaterialTextureCount(m, aiTextureType_AMBIENT);
484 struct aiString path;
485 aiGetMaterialTexture(m, aiTextureType_AMBIENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
486 VUserLog(
"\tambient: %s",path.data);
489 int emissiveTextures = aiGetMaterialTextureCount(m, aiTextureType_EMISSIVE);
490 if (emissiveTextures)
492 struct aiString path;
493 aiGetMaterialTexture(m, aiTextureType_EMISSIVE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
494 VUserLog(
"\temissive: %s",path.data);
497 int opacityTextures = aiGetMaterialTextureCount(m, aiTextureType_OPACITY);
500 struct aiString path;
501 aiGetMaterialTexture(m, aiTextureType_OPACITY, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
502 VUserLog(
"\topacity: %s",path.data);
505 int lightmapTextures = aiGetMaterialTextureCount(m, aiTextureType_LIGHTMAP);
506 if (lightmapTextures)
508 struct aiString path;
509 aiGetMaterialTexture(m, aiTextureType_LIGHTMAP, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
510 VUserLog(
"\tlightmap: %s",path.data);
513 int reflectionTextures = aiGetMaterialTextureCount(m, aiTextureType_REFLECTION);
514 if (reflectionTextures)
516 struct aiString path;
517 aiGetMaterialTexture(m, aiTextureType_REFLECTION, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
518 VUserLog(
"\treflection: %s",path.data);
521 int displacementTextures = aiGetMaterialTextureCount(m, aiTextureType_DISPLACEMENT);
522 if (displacementTextures)
524 struct aiString path;
525 aiGetMaterialTexture(m, aiTextureType_DISPLACEMENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
526 VUserLog(
"\tdisplacement: %s",path.data);
529 int heightTextures = aiGetMaterialTextureCount(m, aiTextureType_HEIGHT);
532 struct aiString path;
533 aiGetMaterialTexture(m, aiTextureType_HEIGHT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
537 int unknownTextures = aiGetMaterialTextureCount(m, aiTextureType_UNKNOWN);
540 struct aiString path;
541 aiGetMaterialTexture(m, aiTextureType_UNKNOWN, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
542 VUserLog(
"\tunknown: %s",path.data);
546 if (normalImage || specularImage)
562 else if (diffuseImage)
577 shadersUsed[i] =
false;
583 for (
unsigned int i = 0; i < ais->mNumMaterials; ++i)
596 if(hasLeftHandedCoordinates)
604 if(currentObject->mesh != NULL)
606 for(int i = 0; i < currentObject->mesh->submeshCount; i++)
608 VuoSubmesh msh = currentObject->mesh->submeshes[i];
609 for(int n = 0; n < msh.vertexCount; n++)
611 msh.positions[n].x *= -1;
615 switch(msh.elementAssemblyMethod)
617 case VuoMesh_IndividualTriangles:
619 unsigned int elementCount = msh.elementCount;
620 for(int i = 0; i < elementCount; i+= 3)
622 unsigned int tmp = msh.elements[i];
623 msh.elements[i] = msh.elements[i+2];
624 msh.elements[i+2] = tmp;
665 aiReleaseImport(ais);