Inheritance: IDisposable
Example #1
0
    public aiNode FindNode(string name)
    {
        IntPtr cPtr = AssimpPINVOKE.aiNode_FindNode__SWIG_1(swigCPtr, name);
        aiNode ret  = (cPtr == IntPtr.Zero) ? null : new aiNode(cPtr, false);

        return(ret);
    }
Example #2
0
        //-------------------------------------------------------------------------------
        // Calculate the boundaries of a given node and all of its children
        // The boundaries are in Worldspace (AABB)
        // piNode Input node
        // min/max Receives the min/max boundaries
        // piMatrix Transformation matrix of the graph at this position
        //-------------------------------------------------------------------------------
        private void CalculateBounds(aiNode piNode, ref Vector3 min, ref Vector3 max, Matrix piMatrix)
        {
            Debug.Assert(null != piNode);

            var mTemp = piNode.mTransformation.ToMatrix();
            var aiMe  = mTemp * piMatrix;

            var meshes    = piNode.mMeshes;
            var numMeshes = meshes.Count;

            for (int i = 0; i < numMeshes; ++i)
            {
                var mesh    = meshes[i];
                var meshMin = Vector3.TransformCoordinate(meshBoundsMin[mesh], aiMe);
                var meshMax = Vector3.TransformCoordinate(meshBoundsMax[mesh], aiMe);
                min.X = Math.Min(min.X, meshMin.X);
                min.Y = Math.Min(min.Y, meshMin.Y);
                min.Z = Math.Min(min.Z, meshMin.Z);
                max.X = Math.Max(max.X, meshMax.X);
                max.Y = Math.Max(max.Y, meshMax.Y);
                max.Z = Math.Max(max.Z, meshMax.Z);
            }
            var children    = piNode.mChildren;
            var numChildren = children.Count;

            for (int i = 0; i < numChildren; ++i)
            {
                CalculateBounds(children[i], ref min, ref max, aiMe);
            }
        }
        private BoneContent createSkel(aiNode root)
        {
            BoneContent BoneContent = null;

            if (ainodetocontent.ContainsKey(root.mName.Data))
            {
                aiBone b = bones.Find((a) => a.mName.Data == root.mName.Data);
                if (b != null)
                {
                    BoneContent           = new BoneContent();
                    BoneContent.Name      = b.mName.Data;
                    BoneContent.Transform = tomatrix(b.mOffsetMatrix);

                    foreach (var item in root.mChildren)
                    {
                        BoneContent bon = createSkel(item);
                        if (bon != null)
                        {
                            BoneContent.Children.Add(bon);
                        }
                    }
                    return(BoneContent);
                }
            }
            return(null);
        }
Example #4
0
    public aiNode FindNode(aiString name)
    {
        IntPtr cPtr = AssimpPINVOKE.aiNode_FindNode__SWIG_0(swigCPtr, aiString.getCPtr(name));
        aiNode ret  = (cPtr == IntPtr.Zero) ? null : new aiNode(cPtr, false);

        if (AssimpPINVOKE.SWIGPendingException.Pending)
        {
            throw AssimpPINVOKE.SWIGPendingException.Retrieve();
        }
        return(ret);
    }
