示例#1
0
        public JNT1(Assimp.Scene scene)
        {
            BoneNameIndices = new Dictionary <string, int>();
            FlatSkeleton    = new List <Rigging.Bone>();
            Assimp.Node root = null;

            for (int i = 0; i < scene.RootNode.ChildCount; i++)
            {
                if (scene.RootNode.Children[i].Name.ToLowerInvariant() == "skeleton_root")
                {
                    root = scene.RootNode.Children[i].Children[0];
                    break;
                }
            }

            if (root == null)
            {
                throw new Exception("Skeleton root was not found. Please make sure the root is under a node called \"skeleton_root.\"");
            }

            SkeletonRoot = AssimpNodesToBonesRecursive(root, null, FlatSkeleton);

            foreach (Rigging.Bone bone in FlatSkeleton)
            {
                BoneNameIndices.Add(bone.Name, FlatSkeleton.IndexOf(bone));
            }
        }
示例#2
0
        /// <summary>
        /// Recursively calculates the bounding box of the whole model.
        /// </summary>
        private void ComputeBoundingBox(Scene scene, Node node,
            ref Vector3 min, ref Vector3 max,
            ref Matrix transform)
        {
            var previousTransform = transform;
            transform = Matrix.Multiply(previousTransform, node.Transform.ToMatrix());

            if (node.HasMeshes)
            {
                foreach (int index in node.MeshIndices)
                {
                    Mesh mesh = scene.Meshes[index];
                    for (int i = 0; i < mesh.VertexCount; i++)
                    {
                        var tmp = mesh.Vertices[i].ToVector3();
                        Vector4 result;
                        Vector3.Transform(ref tmp, ref transform, out result);

                        min.X = System.Math.Min(min.X, result.X);
                        min.Y = System.Math.Min(min.Y, result.Y);
                        min.Z = System.Math.Min(min.Z, result.Z);

                        max.X = System.Math.Max(max.X, result.X);
                        max.Y = System.Math.Max(max.Y, result.Y);
                        max.Z = System.Math.Max(max.Z, result.Z);
                    }
                }
            }

            // Go down the hierarchy if children are present.
            for (int i = 0; i < node.ChildCount; i++)
                ComputeBoundingBox(scene, node.Children[i], ref min, ref max, ref transform);

            transform = previousTransform;
        }
示例#3
0
        public void SetNode(MainWindow mainWindow, Scene scene, Node node)
        {
            _node = node;
            _scene = scene;

            var matrix4X4 = _node.Transform;
            trafoMatrixViewControlLocal.SetMatrix(ref matrix4X4);

            var mat = Matrix4x4.Identity;
            var cur = node;
            while(cur != null)
            {
                var trafo = cur.Transform;
                trafo.Transpose();
                mat = trafo * mat;
                cur = cur.Parent;
            }
            mat.Transpose();
            trafoMatrixViewControlGlobal.SetMatrix(ref mat);

            Text = node.Name + " - Node Details";

            // populate statistics
            labelMeshesDirect.Text = node.MeshCount.ToString(CultureInfo.InvariantCulture);
            labelChildrenDirect.Text = node.ChildCount.ToString(CultureInfo.InvariantCulture);

            var meshTotal = 0;
            var childTotal = 0;
            CountMeshAndChildrenTotal(node, ref meshTotal, ref childTotal);

            labelMeshesTotal.Text = node.MeshCount.ToString(CultureInfo.InvariantCulture);
            labelChildrenTotal.Text = node.ChildCount.ToString(CultureInfo.InvariantCulture);
        }
示例#4
0
		private Bone CreateBoneTree(ref Skeleton skele, Node node, Bone parent) {

			var internalNode = new Bone {
				Name = node.Name, Parent = parent,
			};
			if (boneNames.ContainsKey (node.Name)) {
				boneNames [node.Name].OffsetMatrix.Transpose ();
				internalNode.Offset = FromMatrix (boneNames [node.Name].OffsetMatrix);

			}if (internalNode.Name == "") {
				internalNode.Name = "bone_" + _i++;
			}
			//skele[internalNode.Name] = internalNode;
			var trans = node.Transform;
			trans.Transpose(); //drectx stuff
			internalNode.LocalTransform =FromMatrix(trans);
			internalNode.OriginalLocalTransform = internalNode.LocalTransform;
			CalculateBoneToWorldTransform(internalNode);
			internalNode.Children = new List<Bone> ();
			for (var i = 0; i < node.ChildCount; i++) {
				var child = CreateBoneTree(ref skele,node.Children[i], internalNode);
				if (child != null) {
					internalNode.Children.Add(child);
				}
			}

			return internalNode;
		}
示例#5
0
        /// <summary>
        /// Determines the best target scene node for the mesh.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="aiMesh"></param>
        /// <param name="aiNode"></param>
        /// <param name="nodeSearchFunc"></param>
        /// <param name="fallback"></param>
        /// <returns></returns>
        public static T DetermineBestTargetNode <T>(Assimp.Mesh aiMesh, Assimp.Node aiNode, Func <string, T> nodeSearchFunc, T fallback)
        {
            if (aiMesh.BoneCount > 1)
            {
                // Select node to which the mesh is weighted most
                var boneWeightCoverage = CalculateBoneWeightCoverage(aiMesh);
                var maxCoverage        = boneWeightCoverage.Max(x => x.Coverage);
                var bestTargetBone     = boneWeightCoverage.First(x => x.Coverage == maxCoverage).Bone;
                return(nodeSearchFunc(bestTargetBone.Name));
            }
            else if (aiMesh.BoneCount == 1)
            {
                // Use our only bone as the target node
                return(nodeSearchFunc(aiMesh.Bones[0].Name));
            }
            else
            {
                // Try to find a parent of the mesh's ainode that exists within the existing hierarchy
                var aiNodeParent = aiNode.Parent;
                while (aiNodeParent != null)
                {
                    var nodeParent = nodeSearchFunc(aiNodeParent.Name);
                    if (nodeParent != null)
                    {
                        return(nodeParent);
                    }

                    aiNodeParent = aiNodeParent.Parent;
                }

                // Return fallback
                return(fallback);
            }
        }
