예제 #1
0
파일: Node.cs 프로젝트: clarte53/armine
        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);
        }
예제 #2
0
        public static UnityComponent FromAssimpMetadata(aiMetadata meta)
        {
            UnityComponent metadata = null;

            if (meta != null && meta.Keys != null)
            {
                uint size = meta.Keys.Size();

                if (meta.Values != null && meta.Values.Size() == size)
                {
                    if (size > 0)
                    {
                        Dictionary <string, object> storage = new Dictionary <string, object>();

                        for (uint i = 0; i < size; ++i)
                        {
                            using (aiString key = meta.Keys.Get(i))
                            {
                                using (aiMetadataEntry entry = meta.Values.Get(i))
                                {
                                    object value = null;

                                    switch (entry.mType)
                                    {
                                    case aiMetadataType.AI_BOOL:
                                        value = entry.GetBool();
                                        break;

                                    case aiMetadataType.AI_INT32:
                                        value = entry.GetInt32();
                                        break;

                                    case aiMetadataType.AI_UINT64:
                                        value = entry.GetUInt64();
                                        break;

                                    case aiMetadataType.AI_FLOAT:
                                        value = entry.GetFloat();
                                        break;

                                    case aiMetadataType.AI_DOUBLE:
                                        value = entry.GetDouble();
                                        break;

                                    case aiMetadataType.AI_AISTRING:
                                        value = entry.GetString().C_Str();
                                        break;

                                    case aiMetadataType.AI_AIVECTOR3D:
                                        value = Assimp.Convert.AssimpToUnity.Vector3(entry.GetVector3D());
                                        break;
                                    }

                                    storage.Add(key.C_Str(), value);
                                }
                            }
                        }

                        metadata = new UnityComponent
                        {
                            type = typeof(Metadata)
                        };

                        metadata.CreateBackend();

                        AssimpMetadataSerializationContext context = new AssimpMetadataSerializationContext(metadata.type, storage);

                        ((BackendBinarySerializable)metadata.backend).serialized = Module.Import.Binary.serializer.Serialize(context.Callback);
                    }
                }
                else
                {
                    Debug.LogError("The number of metadata keys and values does not match.");
                }
            }

            return(metadata);
        }
예제 #3
0
파일: Node.cs 프로젝트: clarte53/armine
        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);
        }
예제 #4
0
        public aiMetadata ToAssimpMetadata()
        {
            aiMetadata assimp_meta = null;

            if (typeof(Metadata).IsAssignableFrom(type))
            {
                Dictionary <string, object> data = (Dictionary <string, object>)Module.Import.Binary.serializer.Deserialize(((BackendBinarySerializable)backend).serialized);

                if (data != null && data.Count > 0)
                {
                    uint count = 0;

                    // Get the number of valid metadata that can be exported
                    foreach (KeyValuePair <string, object> pair in data)
                    {
                        if (!string.IsNullOrEmpty(pair.Key) && pair.Value != null)
                        {
                            count++;
                        }
                    }

                    // Allocate memory for metadata
                    assimp_meta = aiMetadata.Alloc(count);

                    uint index = 0;

                    // Export all valid metadata
                    foreach (KeyValuePair <string, object> pair in data)
                    {
                        if (!string.IsNullOrEmpty(pair.Key) && pair.Value != null)
                        {
                            System.Type type = pair.Value.GetType();

                            if (type == typeof(bool))
                            {
                                assimp_meta.SetBool(index++, pair.Key, (bool)pair.Value);
                            }
                            else if (type == typeof(int))
                            {
                                assimp_meta.SetInt32(index++, pair.Key, (int)pair.Value);
                            }
                            else if (type == typeof(ulong))
                            {
                                assimp_meta.SetUInt64(index++, pair.Key, (ulong)pair.Value);
                            }
                            else if (type == typeof(float))
                            {
                                assimp_meta.SetFloat(index++, pair.Key, (float)pair.Value);
                            }
                            else if (type == typeof(double))
                            {
                                assimp_meta.SetDouble(index++, pair.Key, (double)pair.Value);
                            }
                            else if (type == typeof(string))
                            {
                                assimp_meta.SetString(index++, pair.Key, new aiString((string)pair.Value).Unmanaged());
                            }
                            else if (type == typeof(Vector3))
                            {
                                assimp_meta.SetVector3D(index++, pair.Key, Assimp.Convert.UnityToAssimp.Vector3((Vector3)pair.Value).Unmanaged());
                            }
                            else
                            {
                                Debug.LogErrorFormat("Unsupported metadata of type '{0}'.", type);
                            }
                        }
                    }
                }
            }

            return(assimp_meta);
        }