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->mTangents || !meshObj->mBitangents || !meshObj->mTextureCoords[0])
224 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.",
226 meshObj->mNormals ?
"" :
" [normals]",
227 meshObj->mTangents ?
"" :
" [tangents]",
228 meshObj->mBitangents ?
"" :
" [bitangents]",
229 meshObj->mTextureCoords[0] ?
"" :
" [texture coordinates]");
231 VuoPoint4d *positions, *normals, *tangents, *bitangents, *textureCoordinates;
232 unsigned int *elements;
233 VuoMesh_allocateCPUBuffers(meshObj->mNumVertices, &positions, &normals, &tangents, &bitangents, &textureCoordinates, meshObj->mNumFaces * 3, &elements);
235 for (
unsigned int vertex = 0; vertex < meshObj->mNumVertices; ++vertex)
237 struct aiVector3D position = meshObj->mVertices[vertex];
238 positions[vertex] =
VuoPoint4d_make(position.x, position.y, position.z, 1);
240 if (meshObj->mNormals)
242 struct aiVector3D normal = meshObj->mNormals[vertex];
246 if (meshObj->mNormals && meshObj->mTangents)
248 struct aiVector3D normal = meshObj->mNormals[vertex];
249 struct aiVector3D tangent = meshObj->mTangents[vertex];
250 tangents[vertex] =
VuoPoint4d_make(tangent.x, tangent.y, tangent.z, 0);
255 bitangents[vertex] =
VuoPoint4d_make(bitangent.x, bitangent.y, bitangent.z, 0);
258 if (meshObj->mTextureCoords[0])
260 struct aiVector3D textureCoordinate = meshObj->mTextureCoords[0][vertex];
261 textureCoordinates[vertex] =
VuoPoint4d_make(textureCoordinate.x, textureCoordinate.y, textureCoordinate.z, 0);
267 unsigned int numValidElements = 0;
268 for (
unsigned int face = 0; face < meshObj->mNumFaces; ++face)
270 const struct aiFace *faceObj = &meshObj->mFaces[face];
271 if (faceObj->mNumIndices != 3)
273 VUserLog(
"Warning: Face %u isn't a triangle (it has %u indices); skipping.",face,faceObj->mNumIndices);
277 elements[numValidElements++] = faceObj->mIndices[0];
278 elements[numValidElements++] = faceObj->mIndices[1];
279 elements[numValidElements++] = faceObj->mIndices[2];
285 if (!meshObj->mTextureCoords[0])
289 if (!meshObj->mTangents && meshObj->mNormals)
292 if (node->mNumMeshes == 1 && node->mNumChildren == 0)
296 shadersUsed[meshObj->mMaterialIndex] =
true;
303 shadersUsed[meshObj->mMaterialIndex] =
true;
307 for (
unsigned int child = 0; child < node->mNumChildren; ++child)
328 struct aiPropertyStore *props = aiCreatePropertyStore();
331 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices);
332 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, maxIndices/3);
335 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices);
336 aiSetImportPropertyInteger(props, AI_CONFIG_PP_SLM_VERTEX_LIMIT, maxVertices);
339 struct aiFileIO fileHandlers;
343 const struct aiScene *ais = aiImportFileExWithProperties(
345 aiProcess_Triangulate
347 | aiProcess_CalcTangentSpace
348 | aiProcess_GenSmoothNormals
349 | aiProcess_SplitLargeMeshes
350 | aiProcess_GenUVCoords,
355 aiReleasePropertyStore(props);
358 VUserLog(
"Error: %s\n", aiGetErrorString());
362 if (ais->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
363 VUserLog(
"Warning: Open Asset Import wasn't able to parse everything in this file.");
373 bool shadersUsed[ais->mNumMaterials];
374 for (
int i=0; i<ais->mNumMaterials; ++i)
376 struct aiMaterial *m = ais->mMaterials[i];
378 struct aiString name;
379 aiGetMaterialString(m, AI_MATKEY_NAME, &name);
390 struct aiColor4D diffuseColorAI = {1,1,1,1};
391 aiGetMaterialColor(m, AI_MATKEY_COLOR_DIFFUSE, &diffuseColorAI);
395 struct aiColor4D specularColorAI = {1,1,1,1};
396 aiGetMaterialColor(m, AI_MATKEY_COLOR_SPECULAR, &specularColorAI);
400 float shininess = 10;
401 aiGetMaterialFloatArray(m, AI_MATKEY_SHININESS, &shininess, NULL);
403 shininess =
MAX(1.0001 - 1./shininess, 0);
406 int diffuseTextures = aiGetMaterialTextureCount(m, aiTextureType_DIFFUSE);
411 struct aiString path;
412 aiGetMaterialTexture(m, aiTextureType_DIFFUSE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
414 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
424 int normalTextures = aiGetMaterialTextureCount(m, aiTextureType_NORMALS);
428 struct aiString path;
429 aiGetMaterialTexture(m, aiTextureType_NORMALS, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
431 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
441 int specularTextures = aiGetMaterialTextureCount(m, aiTextureType_SPECULAR);
443 if (specularTextures)
445 struct aiString path;
446 aiGetMaterialTexture(m, aiTextureType_SPECULAR, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
448 VuoText urlParts[2] = {sceneURLWithoutFilename, path.data};
460 int ambientTextures = aiGetMaterialTextureCount(m, aiTextureType_AMBIENT);
463 struct aiString path;
464 aiGetMaterialTexture(m, aiTextureType_AMBIENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
465 VUserLog(
"\tambient: %s",path.data);
468 int emissiveTextures = aiGetMaterialTextureCount(m, aiTextureType_EMISSIVE);
469 if (emissiveTextures)
471 struct aiString path;
472 aiGetMaterialTexture(m, aiTextureType_EMISSIVE, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
473 VUserLog(
"\temissive: %s",path.data);
476 int opacityTextures = aiGetMaterialTextureCount(m, aiTextureType_OPACITY);
479 struct aiString path;
480 aiGetMaterialTexture(m, aiTextureType_OPACITY, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
481 VUserLog(
"\topacity: %s",path.data);
484 int lightmapTextures = aiGetMaterialTextureCount(m, aiTextureType_LIGHTMAP);
485 if (lightmapTextures)
487 struct aiString path;
488 aiGetMaterialTexture(m, aiTextureType_LIGHTMAP, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
489 VUserLog(
"\tlightmap: %s",path.data);
492 int reflectionTextures = aiGetMaterialTextureCount(m, aiTextureType_REFLECTION);
493 if (reflectionTextures)
495 struct aiString path;
496 aiGetMaterialTexture(m, aiTextureType_REFLECTION, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
497 VUserLog(
"\treflection: %s",path.data);
500 int displacementTextures = aiGetMaterialTextureCount(m, aiTextureType_DISPLACEMENT);
501 if (displacementTextures)
503 struct aiString path;
504 aiGetMaterialTexture(m, aiTextureType_DISPLACEMENT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
505 VUserLog(
"\tdisplacement: %s",path.data);
508 int heightTextures = aiGetMaterialTextureCount(m, aiTextureType_HEIGHT);
511 struct aiString path;
512 aiGetMaterialTexture(m, aiTextureType_HEIGHT, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
516 int unknownTextures = aiGetMaterialTextureCount(m, aiTextureType_UNKNOWN);
519 struct aiString path;
520 aiGetMaterialTexture(m, aiTextureType_UNKNOWN, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL);
521 VUserLog(
"\tunknown: %s",path.data);
525 if (normalImage || specularImage)
541 else if (diffuseImage)
556 shadersUsed[i] =
false;
563 for (
unsigned int i = 0; i < ais->mNumMaterials; ++i)
576 if(hasLeftHandedCoordinates)
587 unsigned int vertexCount, elementCount, *elements;
588 VuoPoint4d *positions;
589 VuoMesh_getCPUBuffers(mesh, &vertexCount, &positions, NULL, NULL, NULL, NULL, &elementCount, &elements);
591 for (
int n = 0; n < vertexCount; n++)
592 positions[n].x *= -1;
598 for(
int i = 0; i < elementCount; i+= 3)
600 unsigned int tmp = elements[i];
601 elements[i] = elements[i+2];
641 aiReleaseImport(ais);