示例#6
0
        private static int GetTargetIdForNode(Ai.Node rootNode, string nodeName)
        {
            int targetId = 0;

            bool GetTargetIdForNodeRecursive(Ai.Node node)
            {
                if (node.Name == nodeName)
                {
                    return(true);
                }

                ++targetId;

                foreach (var child in node.Children)
                {
                    if (GetTargetIdForNodeRecursive(child))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            if (GetTargetIdForNodeRecursive(rootNode))
            {
                return(targetId);
            }
            else
            {
                return(-1);
            }
        }
示例#7
0
        private void ProcessNode(GraphEntity3D root, Assimp.Node s, List <VMesh> ml)
        {
            GraphEntity3D r1 = new GraphEntity3D();

            root.Sub.Add(r1);
            r1.Top  = root;
            r1.Name = s.Name;


            //r1.LocalTurn = new OpenTK.Matrix4(s.Transform.A1, s.Transform.A2, s.Transform.A3, s.Transform.A4, s.Transform.B1, s.Transform.B2, s.Transform.B3, s.Transform.B4, s.Transform.C1, s.Transform.C2, s.Transform.C3, s.Transform.C4, s.Transform.D1, s.Transform.D2, s.Transform.D3, s.Transform.D4);
            r1.LocalTurn = new OpenTK.Matrix4(s.Transform.A1, s.Transform.B1, s.Transform.C1, s.Transform.D1, s.Transform.A2, s.Transform.B2, s.Transform.C2, s.Transform.D2, s.Transform.A3, s.Transform.B3, s.Transform.C3, s.Transform.D3, s.Transform.A4, s.Transform.B4, s.Transform.C4, s.Transform.D4);
            var lt = r1.LocalTurn;

            r1.LocalTurn = lt.ClearTranslation();
            r1.LocalTurn = r1.LocalTurn.ClearScale();
            r1.LocalPos  = lt.ExtractTranslation();

            r1.LocalScale = lt.ExtractScale();
            // r1.LocalPos = new OpenTK.Vector3(r1.LocalPos.X + 100, 0, 0);
            for (int i = 0; i < s.MeshCount; i++)
            {
                r1.AddMesh(ml[s.MeshIndices[i]]);
            }
            if (s.HasChildren)
            {
                foreach (var pn in s.Children)
                {
                    ProcessNode(r1, pn, ml);
                }
            }
        }
 private Node AddChildBone(string fingerType, string boneType, Hand hand, Node parentNode)
 {
     Node boneNode = new Node();
     boneNode.Name = GetNodeBoneName(fingerType, boneType, hand);
     parentNode.Children.Add(boneNode);
     return (boneNode);
 }
        /// <summary>
        /// Build a Node hierachy into the scene property 'mainScene' from a Hand object
        /// </summary>
        /// <param name="hand"></param>
        private void CreateNodeHierarchy(Hand hand, Scene handScene)
        {
            Node rootNode = handScene.RootNode = new Node();

            Node handNode = new Node();
            handNode.Name = GetNodeHandName(hand.Id.ToString());
            rootNode.Children.Add(handNode);
            
            NodeAnimationChannel bonetest = new NodeAnimationChannel();
            bonetest.NodeName = GetNodeHandName(hand.Id.ToString());
            handScene.Animations[0].NodeAnimationChannels.Add(bonetest);

            foreach (Finger finger in hand.Fingers)
            {
                Node fingerNode = handNode;

                foreach (Leap.Bone.BoneType boneType in (Leap.Bone.BoneType[])Enum.GetValues(typeof(Leap.Bone.BoneType)))
                {
                    string fingerType = finger.Type.ToString();
                    //Add a node hierarchy
                    fingerNode = AddChildBone(fingerType, boneType.ToString(), hand, fingerNode);
                    //Fill the NodeAnimChannel
                    NodeAnimationChannel bone = new NodeAnimationChannel();
                    bone.NodeName = GetNodeBoneName(fingerType, boneType.ToString(), hand);
                    handScene.Animations[0].NodeAnimationChannels.Add(bone);
                }
            }
        }
示例#10
0
        public override IAsset Import(string pathToFile)
        {
            boneNames = new Dictionary <string, Assimp.Bone>();
            //rootBones = new List<Node> ();
            Assimp.Node rootBone = null;
            foreach (var mesh in scene.Meshes)
            {
                foreach (var bone in mesh.Bones)
                {
                    boneNames.Add(bone.Name, bone);
                }
            }

            foreach (var boneName in boneNames.Keys)
            {
                var boneNode = scene.RootNode.FindNode(boneName);
                if (boneNode.Parent == null || !boneNames.ContainsKey(boneNode.Parent.Name))
                {
                    rootBone = boneNode.Parent;
                    break;
                }
            }
            var skele = new Skeleton();

            skele.Name           = "_Skeleton";
            skele[rootBone.Name] = CreateBoneTree(ref skele, rootBone, null);
            //bvh_to_vertices (skele[rootBone.Name],);
            //Console.WriteLine ("/n Start bone list: /n"+rootBone.Name);

            return(skele);
        }
示例#11
0
        private static Object ConvertObjectFromAiNode(Ai.Node aiNode, Ai.Scene aiScene, Matrix4x4 parentTransformation,
                                                      string texturesDirectory, TextureSet textureSet)
        {
            var obj = new Object
            {
                Name = aiNode.Name,
                Skin = new Skin()
            };

            var boneMap     = new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase);
            var materialMap = new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase);

            ConvertMeshesFromAiNodesRecursively(obj, aiNode, aiScene, parentTransformation, boneMap, materialMap,
                                                texturesDirectory, textureSet);

            if (obj.Skin.Bones.Count == 0)
            {
                obj.Skin = null;
            }

            obj.BoundingSphere =
                new AxisAlignedBoundingBox(obj.Meshes.SelectMany(x => x.Vertices)).ToBoundingSphere();

            return(obj.Meshes.Count != 0 ? obj : null);
        }
示例#12
0
        private void ProcessNode(Entity3D root, Assimp.Node s, List <Mesh3D> ml)
        {
            Entity3D r1 = new Entity3D();

            root.Sub.Add(r1);
            r1.Top  = root;
            r1.Name = s.Name;
            if (s.Name.ToLower().Contains("root"))
            {
                r1.Name     = r1.Name + "*";
                r1.BreakTop = true;
            }

            //r1.LocalTurn = new OpenTK.Matrix4(s.Transform.A1, s.Transform.A2, s.Transform.A3, s.Transform.A4, s.Transform.B1, s.Transform.B2, s.Transform.B3, s.Transform.B4, s.Transform.C1, s.Transform.C2, s.Transform.C3, s.Transform.C4, s.Transform.D1, s.Transform.D2, s.Transform.D3, s.Transform.D4);
            r1.LocalTurn = new OpenTK.Matrix4(s.Transform.A1, s.Transform.B1, s.Transform.C1, s.Transform.D1, s.Transform.A2, s.Transform.B2, s.Transform.C2, s.Transform.D2, s.Transform.A3, s.Transform.B3, s.Transform.C3, s.Transform.D3, s.Transform.A4, s.Transform.B4, s.Transform.C4, s.Transform.D4);
            OpenTK.Matrix4 lt = r1.LocalTurn;

            r1.LocalTurn = lt.ClearTranslation();
            r1.LocalTurn = r1.LocalTurn.ClearScale();
            r1.LocalPos  = lt.ExtractTranslation();

            r1.LocalScale = lt.ExtractScale();
            // r1.LocalPos = new OpenTK.Vector3(r1.LocalPos.X + 100, 0, 0);
            for (int i = 0; i < s.MeshCount; i++)
            {
                r1.AddMesh(ml[s.MeshIndices[i]]);
            }
            if (s.HasChildren)
            {
                foreach (Node pn in s.Children)
                {
                    ProcessNode(r1, pn, ml);
                }
            }
        }
示例#13
0
        public JNT1(Assimp.Scene scene, VTX1 vertexData)
        {
            BoneNameIndices = new Dictionary <string, int>();
            FlatSkeleton    = new List <Rigging.Bone>();
            Assimp.Node root = null;

            for (int i = 0; i < scene.RootNode.ChildCount; i++)
            {
                if (scene.RootNode.Children[i].Name.ToLowerInvariant() == "skeleton_root")
                {
                    root = scene.RootNode.Children[i].Children[0];
                    break;
                }
            }

            if (root == null)
            {
                SkeletonRoot = new Rigging.Bone("root");
                SkeletonRoot.Bounds.GetBoundsValues(vertexData.Attributes.Positions);

                FlatSkeleton.Add(SkeletonRoot);
                BoneNameIndices.Add("root", 0);
            }

            else
            {
                SkeletonRoot = AssimpNodesToBonesRecursive(root, null, FlatSkeleton);

                foreach (Rigging.Bone bone in FlatSkeleton)
                {
                    BoneNameIndices.Add(bone.Name, FlatSkeleton.IndexOf(bone));
                }
            }
        }
示例#14
0
        //recursively calculates the bounding box of the whole model
        private void ComputeBoundingBox(Scene scene, Node node, ref Vector3 min, ref Vector3 max, ref Matrix transform)
        {
            Matrix previousTransform = transform;
            transform = Matrix.Multiply(previousTransform, FromMatrix(node.Transform));

            if (node.HasMeshes)
            {
                foreach (int index in node.MeshIndices)
                {
                    Assimp.Mesh mesh = scene.Meshes[index];
                    for (int i = 0; i < mesh.VertexCount; i++)
                    {
                        Vector3 tmp = FromVector(mesh.Vertices[i]);
                        Vector4 result;
                        Vector3.Transform(ref tmp, ref transform, out result);

                        min.X = Math.Min(min.X, result.X);
                        min.Y = Math.Min(min.Y, result.Y);
                        min.Z = Math.Min(min.Z, result.Z);

                        max.X = Math.Max(max.X, result.X);
                        max.Y = Math.Max(max.Y, result.Y);
                        max.Z = Math.Max(max.Z, result.Z);
                    }
                }
            }

            //go down the hierarchy if children are present
            for (int i = 0; i < node.ChildCount; i++)
            {
                ComputeBoundingBox(scene, node.Children[i], ref min, ref max, ref transform);
            }
            transform = previousTransform;
        }