Example #5
0
        private static uint CountNodes(aiNode node)
        {
            uint result = 1;

            using (aiNodeArray children = node.Children)
            {
                uint children_size = children.Size();
                for (uint i = 0; i < children_size; i++)
                {
                    using (aiNode child = children.Get(i))
                    {
                        result += CountNodes(child);
                    }
                }
            }

            return(result);
        }
        private NodeContent extractNo(aiNode node)
        {
            NodeContent nodeContent = new NodeContent();

            nodeContent.Name      = node.mName.Data;
            nodeContent.Transform = tomatrix(node.mTransformation);
            ainodetocontent.Add(node.mName.Data, nodeContent);

            wbone.Clear();
            for (int i = 0; i < node.mNumMeshes; i++)
            {
                for (int j = 0; j < scene.mMeshes[(int)node.mMeshes[i]].mNumBones; j++)
                {
                    aiBone b = scene.mMeshes[(int)node.mMeshes[i]].mBones[j];
                    for (int w = 0; w < b.mNumWeights; w++)
                    {
                        aiVertexWeight vw = b.GetmWeights()[w];
                        if (!wbone.ContainsKey((int)vw.mVertexId))
                        {
                            wbone[(int)vw.mVertexId] = new List <KeyValuePair <string, float> >();
                        }
                        wbone[(int)vw.mVertexId].Add(new KeyValuePair <string, float>(b.mName.Data, vw.mWeight));
                    }
                    bones.Add(b);
                }

                log("model " + node.mMeshes[i].ToString());
                MeshContent MeshContent = ExtractMesh(scene.mMeshes[(int)node.mMeshes[i]]);
                MeshHelper.SwapWindingOrder(MeshContent);
                MeshHelper.OptimizeForCache(MeshContent);
                nodeContent.Children.Add(MeshContent);
            }

            foreach (var item in node.mChildren)
            {
                nodeContent.Children.Add(extractNo(item));
            }
            return(nodeContent);
        }
Example #7
0
        private void RenderNode(aiNode node, Matrix parentMatrix)
        {
            var nodeMatrix = node.mTransformation.ToMatrix() * parentMatrix;

            var children    = node.mChildren;
            var numChildren = node.mNumChildren;

            for (int i = 0; i < numChildren; ++i)
            {
                var child = children[i];
                RenderNode(child, nodeMatrix);
            }

            device.Transform.World = nodeMatrix;
            var meshes    = node.mMeshes;
            var numMeshes = meshes.Count;

            for (int i = 0; i < numMeshes; ++i)
            {
                var meshId     = (int)meshes[i];
                var mesh       = scene.mMeshes[meshId];
                var materialId = (int)mesh.mMaterialIndex;

                var dxMaterial = materialCache[materialId];
                device.Material = dxMaterial.Material3D;

                Texture dxTexture = null;
                if (!string.IsNullOrEmpty(dxMaterial.TextureFilename))
                {
                    textureCache.TryGetValue(dxMaterial.TextureFilename, out dxTexture);
                }
                device.SetTexture(0, dxTexture);

                var dxMesh = meshCache[meshId];
                RenderMesh(dxMesh);
            }
        }
