//------------------------------------------------------------------------------- internal static int[] Face(Interface.DynamicArray <aiFace> assimp, out MeshTopology topology) { uint size = assimp.Size(); topology = MeshTopology.Triangles; uint nb_faces = 3; if (size > 0) { // Get the topology from the first face (because option aiProcess_SortByPType is mandatory, all faces have the same topology) using (aiFace face = assimp.Get(0)) { using (aiUIntArray indices = face.Indices) { switch (indices.Size()) { case 1: topology = MeshTopology.Points; nb_faces = 1; break; case 2: topology = MeshTopology.Lines; nb_faces = 2; break; default: // Because option aiProcess_Triangulate is mandatory topology = MeshTopology.Triangles; nb_faces = 3; break; } } } } int[] unity = new int[size * nb_faces]; for (uint i = 0; i < size; i++) { using (aiFace face = assimp.Get(i)) { using (aiUIntArray indices = face.Indices) { if (indices.Size() >= nb_faces) { for (uint j = 0; j < nb_faces; j++) { unity[i * nb_faces + j] = (int)indices.Get(j); } if (indices.Size() > nb_faces) { Debug.LogError("Too many vertices to compose a face. Some data is lost."); } } else { Debug.LogError("Not enough vertices to compose a face."); } } } } return(unity); }
public static Node FromAssimp(Module.Import.Assimp.Context context, aiScene scene, aiNode assimp_node) { // Create new node object Node node = new Node(); // Get node ID node.id = context.id++; // Get node name node.name = Assimp.Convert.Name(assimp_node.mName, "node"); // Get node metadata using (aiMetadata meta = assimp_node.mMetaData) { UnityComponent metadata = UnityComponent.FromAssimpMetadata(meta); if (metadata != null) { node.components = new UnityComponent[] { metadata }; } } // Parse children recursively using (aiNodeArray children = assimp_node.Children) { uint children_size = children.Size(); if (children_size > 0) { node.children = new Node[children_size]; for (uint i = 0; i < children_size; i++) { aiNode child = children.Get(i); // ParseNode must dispose of the given node afterward // We must use a proxy method for saving the result into the array because the index i is captured by the lambda otherwise and it's value is indefinite across multiple threads. context.threads.ExecAndSaveToArray(node.children, (int)i, () => FromAssimp(context, scene, child)); } } } // Parse meshes associated to this node using (aiUIntArray meshes = assimp_node.Meshes) { uint meshes_size = meshes.Size(); if (meshes_size > 0) { int global_meshes_size = (int)scene.Meshes.Size(); node.meshes = new GraphicMesh[meshes_size]; for (uint j = 0; j < meshes_size; j++) { node.meshes[j] = new GraphicMesh(); if (j < global_meshes_size) { uint mesh_index = meshes.Get(j); node.meshes[j].meshIndex = (int)mesh_index; } } } } // Get the transform of this node using (aiVector3D position = new aiVector3D()) { using (aiVector3D scaling = new aiVector3D()) { using (aiQuaternion rotation = new aiQuaternion()) { assimp_node.mTransformation.Decompose(scaling, rotation, position); node.position = Assimp.Convert.AssimpToUnity.Vector3(position); node.rotation = Assimp.Convert.AssimpToUnity.Quaternion(rotation); node.scale = Assimp.Convert.AssimpToUnity.Vector3(scaling); } } } // We must dispose of the given parameter to avoid memory leaks assimp_node.Dispose(); context.progress.Update(ASSIMP_PROGRESS_FACTOR); return(node); }