示例#15
0
 public static Node GetRootNode(Node myNode)
 {
     Node parent = myNode.Parent;
     if (myNode.Parent != null)
         return GetRootNode(parent);
     return (parent);
 }
        // --------------------------------------------------------------------

        private SceneObject ParseNode(Assimp.Node node, bool preview, SceneObject parent)
        {
            string nodeName = GetSafeFileName(node.Name);
            SceneObject mySceneObject = new SceneObject(nodeName);
            mySceneObject.Parent = parent;
            mySceneObject.Transform.FromMatrix(node.Transform.ToOnyx3D());
            if (!preview)
                mySceneObject.Transform.LocalPosition = mySceneObject.Transform.LocalPosition * sMeshScalar;
            

            if (node.HasMeshes)
            {
                for(int i=0; i < node.MeshCount; ++i)
                { 
                    MeshRenderer meshRenderer = mySceneObject.AddComponent<MeshRenderer>();
                    if (preview)
                    {
						mCurrentModel.Meshes[node.MeshIndices[i]].Name = nodeName;
						meshRenderer.Mesh = mCurrentModel.Meshes[node.MeshIndices[i]].ToOnyx3D();
                        meshRenderer.Material = new DefaultMaterial();
                    }else
                    {
                        meshRenderer.Mesh = Onyx3DEngine.Instance.Resources.GetMesh(mLoadedMeshesGuids[node.MeshIndices[i]]);
                        meshRenderer.Material = Onyx3DEngine.Instance.Resources.GetMaterial(BuiltInMaterial.Default);
                    }
                }
            }

            foreach (Node child in node.Children)
            {
                SceneObject childSceneObject = ParseNode(child, preview, mySceneObject);
            }

            return mySceneObject;
        }
示例#17
0
        private static void CreateAiNodesFromBoneInfos(List <BoneInfo> boneInfos, Ai.Scene aiScene,
                                                       Ai.Node aiParentBone, BoneInfo parentBoneInfo, Dictionary <string, Ai.Node> convertedBones)
        {
            foreach (var boneInfo in boneInfos)
            {
                if (boneInfo.Parent != parentBoneInfo)
                {
                    continue;
                }

                if (!convertedBones.TryGetValue(boneInfo.Name, out var aiBoneNode))
                {
                    aiBoneNode = CreateAiNodeFromBoneInfo(boneInfo, parentBoneInfo?.InverseBindPoseMatrix ?? Matrix4x4.Identity);

                    if (aiParentBone == null)
                    {
                        aiScene.RootNode.Children.Add(aiBoneNode);
                    }
                    else
                    {
                        aiParentBone.Children.Add(aiBoneNode);
                    }

                    convertedBones.Add(boneInfo.Name, aiBoneNode);
                }

                CreateAiNodesFromBoneInfos(boneInfos, aiScene, aiBoneNode, boneInfo, convertedBones);
            }
        }
示例#18
0
 public NodeInfo(Ai.Node aiNode, Node node, int index, bool isMesh)
 {
     AssimpNode       = aiNode;
     Node             = node;
     Index            = index;
     IsMeshAttachment = isMesh;
 }
示例#19
0
        private static void ProcessAssimpNodeMeshesRecursively(Ai.Node aiNode, Ai.Scene aiScene, Dictionary <string, NodeInfo> nodeLookup, ref int nextBoneIndex, Dictionary <int, List <int> > nodeToBoneIndices, List <Matrix4x4> boneInverseBindMatrices, List <Vector3> transformedVertices, ModelConverterOptions options)
        {
            if (aiNode.HasMeshes)
            {
                var nodeInfo           = nodeLookup[AssimpConverterCommon.UnescapeName(aiNode.Name)];
                var node               = nodeInfo.Node;
                var nodeWorldTransform = node.WorldTransform;
                Matrix4x4.Invert(nodeWorldTransform, out var nodeInverseWorldTransform);

                foreach (var aiMeshIndex in aiNode.MeshIndices)
                {
                    var aiMesh     = aiScene.Meshes[aiMeshIndex];
                    var aiMaterial = aiScene.Materials[aiMesh.MaterialIndex];
                    var geometry   = ConvertAssimpMeshToGeometry(aiMesh, aiMaterial, nodeLookup, ref nextBoneIndex, nodeToBoneIndices, boneInverseBindMatrices, ref nodeWorldTransform, ref nodeInverseWorldTransform, transformedVertices, options);

                    if (!nodeInfo.IsMeshAttachment)
                    {
                        node.Attachments.Add(new NodeMeshAttachment(geometry));
                    }
                    else
                    {
                        node.Parent.Attachments.Add(new NodeMeshAttachment(geometry));
                        node.Parent.RemoveChildNode(node);
                    }
                }
            }

            foreach (var aiNodeChild in aiNode.Children)
            {
                ProcessAssimpNodeMeshesRecursively(aiNodeChild, aiScene, nodeLookup, ref nextBoneIndex, nodeToBoneIndices, boneInverseBindMatrices, transformedVertices, options);
            }
        }
示例#20
0
        private static Ai.Node CreateAiNodeFromObject(Object obj, Ai.Scene aiScene)
        {
            var aiObjectNode = new Ai.Node(obj.Name);

            foreach (var mesh in obj.Meshes)
            {
                for (int i = 0; i < mesh.SubMeshes.Count; i++)
                {
                    var subMesh = mesh.SubMeshes[i];

                    string name = mesh.Name;
                    if (i > 0)
                    {
                        name += "." + i.ToString("D3");
                    }

                    var aiSubMeshNode = new Ai.Node(name);
                    var aiMesh        = CreateAiMeshFromSubMesh(subMesh, mesh, obj, aiScene, name);

                    aiSubMeshNode.MeshIndices.Add(aiScene.Meshes.Count);
                    aiScene.Meshes.Add(aiMesh);

                    aiObjectNode.Children.Add(aiSubMeshNode);
                }
            }

            return(aiObjectNode);
        }
示例#21
0
 private Node AddChildNode(Node parentNode, Joint childJoint)
 {
     Node newChildNode = new Node();
     newChildNode.Name = GetNodeIdName(childJoint.JointType);
     parentNode.Children.Add(newChildNode);
     return (newChildNode);
 }
示例#22
0
        private Ai.Node ConvertNode(Scene scene, Node node, Ai.Node aiParent)
        {
            var aiNode = new Ai.Node(AssimpConverterCommon.EscapeName(node.Name), aiParent)
            {
                Transform = new Ai.Matrix4x4(node.LocalTransform.M11, node.LocalTransform.M21, node.LocalTransform.M31, node.LocalTransform.M41,
                                             node.LocalTransform.M12, node.LocalTransform.M22, node.LocalTransform.M32, node.LocalTransform.M42,
                                             node.LocalTransform.M13, node.LocalTransform.M23, node.LocalTransform.M33, node.LocalTransform.M43,
                                             node.LocalTransform.M14, node.LocalTransform.M24, node.LocalTransform.M34, node.LocalTransform.M44)
            };

            if (node.HasProperties)
            {
                ConvertNodeProperties(node.Properties, aiNode);
            }

            if (node.HasAttachments)
            {
                ConvertNodeAttachments(scene, node, aiNode);
            }

            if (node.HasChildren)
            {
                foreach (var childNode in node.Children)
                {
                    aiNode.Children.Add(ConvertNode(scene, childNode, aiNode));
                }
            }

            return(aiNode);
        }