Example #8
0
 internal static HandleRef getCPtr(aiNode obj)
 {
     return((obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr);
 }
Example #9
0
        private void RenderNode(aiNode node, Matrix parentMatrix)
        {
            var nodeMatrix = node.mTransformation.ToMatrix() * parentMatrix;

            var children = node.mChildren;
            var numChildren = node.mNumChildren;
            for (int i = 0; i < numChildren; ++i) {
                var child = children[i];
                RenderNode(child, nodeMatrix);
            }

            device.Transform.World = nodeMatrix;
            var meshes = node.mMeshes;
            var numMeshes = meshes.Count;
            for (int i = 0; i < numMeshes; ++i) {
                var meshId = (int)meshes[i];
                var mesh = scene.mMeshes[meshId];
                var materialId = (int)mesh.mMaterialIndex;

                var dxMaterial = materialCache[materialId];
                device.Material = dxMaterial.Material3D;

                Texture dxTexture = null;
                if (!string.IsNullOrEmpty(dxMaterial.TextureFilename)) {
                    textureCache.TryGetValue(dxMaterial.TextureFilename, out dxTexture);
                }
                device.SetTexture(0, dxTexture);

                var dxMesh = meshCache[meshId];
                RenderMesh(dxMesh);
            }
        }
Example #10
0
        //-------------------------------------------------------------------------------
        // Calculate the boundaries of a given node and all of its children
        // The boundaries are in Worldspace (AABB)
        // piNode Input node
        // min/max Receives the min/max boundaries
        // piMatrix Transformation matrix of the graph at this position
        //-------------------------------------------------------------------------------
        private void CalculateBounds(aiNode piNode, ref Vector3 min, ref Vector3 max, Matrix piMatrix)
        {
            Debug.Assert(null != piNode);

            var mTemp = piNode.mTransformation.ToMatrix();
            var aiMe = mTemp * piMatrix;

            var meshes = piNode.mMeshes;
            var numMeshes = meshes.Count;
            for (int i = 0; i < numMeshes; ++i) {
                var mesh = meshes[i];
                var meshMin = Vector3.TransformCoordinate(meshBoundsMin[mesh], aiMe);
                var meshMax = Vector3.TransformCoordinate(meshBoundsMax[mesh], aiMe);
                min.X = Math.Min(min.X, meshMin.X);
                min.Y = Math.Min(min.Y, meshMin.Y);
                min.Z = Math.Min(min.Z, meshMin.Z);
                max.X = Math.Max(max.X, meshMax.X);
                max.Y = Math.Max(max.Y, meshMax.Y);
                max.Z = Math.Max(max.Z, meshMax.Z);
            }
            var children = piNode.mChildren;
            var numChildren = children.Count;
            for (int i = 0; i < numChildren; ++i) {
                CalculateBounds(children[i], ref min, ref max, aiMe);
            }
        }
Example #11
0
        public IEnumerator ToAssimp(Module.Export.Assimp.Context context, string filename, aiPostProcessSteps steps, Module.ExporterSuccessCallback return_callback, Module.ProgressCallback progress_callback)
        {
            bool success = false;

            string extension = System.IO.Path.GetExtension(filename).Remove(0, 1).ToLower();

            uint export_format_count = context.exporter.GetExportFormatCount();

            bool found_exporter = false;

            for (uint i = 0; i < export_format_count; i++)
            {
                using (aiExportFormatDesc desc = context.exporter.GetExportFormatDescription(i))
                {
                    if (extension == desc.fileExtension.ToLower())
                    {
                        using (aiScene scene = new aiScene())
                        {
                            InitProgress(context, progress_callback, this);

                            context.scene = scene;

                            // Export nodes
                            IResult nodes_result = context.threads.AddTask(() =>
                            {
                                using (aiNode root = root_node.ToAssimp(context, this, null))
                                {
                                    scene.mRootNode = root.Unmanaged();
                                }
                            });

                            // Export materials.
                            context.threads.AddTask(() => Material.ToAssimp(context, this));

                            // We must wait for all the nodes to be processed before exporting meshes because indexes are computed during parsing.
                            while (!nodes_result.Done)
                            {
                                context.progress.Display();

                                yield return(null);
                            }

                            // Export meshes
                            context.threads.AddTask(() => Mesh.ToAssimp(context, this));

                            // Wait for all tasks to be completed
                            IEnumerator it = context.threads.WaitForTasksCompletion();
                            while (it.MoveNext())
                            {
                                context.progress.Display();

                                yield return(it.Current);
                            }

                            // Do the final export using Assimp now that we created the complete structure in the C++ DLL.
                            Result <aiReturn> status = context.threads.AddTask(() => context.exporter.Export(scene, desc.id, filename, steps));

                            // Wait for export to complete
                            while (!status.Done)
                            {
                                context.progress.Display();

                                yield return(null);
                            }

                            if (progress_callback != null)
                            {
                                progress_callback(1f);
                            }

                            context.Clean();

                            // Check export status
                            if (status.Success && status.Value == aiReturn.aiReturn_SUCCESS)
                            {
                                success = true;
                            }
                            else
                            {
                                Debug.LogErrorFormat("Failed to export to: {0}. \nThe exporter reported the following error: {1}", filename, context.exporter.GetErrorString());
                            }
                        }

                        found_exporter = true;

                        break;
                    }
                }
            }

            if (!found_exporter)
            {
                Debug.LogErrorFormat("No exporter for format '{0}' was found in Assimp.", extension);
            }

            if (return_callback != null)
            {
                return_callback(success);
            }
        }
Example #12
0
        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);
        }
