Ejemplo n.º 1
0
            //-------------------------------------------------------------------------------
            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);
            }
Ejemplo n.º 2
0
        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);
        }