示例#23
0
        void get_bounding_box_for_node(Assimp.Node nd, Vector3 min, Vector3 max)

        {
            //Matrix4x4 prev;
            //uint n = 0, t;

            //for (; n < nd.MeshCount; ++n) {
            //    Assimp.Mesh mesh = scene.Meshes[nd.Children.IndexOf(n)];  //mMeshes[nd->mMeshes[n]];    //////////////////////////////////////////////////////////////////////////
            //    for (t = 0; t < mesh->mNumVertices; ++t) {

            //        aiVector3D tmp = mesh->mVertices[t];

            //        min->x = aisgl_min(min->x,tmp.x);
            //        min->y = aisgl_min(min->y,tmp.y);
            //        min->z = aisgl_min(min->z,tmp.z);

            //        max->x = aisgl_max(max->x,tmp.x);
            //        max->y = aisgl_max(max->y,tmp.y);
            //        max->z = aisgl_max(max->z,tmp.z);
            //    }
            //}

            //for (n = 0; n < nd->mNumChildren; ++n) {
            //    get_bounding_box_for_node(nd->mChildren[n],min,max);
            //}
        }
示例#24
0
        private static bool IsMeshAttachmentNode(Ai.Node node)
        {
            bool isMeshAttachmentNode = node.Parent != null &&                                                          // definitely not a mesh attachment if it doesnt have a parent -> RootNode
                                        node.Parent.Name != "RootNode" &&                                               // probably not a mesh attachment if its part of the scene root
                                        AssimpConverterCommon.MeshAttachmentNameRegex.IsMatch(node.Name) &&             // match name regex
                                        NearlyEquals(node.Transform, Ai.Matrix4x4.Identity);                            // transform must be identity

            return(isMeshAttachmentNode);
        }
        /// <summary>
        /// Gets a <see cref="DomainBone"/> for a given <see cref="AssimpNode"/>.
        /// </summary>
        /// <param name="node">The <see cref="AssimpNode"/> to get a skeleton node from.</param>
        /// <param name="isRootNode">A value indicating if this is the root skeleton node.</param>
        /// <returns>The resulting <see cref="DomainBone"/>.</returns>
        private DomainBone GetSkeletonNode(AssimpNode node, bool isRootNode)
        {
            var childrenBones = node.Children.Select(child => GetSkeletonNode(child, false)).ToArray();

            return(new DomainBone(GetNumericsMatrix4x4(node.Transform),
                                  node.Name,
                                  new ReadOnlyCollection <DomainBone>(childrenBones),
                                  computeWorldToBindMatrices: isRootNode));
        }
示例#26
0
        public static void DrawNormals(Node node, int meshIndex, Mesh mesh, CpuSkinningEvaluator skinner, float invGlobalScale, Matrix4 transform)
        {
            if (!mesh.HasNormals)
            {
                return;
            }

            // The normal directions are transformed using the transpose(inverse(transform)).
            // This ensures correct direction is used when non-uniform scaling is present.
            Matrix4 normalMatrix = transform;
            normalMatrix.Invert();
            normalMatrix.Transpose();

            // Scale by scene size because the scene will be resized to fit
            // the unit box, but the normals should have a fixed length.
            var scale = invGlobalScale * 0.05f;

            GL.Begin(BeginMode.Lines);

            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);
            GL.Enable(EnableCap.ColorMaterial);

            GL.Color4(new Color4(0.0f, 1.0f, 0.0f, 1.0f));

            for (uint i = 0; i < mesh.VertexCount; ++i)
            {
                Vector3 v;
                if (skinner != null && mesh.HasBones)
                {
                    skinner.GetTransformedVertexPosition(node, mesh, i, out v);
                }
                else
                {
                    v = AssimpToOpenTk.FromVector(mesh.Vertices[(int)i]);
                }
                v = Vector4.Transform(new Vector4(v, 1.0f), transform).Xyz; // Skip dividing by W component. It should always be 1, here.

                Vector3 n;
                if (skinner != null)
                {
                    skinner.GetTransformedVertexNormal(node, mesh, i, out n);
                }
                else
                {
                    n = AssimpToOpenTk.FromVector(mesh.Normals[(int)i]);
                }
                n = Vector4.Transform(new Vector4(n, 0.0f), normalMatrix).Xyz; // Toss the W component. It is non-sensical for normals.
                n.Normalize();

                GL.Vertex3(v);
                GL.Vertex3(v + n * scale);
            }
            GL.End();

            GL.Disable(EnableCap.ColorMaterial);
        }
示例#27
0
 /// <summary>
 /// Counts recursively the number of nodes in a node architecture.<br />
 /// Each node contains a pointer to the next nodes in a node architecture.
 /// </summary>
 /// <param name="node">The node to be counted and containing the next nodes as pointers in the node architecture, as a Asssimp.Node.</param>
 /// <param name="nodeNumber">The number of nodes to be updated as the algorithm goes deeper into the node architecture, as an Integer.</param>
 private static void CountNodeNumber(Node node, ref int nodeNumber)
 {
     if (node != null)
     {
         nodeNumber += 1;
         for (int i = 0; i < node.ChildCount; i++)
             CountNodeNumber(node.Children[i], ref nodeNumber);
     }
 }
示例#28
0
 /// <summary>
 /// Creates an Assimp.Animation by copying the given source Assimp.Animation content.<br />
 /// </summary>
 /// <param name="rootNode"></param>
 /// <param name="sourceAnimation">The source Assimp.Animation to copy.</param>
 /// <returns></returns>
 private static Assimp.Animation CreateAssimpAnimation(Node rootNode, Assimp.Animation sourceAnimation)
 {
     Assimp.Animation animation = new Assimp.Animation();
     animation.DurationInTicks = sourceAnimation.DurationInTicks;
     animation.Name = sourceAnimation.Name;
     animation.TicksPerSecond = sourceAnimation.TicksPerSecond;
     CreateNodeAnimationChannels(animation, sourceAnimation.NodeAnimationChannels, rootNode);
     return animation;
 }
示例#29
0
        private void ConvertNodeAttachments(Model model, Node node, Ai.Node aiNode)
        {
            for (int i = 0; i < node.Attachments.Count; i++)
            {
                var attachment = node.Attachments[i];

                switch (attachment.Type)
                {
                case NodeAttachmentType.Mesh:
                {
                    var mesh = ConvertGeometry(model, node, attachment.GetValue <Mesh>());

                    mesh.Name = $"{AssimpConverterCommon.EscapeName(node.Name)}_Attachment{i}_Mesh";
                    aiNode.MeshIndices.Add(mAiScene.Meshes.Count);
                    mAiScene.Meshes.Add(mesh);
                }
                break;

                case NodeAttachmentType.Camera:
                {
                    var camera = attachment.GetValue <Camera>();
                    mAiScene.Cameras.Add(new Ai.Camera
                        {
                            Name          = node.Name,
                            Position      = camera.Position.ToAssimp(),
                            Up            = camera.Up.ToAssimp(),
                            Direction     = -camera.Direction.ToAssimp(),
                            FieldOfview   = MathHelper.DegreesToRadians(camera.FieldOfView),
                            ClipPlaneNear = camera.ClipPlaneNear,
                            ClipPlaneFar  = camera.ClipPlaneFar,
                            AspectRatio   = camera.AspectRatio
                        });
                }
                break;

                case NodeAttachmentType.Light:
                {
                    var light = attachment.GetValue <Light>();
                    mAiScene.Lights.Add(new Ai.Light
                        {
                            Name           = node.Name,
                            AngleInnerCone = light.AngleInnerCone,
                            AngleOuterCone = light.AngleOuterCone,
                            ColorAmbient   = light.AmbientColor.ToAssimpAsColor3D(),
                            ColorDiffuse   = light.DiffuseColor.ToAssimpAsColor3D(),
                            ColorSpecular  = light.SpecularColor.ToAssimpAsColor3D(),
                            LightType      = light.Type == LightType.Point ? Ai.LightSourceType.Point : light.Type == LightType.Spot ? Ai.LightSourceType.Spot : Ai.LightSourceType.Directional,
                        });
                }
                break;

                default:
                    //throw new NotImplementedException();
                    break;
                }
            }
        }