Example #13
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);
        }
Example #14
0
 internal static HandleRef getCPtr(aiNode obj) {
   return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
 }
        /// <summary>
        /// The importer's entry point.
        /// Called by the framework when importing a game asset.
        /// </summary>
        /// <param name="filename">Name of a game asset file.</param>
        /// <param name="context">
        /// Contains information for importing a game asset, such as a logger interface.
        /// </param>
        /// <returns>Resulting game asset.</returns>
        public override NodeContent Import(string filename,
                                           ContentImporterContext context)
        {
            // Uncomment the following line to debug:
            //System.Diagnostics.Debugger.Launch();

            importerContext = context;

            // Reset all importer state
            // See field declarations for more information
            rootNode      = new NodeContent();
            meshBuilder   = null;
            this.filename = filename;
            // Model identity is tied to the file it is loaded from
            rootNode.Identity = new ContentIdentity(filename);

            var flags = (ppsteps |
                         aiPostProcessSteps.aiProcess_GenSmoothNormals |    // generate smooth normal vectors if not existing
                         aiPostProcessSteps.aiProcess_SplitLargeMeshes |    // split large, unrenderable meshes into submeshes
                         aiPostProcessSteps.aiProcess_Triangulate |         // triangulate polygons with more than 3 edges
                         aiPostProcessSteps.aiProcess_ConvertToLeftHanded | // convert everything to D3D left handed space
                         aiPostProcessSteps.aiProcess_SortByPType |         // make 'clean' meshes which consist of a single typ of primitives
                         aiPostProcessSteps.aiProcess_FixInfacingNormals |
                         aiPostProcessSteps.aiProcess_FlipWindingOrder |
                         (aiPostProcessSteps)0);

            Importer importer = new Importer();

            scene = importer.ReadFile(filename, flags);
            if (scene != null)
            {
                directory = Path.GetDirectoryName(filename);
            }
            else
            {
                throw new InvalidContentException("Failed to open file: " + filename + ". Either Assimp screwed up or the path is not valid.");
            }


            ///animacoes
            Dictionary <String, AnimationContent> AnimNameToAcontent = new Dictionary <string, AnimationContent>();

            for (int i = 0; i < scene.mNumAnimations; i++)
            {
                AnimationContent AnimationContent = new AnimationContent();
                AnimationContent.Duration = TimeSpan.FromMilliseconds(scene.mAnimations[i].mDuration);
                if (String.IsNullOrEmpty(scene.mAnimations[i].mName.Data))
                {
                    scene.mAnimations[i].mName.Data = "EMPTY";
                }
                AnimationContent.Name = scene.mAnimations[i].mName.Data;

                AnimNameToAcontent.Add(scene.mAnimations[i].mName.Data, AnimationContent);

                for (int j = 0; j < scene.mAnimations[i].mNumChannels; j++)
                {
                    AnimationChannel AnimationChannel;
                    String           boneName = scene.mAnimations[i].mChannels[j].mNodeName.Data;

                    if (AnimationContent.Channels.ContainsKey(boneName))
                    {
                        AnimationChannel = AnimationContent.Channels[boneName];
                    }
                    else
                    {
                        AnimationChannel = new AnimationChannel();
                        AnimationContent.Channels.Add(boneName, AnimationChannel);
                    }

                    Dictionary <double, Vector3>    position = new Dictionary <double, Vector3>();
                    Dictionary <double, Vector3>    scales   = new Dictionary <double, Vector3>();
                    Dictionary <double, Quaternion> rots     = new Dictionary <double, Quaternion>();

                    SortedSet <double> set = new SortedSet <double>();
                    for (int w = 0; w < scene.mAnimations[i].mChannels[j].mNumPositionKeys; w++)
                    {
                        position.Add(scene.mAnimations[i].mChannels[j].mPositionKeys[w].mTime, new Vector3(scene.mAnimations[i].mChannels[j].mPositionKeys[w].mValue.x, scene.mAnimations[i].mChannels[j].mPositionKeys[w].mValue.y, scene.mAnimations[i].mChannels[j].mPositionKeys[w].mValue.z));
                        set.Add(scene.mAnimations[i].mChannels[j].mPositionKeys[w].mTime);
                    }

                    for (int w = 0; w < scene.mAnimations[i].mChannels[j].mNumScalingKeys; w++)
                    {
                        scales.Add(scene.mAnimations[i].mChannels[j].mScalingKeys[w].mTime, new Vector3(scene.mAnimations[i].mChannels[j].mScalingKeys[w].mValue.x, scene.mAnimations[i].mChannels[j].mScalingKeys[w].mValue.y, scene.mAnimations[i].mChannels[j].mScalingKeys[w].mValue.z));
                        set.Add(scene.mAnimations[i].mChannels[j].mScalingKeys[w].mTime);
                    }

                    for (int w = 0; w < scene.mAnimations[i].mChannels[j].mNumRotationKeys; w++)
                    {
                        rots.Add(scene.mAnimations[i].mChannels[j].mRotationKeys[w].mTime, new Quaternion(scene.mAnimations[i].mChannels[j].mRotationKeys[w].mValue.x, scene.mAnimations[i].mChannels[j].mRotationKeys[w].mValue.y, scene.mAnimations[i].mChannels[j].mRotationKeys[w].mValue.z, scene.mAnimations[i].mChannels[j].mRotationKeys[w].mValue.w));
                        set.Add(scene.mAnimations[i].mChannels[j].mRotationKeys[w].mTime);
                    }

                    foreach (var item in set)
                    {
                        Vector3    pos;
                        Vector3    sca;
                        Quaternion rot;

                        if (position.TryGetValue(item, out pos) == false)
                        {
                            pos = Vector3.Zero;
                        }
                        if (rots.TryGetValue(item, out rot) == false)
                        {
                            rot = Quaternion.Identity;
                        }
                        if (scales.TryGetValue(item, out sca) == false)
                        {
                            sca = Vector3.One;
                        }

                        Matrix world = Matrix.CreateScale(sca) * Matrix.CreateFromQuaternion(rot) * Matrix.CreateTranslation(pos);

                        AnimationChannel.Add(new AnimationKeyframe(TimeSpan.FromMilliseconds(item), world));
                    }
                }
            }

            rootNode.Children.Add(extractNo(scene.mRootNode));

            aiNode boneRoot = null;
            aiBone broot    = null;
            int    distance = int.MaxValue;

            ///pega o root manow
            foreach (var item in bones)
            {
                aiNode ainode = scene.mRootNode.FindNode(item.mName);
                aiNode n      = ainode;
                int    d      = 0;
                //find the closest to the root =P
                while (n.mParent != null)
                {
                    d++;
                    n = n.mParent;
                }
                if (d < distance)
                {
                    broot    = item;
                    boneRoot = ainode;
                    distance = d;
                }
            }

            if (broot != null)
            {
                BoneContent BoneContent = new BoneContent();
                BoneContent.Name      = broot.mName.Data;
                BoneContent.Transform = tomatrix(broot.mOffsetMatrix);
                rootNode.Children.Add(BoneContent);

                foreach (var item2 in AnimNameToAcontent)
                {
                    BoneContent.Animations.Add(item2.Key, item2.Value);
                }

                foreach (var item in boneRoot.mChildren)
                {
                    BoneContent.Children.Add(createSkel(boneRoot));
                }

                ClearTree(rootNode);
            }



            return(rootNode);
        }