public static void ToAssimp(Module.Export.Assimp.Context context, Scene scene) { if (context.meshes != null && context.meshes.Count > 0) { using (aiMeshArray meshes = context.scene.Meshes) { uint count = (uint)context.meshes.Count; meshes.Reserve(count, true); foreach (KeyValuePair <Module.Export.Assimp.Mesh, uint> indexes in context.meshes) { if (indexes.Value >= 0 && indexes.Value < count) { // Save the values to local variables to avoid the problem of variables passed by reference to lambda functions. Module.Export.Assimp.Mesh mesh_indexes = indexes.Key; aiMesh assimp_mesh = new aiMesh(); // Allocation in another thread fails so we must do it before starting the task meshes.Set(indexes.Value, assimp_mesh.Unmanaged()); context.threads.AddTask(() => ToAssimp(context, scene, mesh_indexes, assimp_mesh)); } } } } }
public aiNode ToAssimp(Module.Export.Assimp.Context context, Scene scene, aiNode parent) { uint index = 0; aiNode node_object = new aiNode(name); // Set parent node_object.mParent = parent; // Set transform using (aiVector3D assimp_scale = Assimp.Convert.UnityToAssimp.Vector3(scale)) { using (aiQuaternion assimp_rotation = Assimp.Convert.UnityToAssimp.Quaternion(rotation)) { using (aiVector3D assimp_position = Assimp.Convert.UnityToAssimp.Vector3(position)) { using (aiMatrix4x4 matrix = new aiMatrix4x4(assimp_scale, assimp_rotation, assimp_position)) { node_object.mTransformation = matrix.Unmanaged(); } } } } // Parse the children nodes if (children != null && children.Length > 0) { using (aiNodeArray assimp_children = node_object.Children) { assimp_children.Reserve((uint)children.Length, true); index = 0; foreach (Node child in children) { using (aiNode assimp_child = child.ToAssimp(context, scene, node_object)) { if (assimp_child != null) { assimp_children.Set(index++, assimp_child.Unmanaged()); } } } } } // Parse the mesh objects if (meshes != null && meshes.Length > 0) { using (aiUIntArray assimp_meshes = node_object.Meshes) { assimp_meshes.Reserve((uint)meshes.Length, true); index = 0; foreach (GraphicMesh graphic_mesh in meshes) { Mesh mesh = scene.meshes[graphic_mesh.meshIndex]; int nb_materials = (graphic_mesh.materialsIndexes != null ? graphic_mesh.materialsIndexes.Length : 0); // Handle unity submeshes by creating new meshes for each submesh for (int i = 0; i < mesh.SubMeshesCount; i++) { // Assimp meshes can only have one material. Therefore, mutliple instances of one mesh // using different materials must be detected and replaced by different output meshes. uint assimp_mesh_index; int mat_index = (i < nb_materials ? graphic_mesh.materialsIndexes[i] : 0 /*Assimp default*/); Module.Export.Assimp.Mesh key = new Module.Export.Assimp.Mesh(graphic_mesh.meshIndex, i, mat_index); if (!context.meshes.TryGetValue(key, out assimp_mesh_index)) { assimp_mesh_index = (uint)context.meshes.Count; context.meshes.Add(key, assimp_mesh_index); } assimp_meshes.Set(index++, assimp_mesh_index); } } } } // Parse the node metadata if (components != null) { foreach (UnityComponent component in components) { aiMetadata assimp_meta = component.ToAssimpMetadata(); if (assimp_meta != null) { node_object.mMetaData = assimp_meta.Unmanaged(); break; } } } context.progress.Update(ASSIMP_PROGRESS_FACTOR); return(node_object); }
private static void ToAssimp(Module.Export.Assimp.Context context, Scene scene, Module.Export.Assimp.Mesh mesh_indexes, aiMesh assimp_mesh) { Mesh mesh = scene.meshes[mesh_indexes.mesh]; assimp_mesh.mMaterialIndex = (uint)mesh_indexes.material; using (aiString assimp_mesh_name = new aiString(mesh.name)) { assimp_mesh.mName = assimp_mesh_name.Unmanaged(); } if (mesh.vertices.Length > 0) { using (aiVector3DArray vertices = assimp_mesh.Vertices) { Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Vector3, mesh.vertices, vertices); } } if (mesh.normals.Length > 0) { using (aiVector3DArray normals = assimp_mesh.Normals) { Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Vector3, mesh.normals, normals); } } if (mesh.tangents.Length > 0) { using (aiVector3DArray tangents = assimp_mesh.Tangents) { Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Tangent, mesh.tangents, tangents); } } if (mesh_indexes.submesh < mesh.submeshes.Length) { // Support for submeshes: this mesh represent only one submesh of the original mesh SubMesh sub_mesh = mesh.submeshes[mesh_indexes.submesh]; if (sub_mesh != null && sub_mesh.triangles != null && sub_mesh.triangles.Length > 0) { using (aiFaceArray faces = assimp_mesh.Faces) { Assimp.Convert.UnityToAssimp.Face(sub_mesh.triangles, sub_mesh.topology, faces); } } } if (mesh.uv1.Length > 0 || mesh.uv2.Length > 0) { using (aiVector3DMultiArray texture_coords = assimp_mesh.TextureCoords) { if (mesh.uv1.Length > 0) { using (aiVector3DArray texture_coords0 = texture_coords.Get(0)) { Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.UV, mesh.uv1, texture_coords0); } } if (mesh.uv2.Length > 0) { using (aiVector3DArray texture_coords1 = texture_coords.Get(1)) { Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.UV, mesh.uv2, texture_coords1); } } } } if (mesh.colors.Length > 0) { using (aiColor4DMultiArray colors = assimp_mesh.Colors) { using (aiColor4DArray colors0 = colors.Get(0)) { Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Color, mesh.colors, colors0); } } } context.progress.Update(ASSIMP_PROGRESS_FACTOR); }