示例#30
0
 private static void CopyNodeTree(Node oriParentNode, Node copyRootNode)
 {
     foreach (Node oriChildNode in oriParentNode.Children)
     {
         //We could use a CopyNode method later if its necessary to add more metadata inside.
         Node newNode = new Node(oriChildNode.Name);
         copyRootNode.Children.Add(newNode);
         CopyNodeTree(oriChildNode, newNode);
     }
 }
示例#31
0
        /// <summary>
        /// Creates an Assimp.NodeAnimationChannel from the given NodeAnimationChannel list and Assimp.Node.<br />
        /// Adds the Assimp.NodeAnimationChannel to the given Assimp.Animation
        /// </summary>
        /// <param name="node"></param>
        /// <param name="channel"></param>
        private static void CreateNodeAnimationChannels(Assimp.Animation animation, List<NodeAnimationChannel> sourceNodeAnimationChannels, Node node)
        {
            NodeAnimationChannel nodeAnimationChannel = new NodeAnimationChannel();
            nodeAnimationChannel = sourceNodeAnimationChannels[animation.NodeAnimationChannelCount];
            nodeAnimationChannel.NodeName = node.Name;
            animation.NodeAnimationChannels.Add(nodeAnimationChannel);

            for (int i = 0; i < node.ChildCount; i++)
                CreateNodeAnimationChannels(animation, sourceNodeAnimationChannels, node.Children[i]);
        }
示例#32
0
        private static Ai.Node CreateAiNodeFromBoneInfo(BoneInfo boneInfo, Matrix4x4 inverseParentTransformation)
        {
            var aiNode = new Ai.Node(boneInfo.Name);

            Matrix4x4.Invert(boneInfo.InverseBindPoseMatrix, out var transformation);

            aiNode.Transform = Matrix4x4.Multiply(transformation, inverseParentTransformation).ToAssimpTransposed();

            return(aiNode);
        }
        private static Node ConvertAssimpNodeRecursively(Ai.Node aiNode, Dictionary <string, NodeInfo> nodeLookup, ref int nextIndex)
        {
            aiNode.Transform.Decompose(out var scale, out var rotation, out var translation);

            // Create node
            var node = new Node(AssimpConverterCommon.UnescapeName(aiNode.Name),
                                new Vector3(translation.X, translation.Y, translation.Z),
                                new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W),
                                new Vector3(scale.X, scale.Y, scale.Z));



            if (!IsMeshAttachmentNode(aiNode))
            {
                // Convert properties
                ConvertAssimpMetadataToProperties(aiNode.Metadata, node);

                if (!nodeLookup.ContainsKey(node.Name))
                {
                    // Add to lookup
                    nodeLookup.Add(node.Name, new NodeInfo(aiNode, node, nextIndex++, false));
                }
                else
                {
                    throw new Exception($"Duplicate node name '{node.Name}'");
                }


                // Process children
                foreach (var aiNodeChild in aiNode.Children)
                {
                    if (aiNodeChild.Name == "RootNode")
                    {
                        // For compatibility with old exports
                        // Merge children of 'RootNode' node with actual root node
                        foreach (var aiFakeRootNodeChild in aiNodeChild.Children)
                        {
                            var childNode = ConvertAssimpNodeRecursively(aiFakeRootNodeChild, nodeLookup, ref nextIndex);
                            node.AddChildNode(childNode);
                        }
                    }
                    else
                    {
                        var childNode = ConvertAssimpNodeRecursively(aiNodeChild, nodeLookup, ref nextIndex);
                        node.AddChildNode(childNode);
                    }
                }
            }
            else
            {
                nodeLookup.Add(node.Name, new NodeInfo(aiNode, node, -1, true));
            }

            return(node);
        }
示例#34
0
        /// <summary>
        /// Generate weights and skeleton Nodes from an assimp skeleton Node.
        /// However pinocchio does not looks to be very good with
        /// that Method.
        /// It takes a
        /// </summary>
        /// <param name="modelPath">The original model Path</param>
        /// <param name="scene"></param>
        /// <param name="skeletalAnim"></param>
        /// <param name="rootSkeletalAnim"></param>
        public void AutomaticRiggingFromSkeleton(string modelPath, Scene scene, Animation skeletalAnim, Node rootSkeletalAnim)
        {
            string skelPathFile = Path.Combine(Path.Combine(projectPath, PINOCCHIO_TMP_DIR_INPUT), "skeleton.out");
            ExportToPinocchioFormat(projectPath, skeletalAnim, rootSkeletalAnim, 0);
            LaunchPinocchioBinary(modelPath, skelPathFile);

            //Import Data that pinocchio did generated
            //There is a problem here since we dont have a way to associate AssimpNodes and Bones in the attachement.out for now()
            BuildBones(scene.Meshes[0], rootSkeletalAnim);
            BuildBonesWeight(scene);
        }
示例#35
0
 private static void ConvertAiNodesFromBonesRecursively(Ai.Node parent, Matrix4x4 inverseParentTransform, string parentName, List <Bone> bones, Dictionary <string, string> boneParentMap, bool appendTags = false)
 {
     foreach (var bone in bones)
     {
         if (boneParentMap[bone.Name] == parentName)
         {
             var boneNode = ConvertAiNodeFromBone(parent, inverseParentTransform, bone, appendTags);
             ConvertAiNodesFromBonesRecursively(boneNode, bone.Matrix, bone.Name, bones, boneParentMap, appendTags);
         }
     }
 }
示例#36
0
        public static void DrawSkeletonBone(Node node, float invGlobalScale, bool highlight)
        {
            var target = new Vector3(node.Transform.A4, node.Transform.B4, node.Transform.C4);
            if (!(target.LengthSquared > 1e-6f))
            {
                return;
            }

            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);
            GL.Enable(EnableCap.ColorMaterial);
            GL.Disable(EnableCap.DepthTest);

            GL.Color4(highlight ? new Color4(0.0f, 1.0f, 0.5f, 1.0f) : new Color4(0.0f, 0.5f, 1.0f, 1.0f));

            var right = new Vector3(1, 0, 0);
            var targetNorm = target;
            targetNorm.Normalize();

            Vector3 up;
            Vector3.Cross(ref targetNorm, ref right, out up);
            Vector3.Cross(ref up, ref targetNorm, out right);

            up *= invGlobalScale;
            right *= invGlobalScale;

            const float jointWidth = 0.03f;

            GL.Begin(BeginMode.LineLoop);
            GL.Vertex3(-jointWidth * up + -jointWidth * right);
            GL.Vertex3(-jointWidth * up + jointWidth * right);
            GL.Vertex3(jointWidth * up + jointWidth * right);
            GL.Vertex3(jointWidth * up + -jointWidth * right);
            GL.End();

            GL.Begin(BeginMode.Lines);
            GL.Vertex3(-jointWidth * up + -jointWidth * right);
            GL.Vertex3(target);
            GL.Vertex3(-jointWidth * up + jointWidth * right);
            GL.Vertex3(target);
            GL.Vertex3(jointWidth * up + jointWidth * right);
            GL.Vertex3(target);
            GL.Vertex3(jointWidth * up + -jointWidth * right);
            GL.Vertex3(target);

            GL.Color4(highlight ? new Color4(1.0f, 0.0f, 0.0f, 1.0f) : new Color4(1.0f, 1.0f, 0.0f, 1.0f));

            GL.Vertex3(Vector3.Zero);
            GL.Vertex3(target);
            GL.End();

            GL.Disable(EnableCap.ColorMaterial);
            GL.Enable(EnableCap.DepthTest);
        }
示例#37
0
        private static Ai.Matrix4x4 GetGlobalTransformation(Ai.Node aiNode)
        {
            var transform = Ai.Matrix4x4.Identity;

            for (var node = aiNode; aiNode != null; aiNode = aiNode.Parent)
            {
                transform = transform * aiNode.Transform;
            }

            return(transform);
        }
示例#38
0
        private static Matrix4x4 GetWorldTransform(Ai.Node aiNode)
        {
            var transform = aiNode.Transform;

            while ((aiNode = aiNode.Parent) != null)
            {
                transform *= aiNode.Transform;
            }

            return(transform.ToNumericsTransposed());
        }
示例#39
0
        private static Object CreateObjectFromAiNode(Ai.Node aiNode, Ai.Scene aiScene, ObjectSet objectSet, string texturesDirectoryPath)
        {
            var obj = new Object();

            obj.Name = aiNode.Name;
            obj.Id   = MurmurHash.Calculate(aiNode.Name);
            obj.Skin = new Skin();

            var aabb = new AxisAlignedBoundingBox();

            CreateRecursively(aiNode);

            void CreateRecursively(Ai.Node aiChildNode)
            {
                if (aiChildNode.HasMeshes)
                {
                    var meshes = CreateMeshesFromAiNode(aiChildNode, aiScene, obj, ref aabb, objectSet,
                                                        texturesDirectoryPath);

                    if (meshes?.Count > 0)
                    {
                        obj.Meshes.AddRange(meshes);
                    }
                }

                foreach (var aiAlsoChildNode in aiChildNode.Children)
                {
                    CreateRecursively(aiAlsoChildNode);
                }
            }

            obj.BoundingSphere = aabb.ToBoundingSphere();

            if (obj.Skin.Bones.Count > 0)
            {
                foreach (var boneInfo in obj.Skin.Bones)
                {
                    var aiBoneNode = aiScene.RootNode.FindNode(boneInfo.Name);
                    if (aiBoneNode.Parent == null || aiBoneNode.Parent == aiScene.RootNode)
                    {
                        continue;
                    }

                    boneInfo.Parent = obj.Skin.Bones.FirstOrDefault(x => x.Name == aiBoneNode.Parent.Name);
                }
            }

            else
            {
                obj.Skin = null;
            }

            return(obj);
        }
示例#40
0
        private static void ConvertNodeProperties(UserPropertyCollection properties, Ai.Node aiNode)
        {
            var stringBuilder = new StringBuilder();

            foreach (var property in properties.Values)
            {
                // Todo: Assign to 3ds max user properties
                stringBuilder.Append($"{property.ToUserPropertyString()}&cr;&lf;");
            }

            aiNode.Metadata["UDP3DSMAX"] = new Ai.Metadata.Entry(Ai.MetaDataType.String, stringBuilder.ToString());
        }
示例#41
0
        private Rigging.Bone AssimpNodesToBonesRecursive(Assimp.Node node, Rigging.Bone parent, List <Rigging.Bone> boneList)
        {
            Rigging.Bone newBone = new Rigging.Bone(node, parent);
            boneList.Add(newBone);

            for (int i = 0; i < node.ChildCount; i++)
            {
                newBone.Children.Add(AssimpNodesToBonesRecursive(node.Children[i], newBone, boneList));
            }

            return(newBone);
        }
示例#42
0
        public static Ai.Scene ExportToAiScene(ObjectSet objectSet)
        {
            if (objectSet.TextureSet != null)
            {
                foreach (var texture in objectSet.TextureSet.Textures
                         .Where(texture => string.IsNullOrEmpty(texture.Name)))
                {
                    texture.Name = Guid.NewGuid().ToString();
                }
            }

            var aiScene = new Ai.Scene {
                RootNode = new Ai.Node("RootNode")
            };

            var convertedMaterials = new HashSet <string>();

            foreach (var obj in objectSet.Objects)
            {
                foreach (var material in obj.Materials)
                {
                    var aiMaterial = CreateAiMaterialFromMaterial(material, objectSet.TextureSet);
                    if (convertedMaterials.Contains(aiMaterial.Name))
                    {
                        aiMaterial.Name += "+" + material.Name;
                    }

                    aiScene.Materials.Add(aiMaterial);
                    convertedMaterials.Add(aiMaterial.Name);
                }
            }

            var convertedBones = new Dictionary <string, Ai.Node>();
            var gblctrNode     = new Ai.Node("gblctr");

            foreach (var obj in objectSet.Objects)
            {
                if (obj.Skin != null)
                {
                    CreateAiNodesFromBoneInfos(obj.Skin.Bones, aiScene, gblctrNode, null, convertedBones);
                }

                aiScene.RootNode.Children.Add(CreateAiNodeFromObject(obj, aiScene));
            }

            if (gblctrNode.HasChildren)
            {
                aiScene.RootNode.Children.Add(gblctrNode);
            }

            return(aiScene);
        }
示例#43
0
        private void proccessNode(ai.Node node, ai.Scene scene, MeshLoader loader)
        {
            foreach (int index in node.MeshIndices)
            {
                ai.Mesh mesh = scene.Meshes[index];
                Meshes.Add(loader(mesh, scene));
            }

            foreach (ai.Node child in node.Children)
            {
                proccessNode(child, scene, loader);
            }
        }
示例#44
0
        private void ProcessNode(Assimp.Node node, Assimp.Scene scene)
        {
            for (int i = 0; i < node.MeshCount; i++)
            {
                Assimp.Mesh amesh = scene.Meshes[node.MeshIndices[i]];
                _meshes.Add(ProcessMesh(amesh, scene));
            }

            for (int i = 0; i < node.ChildCount; i++)
            {
                ProcessNode(node.Children[i], scene);
            }
        }
示例#45
0
        private static Ai.Matrix4x4 GetWorldTransform(Ai.Node aiNode)
        {
            var transform = aiNode.Transform;
            var parent    = aiNode.Parent;

            while (parent != null)
            {
                transform *= parent.Transform;
                parent     = parent.Parent;
            }

            return(transform);
        }
示例#46
0
        /// <summary>
        /// Sets the contents of the info pop-up given an assimp node.
        /// 
        /// At the time this method is called, the node info popup's
        /// location has already been adjusted by the caller.
        /// </summary>
        public void Populate(Assimp.Scene scene, Node node, NodePurpose purpose)
        {
            Debug.Assert(scene != null);
            Debug.Assert(node != null);
            Debug.Assert(_owner != null);
            switch (purpose)
            {
                case NodePurpose.Joint:
                    labelCaption.Text = "Joint";
                    break;
                case NodePurpose.ImporterGenerated:
                    labelCaption.Text = "Root";
                    break;
                case NodePurpose.GenericMeshHolder:
                    labelCaption.Text = "Node";
                    break;
                case NodePurpose.Camera:
                    labelCaption.Text = "Camera";
                    break;
                case NodePurpose.Light:
                    labelCaption.Text = "Light";
                    break;
                default:
                    Debug.Assert(false);
                    break;
            }

            // count children recursively
            var children = 0;
            CountChildren(node, ref children);

            var animated = false;

            // check whether there are any animation channels for this node
            for (var i = 0; i < scene.AnimationCount && !animated; ++i )
            {
                var anim = scene.Animations[i];
                for(var j = 0; j < anim.NodeAnimationChannelCount; ++j)
                {
                    if(anim.NodeAnimationChannels[j].NodeName == node.Name)
                    {
                        animated = true;
                        break;
                    }
                }
            }

            labelInfo.Text = string.Format("{0} Children\n{1}", children, (animated ? "Animated" : "Not animated"));
        }
示例#47
0
        public static void DrawNormals(Node node, int meshIndex, Mesh mesh, CpuSkinningEvaluator skinner, float invGlobalScale)
        {
            if (!mesh.HasNormals)
            {
                return;
            }
            // Scale by scene size because the scene will be resized to fit
            // the unit box but the normals should have a fixed length
            var scale = invGlobalScale * 0.05f;

            GL.Begin(BeginMode.Lines);

            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);
            GL.Enable(EnableCap.ColorMaterial);

            GL.Color4(new Color4(0.0f, 1.0f, 0.0f, 1.0f));

            for (uint i = 0; i < mesh.VertexCount; ++i)
            {
                Vector3 v;
                if (skinner != null && mesh.HasBones)
                {
                    skinner.GetTransformedVertexPosition(node, meshIndex, i, out v);
                }
                else
                {
                    v = AssimpToOpenTk.FromVector(mesh.Vertices[(int)i]);
                }

                Vector3 n;
                if (skinner != null)
                {
                    skinner.GetTransformedVertexNormal(node, meshIndex, i, out n);
                }
                else
                {
                    n = AssimpToOpenTk.FromVector(mesh.Normals[(int)i]);
                }

                GL.Vertex3(v);
                GL.Vertex3(v + n * scale);
            }
            GL.End();

            GL.Disable(EnableCap.ColorMaterial);
        }
示例#48
0
 static Node LookForMatch(Node root, string name)
 {
     string namelow = name.ToLower();
     if (root.Name.ToLower() == namelow)
     {
         return root;
     }
     for (int i = 0; i < root.ChildCount; i++)
     {
         Node found = LookForMatch(root.Children[i], name);
         if (found != null)
         {
             return found;
         }
     }
     return null;
 }
示例#49
0
            public void GetTransformedVertexPosition(Node node, uint vertexIndex, out Vector3 pos)
            {
                // note: the scenario in which a skinned mesh is referenced by multiple nodes
                // is not currently implemented properly. It works, but it prevents caching.
                if (node != _lastNode)
                {
                    _lastNode = node;
                    _dirty = true;
                }
                if(_dirty)
                {
                   Cache();        
                }
                Debug.Assert(!_dirty);

                Debug.Assert(vertexIndex < _cachedPositions.Length);
                pos = _cachedPositions[vertexIndex];
            }
示例#50
0
        /// <summary>
        /// Constructs a new Node.
        /// </summary>
        /// <param name="aiNode">Unmanaged AiNode structure</param>
        /// <param name="parent">Parent of this node or null</param>
        internal Node(AiNode aiNode, Node parent)
        {
            _name = aiNode.Name.GetString();
            _transform = aiNode.Transformation;
            _parent = parent;

            if(aiNode.NumChildren > 0 && aiNode.Children != IntPtr.Zero) {
                AiNode[] childNodes = MemoryHelper.MarshalArray<AiNode>(aiNode.Children, (int) aiNode.NumChildren, true);
                _children = new Node[childNodes.Length];
                for(int i = 0; i < _children.Length; i++) {
                    _children[i] = new Node(childNodes[i], this);
                }
            }

            if(aiNode.NumMeshes > 0 && aiNode.Meshes != IntPtr.Zero) {
                _meshes = MemoryHelper.MarshalArray<int>(aiNode.Meshes, (int) aiNode.NumMeshes);
            }
        }
        /// <summary>
        /// Allows to merge 2 Node hierarchy
        /// </summary>
        /// <param name="rootNode1">The root Node of the first Node Hierarchy</param>
        /// <param name="mergeNodeName1">The name of the node that we want to merge with mergeNodeName2</param>
        /// <param name="rootNode2">The root Node of the first Node Hierarchy</param>
        /// <param name="mergeNodeName2">The name of the node that we want to merge with mergdeNodeName1</param>
        /// <param name="childrenCopy">Should we make a simple jointure or only copy the nodes childrens</param>
        public static Node MergeNodeStructure(Node rootNode1, string mergeNodeName1, Node rootNode2, string mergeNodeName2, ref MergeBehaviour mergeBehav)
        {
            Node rootNode1Copy = rootNode1;
            if (mergeBehav.copyTreeNode1)
                rootNode1Copy = AssimpUtil.DuplicateNodeTree(rootNode1);
            Node rootNode2Copy = rootNode2;
            if (mergeBehav.copyTreeNode2)
                rootNode2Copy = AssimpUtil.DuplicateNodeTree(rootNode2);

            Node mergeNode1 = rootNode1Copy.FindNode(mergeNodeName1);
            Node mergeNode2 = rootNode2Copy.FindNode(mergeNodeName2);

            if (mergeBehav.childrenCopy)
            {
                foreach (Node tmp in mergeNode2.Children)
                    mergeNode1.Children.Add(tmp);
            }
            else
                mergeNode1.Children.Add(mergeNode2);
            return rootNode1Copy;
        }
示例#52
0
        /// <summary>
        /// Rename node to the given new name.
        /// 
        /// Does not create UndoStack entries itself, caller must do this.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="newName"></param>
        public void RenameNode(Node node, string newName)
        {
            if (newName == node.Name)
            {
                return;
            }

            var oldName = node.Name;
            node.Name = newName;

            // Update references from bones
            foreach (var mesh in _scene.Raw.Meshes)
            {
                foreach (var bone in mesh.Bones)
                {
                    if (bone.Name == oldName)
                    {
                        bone.Name = newName;
                    }
                }
            }

            // Update references from node animation channels
            foreach (var anim in _scene.Raw.Animations)
            {
                foreach (var channel in anim.NodeAnimationChannels)
                {
                    if (channel.NodeName == oldName)
                    {
                        channel.NodeName = newName;
                    }
                }
            }

            // SceneAnimator is - unfortunately - name based.
            _scene.SceneAnimator.RenameNode(oldName, newName);
        }
示例#53
0
        /// <summary>
        ///  Icrtavanje objekata u sceni koji su reprezentovani datim cvorom, kao i njegovim pod-cvorovima. 
        ///  U zavisnosti od karakteristika objekata podesavaju se odgovarajuce promenjive stanja (GL_LIGHTING, GL_COLOR_MATERIAL, GL_TEXTURE_2D).
        /// </summary>
        /// <param name="node">Cvor koji ce biti iscrtan.</param>
        private void RenderNode(Node node)
        {
            Gl.glPushMatrix();

            // Primena tranformacija vezanih za dati cvor.
            float[] matrix = new float[16] { node.Transform.A1, node.Transform.B1, node.Transform.C1, node.Transform.D1, node.Transform.A2, node.Transform.B2, node.Transform.C2, node.Transform.D2, node.Transform.A3, node.Transform.B3, node.Transform.C3, node.Transform.D3, node.Transform.A4, node.Transform.B4, node.Transform.C4, node.Transform.D4 };
            Gl.glMultMatrixf(matrix);

            // Iscrtavanje objekata u sceni koji su reprezentovani datim cvorom.
            if (node.HasMeshes)
            {
                foreach (int index in node.MeshIndices)
                {
                    Mesh mesh = m_scene.Meshes[index];
                    Material material = m_scene.Materials[mesh.MaterialIndex];

                    // Primena komponenti materijala datog objekta.
                    ApplyMaterial(material);

                    // Primena teksture u slucaju da je ista definisana za dati materijal.
                    if (material.GetAllTextures().Length > 0)
                        Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texMappings[material.GetAllTextures()[0]]);

                    // Podesavanje proracuna osvetljenja za dati objekat.
                    bool hasNormals = mesh.HasNormals;
                    if (hasNormals)
                        Gl.glEnable(Gl.GL_LIGHTING);
                    else
                        Gl.glDisable(Gl.GL_LIGHTING);

                    // Podesavanje color tracking mehanizma za dati objekat.
                    bool hasColors = mesh.HasVertexColors(0);
                    if (hasColors)
                        Gl.glEnable(Gl.GL_COLOR_MATERIAL);
                    else
                        Gl.glDisable(Gl.GL_COLOR_MATERIAL);

                    // Podesavanje rezima mapiranja na teksture.
                    bool hasTexCoords = material.GetAllTextures().Length > 0 && mesh.HasTextureCoords(0);
                    if (hasTexCoords)
                        Gl.glEnable(Gl.GL_TEXTURE_2D);
                    else
                        Gl.glDisable(Gl.GL_TEXTURE_2D);

                    // Iscrtavanje primitiva koji cine dati objekat.
                    // U zavisnosti od broja temena, moguce je iscrtavanje tacaka, linija, trouglova ili poligona.
                    foreach (Face face in mesh.Faces)
                    {
                        switch (face.IndexCount)
                        {
                            case 1:
                                Gl.glBegin(Gl.GL_POINTS);
                                break;
                            case 2:
                                Gl.glBegin(Gl.GL_LINES);
                                break;
                            case 3:
                                Gl.glBegin(Gl.GL_TRIANGLES);
                                break;
                            default:
                                Gl.glBegin(Gl.GL_POLYGON);
                                break;
                        }

                        for (int i = 0; i < face.IndexCount; i++)
                        {
                            uint indice = face.Indices[i];

                            // Definisanje boje temena.
                            if (hasColors)
                                Gl.glColor4f(mesh.GetVertexColors(0)[indice].R, mesh.GetVertexColors(0)[indice].G, mesh.GetVertexColors(0)[indice].B, mesh.GetVertexColors(0)[indice].A);

                            // Definisanje normale temena.
                            if (hasNormals)
                                Gl.glNormal3f(mesh.Normals[indice].X, mesh.Normals[indice].Y, mesh.Normals[indice].Z);

                            // Definisanje koordinata teksture temena.
                            if (hasTexCoords)
                                Gl.glTexCoord2f(mesh.GetTextureCoords(0)[indice].X, 1 - mesh.GetTextureCoords(0)[indice].Y);

                            // Definisanje temena primitive.
                            Gl.glVertex3f(mesh.Vertices[indice].X, mesh.Vertices[indice].Y, mesh.Vertices[indice].Z);
                        }
                        Gl.glEnd();
                    }
                }
            }

            // Rekurzivno iscrtavanje cvorova potomaka tekuceg cvora
            for (int i = 0; i < node.ChildCount; i++)
            {
                RenderNode(node.Children[i]);
            }

            Gl.glPopMatrix();
        }
示例#54
0
        private NodeState CreateNodeTree(Node rootNode, NodeState parent)
        {
            var outNode = new NodeState {LocalTransform = AssimpToOpenTk.FromMatrix(rootNode.Transform)};
            outNode.Parent = parent;

            // calculate transforms
            outNode.GlobalTransform = parent != null ? parent.GlobalTransform * outNode.LocalTransform : outNode.LocalTransform;

            // populate by-name map to quickly map nodes to their state
            _nodeStateByName[rootNode.Name] = outNode;

            // find the index of the animation track affecting this node, if any
            outNode.ChannelIndex = -1;
            if (ActiveAnimation != -1)
            {
                var channels = _raw.Animations[ActiveAnimation].NodeAnimationChannels;
                for (int i = 0; i < channels.Count; ++i)
                {
                    if (channels[i].NodeName != rootNode.Name)
                    {
                        continue;
                    }
                    outNode.ChannelIndex = i;
                    break;
                }
            }

            outNode.Children = new NodeState[rootNode.ChildCount];

            // recursively add up children
            for (int i = 0; i < rootNode.ChildCount; ++i)
            {
                outNode.Children[i] = CreateNodeTree(rootNode.Children[i], outNode);
            }

            return outNode;
        }
示例#55
0
        /// <summary>
        /// Obtain the bone matrices for a given node mesh index at the
        /// current time. Calling this is costly, redundant invocations
        /// should thus be avoided.
        /// </summary>
        /// <param name="node">Node for which to query bone matrices</param>
        /// <param name="mesh">Mesh for which to query bone matrices. Must be
        ///    one of the meshes attached to the node.</param>
        /// <returns>For each bone of the mesh the bone transformation
        /// matrix. The returned array is only valid for the rest of
        /// the frame or till the next call to GetBoneMatricesForMesh(). 
        /// It may contain more entries than the mesh has bones, the extra entries 
        /// should be ignored in this case.</returns>
        public Matrix4[] GetBoneMatricesForMesh(Node node, Mesh mesh)
        {
            Debug.Assert(node != null);
            Debug.Assert(mesh != null);

            // calculate the mesh's inverse global transform
            Matrix4 globalInverseMeshTransform;
            GetGlobalTransform( node, out globalInverseMeshTransform );
            globalInverseMeshTransform.Invert();

            // Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose
            // Therefore the formula is offsetMatrix * currentGlobalTransform * inverseCurrentMeshTransform
            for( int a = 0; a < mesh.BoneCount; ++a)
            {
                var bone = mesh.Bones[a];

                Matrix4 currentGlobalTransform;
                GetGlobalTransform( bone.Name, out currentGlobalTransform );
                _boneMatrices[a] = globalInverseMeshTransform * currentGlobalTransform * AssimpToOpenTk.FromMatrix(bone.OffsetMatrix);
                // TODO for some reason, all OpenTk matrices need a ^T - clarify our conventions somewhere
                _boneMatrices[a].Transpose();
            }
            return _boneMatrices;
        }
示例#56
0
 /// <summary>
 /// Obtain the current local transformation matrix for a node
 /// </summary>
 /// <param name="node">Node</param>
 /// <param name="outTrafo">Receives the transformation matrix</param>
 public void GetLocalTransform(Node node, out Matrix4 outTrafo)
 {
     GetLocalTransform(node.Name, out outTrafo);
 }
示例#57
0
        private SEAMesh AppendMesh(Scene scene, Node node, List<Mesh> meshes, SEAObject3D parent)
        {
            int sIndex = GetIndexByTag(node);

            if (sIndex != -1) return (SEAMesh)Writer.Objects[sIndex];

            List<Animation> anmList = GetAnimation(scene, node.Name);

            SEAGeometry geo = AppendGeometry(scene, node, meshes);

            if (geo != null)
            {
                SEAMesh seaMesh = new SEAMesh(node.Name);

                /*if (meshes[0].HasMeshAnimationAttachments)
                {
                }*/

                Mesh mesh = meshes[0];

                if (Modifiers && geo.jointPerVertex > 0)
                {
                    seaMesh.modifiers.Add((uint)GetIndex(AppendSkeleton(scene, mesh)));
                    seaMesh.animations.Add((uint)GetIndex(AppendSkeletonAnimation(scene, mesh)));
                }

                if (mesh.MaterialIndex != -1)
                {
                    seaMesh.materials.Add(GetIndex(AppendMaterial(scene, scene.Materials[mesh.MaterialIndex])));
                }

                seaMesh.parent = parent != null ? GetIndex(parent) : -1;

                objects.Add(seaMesh);
                Writer.AddObject(seaMesh);

                seaMesh.transform = To3x4Array( node.Transform );
                seaMesh.geometry = GetIndex(geo);

                seaMesh.tag = node;

                return seaMesh;
            }

            return null;
        }
示例#58
0
        private object GetUnrelatedObjectByNode(Node node, Scene scene)
        {
            foreach (Light light in scene.Lights)
            {
                if (light.Name == node.Name)
                    return light;
            }

            foreach (Camera camera in scene.Cameras)
            {
                if (camera.Name == node.Name)
                    return camera;
            }

            return null;
        }
示例#59
0
 private SEAObject3D AppendObject3D(Scene scene, Node node)
 {
     return AppendObject3D(scene, node, null);
 }
示例#60
0
        private SEAObject3D AppendObject3D(Scene scene, Node node, SEAObject3D parent)
        {
            SEAObject3D object3d = null;

            /*
                mtx.e00 / scale.x, mtx.e10 / scale.x, mtx.e20 / scale.x,
                mtx.e01 / scale.y, mtx.e11 / scale.y, mtx.e21 / scale.y,
                mtx.e02 / scale.z, mtx.e12 / scale.z, mtx.e22 / scale.z
            */

            //node.Transform = node.Transform * Matrix4x4.FromEulerAnglesXYZ(-90, 0, 0);

            if (node.MeshCount > 0)
            {
                object3d = AppendMesh(scene, node, scene.Meshes, parent);
            }
            else if (!MeshOnly && scene.RootNode != node)
            {
                object unrelatedObject = GetUnrelatedObjectByNode(node, scene);

                if (unrelatedObject is Light)
                {
                    object3d = AppendLight(scene, node, (Light)unrelatedObject, parent);
                }
                else if (unrelatedObject is Camera)
                {
                    object3d = AppendCamera(scene, node, (Camera)unrelatedObject, parent);
                }
                else if (EnabledDummy)
                {
                    object3d = AppendDummy(scene, node, parent);
                }
            }

            foreach (Node children in node.Children)
            {
                AppendObject3D(scene, children, object3d);
            }

            return null;
        }