Пример #1
0
 public AnimationNode RecursiveCopy(SortedList<string, AnimationNode> nodeCollection)
 {
     AnimationNode node = new AnimationNode(this.Name, this.Translation, this.Rotation);
     nodeCollection.Add(node.Name, node);
     for (int i = 0; i < this.children.Count; i++)
     {
         AnimationNode child = this.children[i].RecursiveCopy(nodeCollection);
         node.children.Add(child);
     }
     return node;
 }
Пример #2
0
 public void CreateRagdoll(AnimationNode[] rootNodes)
 {
     limbs = new SortedList<string, PhysicsObject>();
     joints = new List<HingeJoint>();
     //DisableCollisions(limbs[(int)LimbId.Torso].PhysicsBody, limbs[(int)LimbId.LowerLegLeft].PhysicsBody);
 }
Пример #3
0
        void LoadMS3D(string filename)
        {
            using (FileStream fs = new FileStream(filename, FileMode.Open))
            {
                using (BinaryReader br = new BinaryReader(fs, System.Text.Encoding.Default))
                {
                    br.ReadChars(10);
                    br.ReadInt32();
                    vertexCount = br.ReadUInt16();
                    ModelVertex[] vertices = new ModelVertex[vertexCount];

                    Vector3 minVert = Vector3.One * float.PositiveInfinity;
                    Vector3 maxVert = Vector3.One * float.NegativeInfinity;
                    for (int i = 0; i < vertexCount; i++)
                    {
                        br.ReadByte();
                        vertices[i].Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        minVert = Vector3.Min(minVert, vertices[i].Position);
                        maxVert = Vector3.Max(maxVert, vertices[i].Position);
                        vertices[i].BoneIndex = (int)br.ReadChar();
                        if (vertices[i].BoneIndex >= 255)
                            vertices[i].BoneIndex = 0;
                        vertices[i].Weight = 1;
                        br.ReadByte();
                    }

                    ushort triangleCount = br.ReadUInt16();

                    Triangle[] triList = new Triangle[triangleCount];
                    for (int i = 0; i < triangleCount; i++)
                    {
                        br.ReadUInt16(); //flag

                        //Indices
                        ushort v0 = br.ReadUInt16();
                        ushort v1 = br.ReadUInt16();
                        ushort v2 = br.ReadUInt16();
                        triList[i].vertex0 = v0;
                        triList[i].vertex1 = v1;
                        triList[i].vertex2 = v2;

                        //Vertex 0 Normal
                        vertices[v0].Normal += new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());

                        //Vertex 1 Normal
                        vertices[v1].Normal += new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());

                        //Vertex 2 Normal
                        vertices[v2].Normal += new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());

                        //U
                        vertices[v0].TexCoord.X = br.ReadSingle();
                        vertices[v1].TexCoord.X = br.ReadSingle();
                        vertices[v2].TexCoord.X = br.ReadSingle();

                        //V
                        vertices[v0].TexCoord.Y = br.ReadSingle();
                        vertices[v1].TexCoord.Y = br.ReadSingle();
                        vertices[v2].TexCoord.Y = br.ReadSingle();

                        vertices[v0].Weight++;
                        vertices[v1].Weight++;
                        vertices[v2].Weight++;

                        //Smoothing
                        br.ReadByte();

                        //Group index
                        br.ReadByte();
                    }

                    for (int i = 0; i < vertexCount; i++)
                    {
                        vertices[i].Normal /= vertices[i].Weight;
                        vertices[i].Weight = 1;
                    }

                    for (int i = 0; i < triangleCount; i++)
                    {
                        vertices[triList[i].vertex0].AddTangent(vertices[triList[i].vertex1], vertices[triList[i].vertex2]);
                        vertices[triList[i].vertex1].AddTangent(vertices[triList[i].vertex0].Tangent, vertices[triList[i].vertex0].Tangent2);
                        vertices[triList[i].vertex2].AddTangent(vertices[triList[i].vertex0].Tangent, vertices[triList[i].vertex0].Tangent2);
                        //vertices[triList[i].vertex1].AddTangent(vertices[triList[i].vertex0], vertices[triList[i].vertex2]);
                        //vertices[triList[i].vertex2].AddTangent(vertices[triList[i].vertex0], vertices[triList[i].vertex1]);
                    }

                    VertexPNTTI[] verts = new VertexPNTTI[vertexCount];
                    for (int i = 0; i < vertexCount; i++)
                    {
                        Vector3 N = vertices[i].Normal;
                        N.Normalize();
                        Vector3 tangent = vertices[i].Tangent / vertices[i].Weight;
                        tangent = (tangent - N * Vector3.Dot(N, tangent));
                        tangent.Normalize();
                        vertices[i].Tangent = tangent;
                        vertices[i].Tangent2 /= vertices[i].Weight;
                        vertices[i].Weight = 1;
                        float binormSign = (Vector3.Dot(Vector3.Cross(N, tangent), vertices[i].Tangent2) < 0.0f) ? -1.0f : 1.0f;
                        verts[i] = new VertexPNTTI(vertices[i].Position, vertices[i].Normal, vertices[i].TexCoord, vertices[i].Tangent, vertices[i].BoneIndex, binormSign);
                    }
                    vertexBuffer = new VertexBuffer(GFX.Device, vertexCount * VertexPNTTI.SizeInBytes, BufferUsage.None);
                    vertexBuffer.SetData<VertexPNTTI>(verts);

                    ushort groupCount = br.ReadUInt16();
                    parts = new ModelPart[groupCount];
                    int[] matIndices = new int[groupCount];
                    for (int i = 0; i < groupCount; i++)
                    {
                        br.ReadByte();
                        parts[i] = new ModelPart();
                        parts[i].name = new string(br.ReadChars(32)); //Group Name
                        parts[i].name = parts[i].name.Replace("\0",string.Empty);
                        ushort numTriangles = br.ReadUInt16(); //numTriangles

                        parts[i].renderElement = new RenderElement();
                        parts[i].renderElement.PrimitiveCount = numTriangles;
                        parts[i].renderElement.StartVertex = 0;
                        parts[i].renderElement.VertexBuffer = vertexBuffer;
                        parts[i].renderElement.VertexCount = vertexCount;
                        parts[i].renderElement.VertexStride = VertexPNTTI.SizeInBytes;
                        parts[i].renderElement.VertexDec = GFXVertexDeclarations.PNTTIDec;
                        parts[i].bounds.Max = Vector3.Zero;
                        parts[i].bounds.Min = Vector3.Zero;

                        bool useIntIndices = (numTriangles >= ushort.MaxValue);
                        IndexElementSize size = (useIntIndices) ? IndexElementSize.ThirtyTwoBits : IndexElementSize.SixteenBits;
                        int stride = (useIntIndices) ? sizeof(uint) : sizeof(ushort);

                        parts[i].renderElement.IndexBuffer = new IndexBuffer(GFX.Device, stride * numTriangles * 3, BufferUsage.None, size);

                        List<ushort> ushortIndices = new List<ushort>();
                        List<uint> uintIndices = new List<uint>();
                        for (int l = 0; l < numTriangles; l++)
                        {
                            ushort t = br.ReadUInt16(); //triangle index
                            if (useIntIndices)
                            {
                                uintIndices.Add((uint)triList[t].vertex2);
                                uintIndices.Add((uint)triList[t].vertex1);
                                uintIndices.Add((uint)triList[t].vertex0);

                            }
                            else
                            {
                                ushortIndices.Add((ushort)triList[t].vertex2);
                                ushortIndices.Add((ushort)triList[t].vertex1);
                                ushortIndices.Add((ushort)triList[t].vertex0);
                            }
                            parts[i].bounds.Max = Vector3.Max(parts[i].bounds.Max, vertices[triList[t].vertex0].Position);
                            parts[i].bounds.Max = Vector3.Max(parts[i].bounds.Max, vertices[triList[t].vertex1].Position);
                            parts[i].bounds.Max = Vector3.Max(parts[i].bounds.Max, vertices[triList[t].vertex2].Position);

                            parts[i].bounds.Min = Vector3.Min(parts[i].bounds.Min, vertices[triList[t].vertex0].Position);
                            parts[i].bounds.Min = Vector3.Min(parts[i].bounds.Min, vertices[triList[t].vertex1].Position);
                            parts[i].bounds.Min = Vector3.Min(parts[i].bounds.Min, vertices[triList[t].vertex2].Position);
                        }
                        if (useIntIndices)
                            parts[i].renderElement.IndexBuffer.SetData<uint>(uintIndices.ToArray());
                        else
                            parts[i].renderElement.IndexBuffer.SetData<ushort>(ushortIndices.ToArray());

                        matIndices[i] = (int)br.ReadChar(); //Material index
                    }

                    meshBounds = new BoundingBox(parts[0].bounds.Min, parts[0].bounds.Max);
                    for (int i = 1; i < parts.Length; i++)
                    {
                        meshBounds.Min = Vector3.Min(parts[i].bounds.Min, meshBounds.Min);
                        meshBounds.Max = Vector3.Max(parts[i].bounds.Max, meshBounds.Max);
                    }

                    ushort MaterialCount = br.ReadUInt16();
                    string[] materialNames = new string[MaterialCount];
                    for (int i = 0; i < MaterialCount; i++)
                    {

                        materialNames[i] = new string(br.ReadChars(32));
                        materialNames[i] = materialNames[i].Replace("\0", string.Empty);
                        for (int l = 0; l < 4; l++)
                            br.ReadSingle();
                        for (int l = 0; l < 4; l++)
                            br.ReadSingle();
                        for (int l = 0; l < 4; l++)
                            br.ReadSingle();
                        for (int l = 0; l < 4; l++)
                            br.ReadSingle();

                        br.ReadSingle();
                        br.ReadSingle();
                        br.ReadChar();
                        br.ReadChars(128);
                        br.ReadChars(128);
                    }

                    CheckMissingMaterials(filename, matIndices, materialNames);

                    for (int i = 0; i < groupCount; i++)
                    {
                        int matIndex = matIndices[i];
                        if (matIndex < 255)
                            parts[i].material = ResourceManager.Inst.GetMaterial(materialNames[matIndex]);

                        if (parts[i].material == null)
                            parts[i].material = ResourceManager.Inst.GetMaterial("NULL");
                    }

                    float fps = br.ReadSingle();//FPS
                    br.ReadSingle();//current time
                    int frameCount = br.ReadInt32(); //Total frames

                    ushort boneCount = br.ReadUInt16();
                    nodes = new AnimationNode[boneCount];
                    if (boneCount > 0)
                    {
                        List<string> nodeParentNames = new List<string>();

                        for (int i = 0; i < boneCount; i++)
                        {
                            br.ReadByte(); //flag

                            string name = new string(br.ReadChars(32)).Replace("\0", "");
                            string parentName = new string(br.ReadChars(32)).Replace("\0", "");
                            nodeParentNames.Add(parentName);

                            Vector3 rotation = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());

                            Vector3 position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());

                            nodes[i] = new AnimationNode(name, position, rotation);
                            namesToNodes.Add(name, nodes[i]);

                            ushort keyRotCount = br.ReadUInt16(); //Key frame rot count
                            ushort keyPosCount = br.ReadUInt16(); //Key frame pos count
                            //nodes[i].rotationFrames = new ModelBoneAnimationFrame[keyRotCount];
                            //nodes[i].translationFrames = new ModelBoneAnimationFrame[keyPosCount];
                            /*
                            for (int j = 0; j < keyRotCount; j++)
                            {
                                nodes[i].rotationFrames[j].time = br.ReadSingle() * fps; //time
                                nodes[i].rotationFrames[j].Displacement = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                                nodes[i].rotationFrames[j].boneName = name;
                            }

                            for (int j = 0; j < keyPosCount; j++)
                            {
                                nodes[i].translationFrames[j].time = br.ReadSingle() * fps; //time
                                nodes[i].translationFrames[j].Displacement = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                                nodes[i].translationFrames[j].boneName = name;
                            }*/
                            int count = (keyRotCount + keyPosCount) * 4;
                            for (int j = 0; j < count; j++)
                                br.ReadSingle();
                        }

                        List<AnimationNode> rootNodeList = new List<AnimationNode>();
                        for (int i = 0; i < nodes.Length; i++)
                        {
                            if (namesToNodes.ContainsKey(nodeParentNames[i]))
                            {
                                AnimationNode node = namesToNodes[nodeParentNames[i]];
                                node.children.Add(nodes[i]);
                            }
                            else
                                rootNodeList.Add(nodes[i]);
                        }
                        rootNodes = rootNodeList.ToArray();
                        for (int i = 0; i < rootNodes.Length; i++)
                        {
                            Matrix identityMat = Matrix.Identity;
                            rootNodes[i].ApplyTransform(ref identityMat);
                        }

                        Matrix[] inverseMats = new Matrix[nodes.Length];
                        Matrix[] invRotMats = new Matrix[nodes.Length];
                        for (int i = 0; i < inverseMats.Length; i++)
                        {
                            inverseMats[i] = Matrix.Invert(nodes[i].Transform);
                            invRotMats[i] = MathUtils.Invert3x3(nodes[i].Transform);
                        }

                        if (nodesAreAnimated)
                        {
                            for (int i = 0; i < verts.Length; i++)
                            {
                                verts[i].Position = Vector3.Transform(verts[i].Position, inverseMats[(int)verts[i].Index]);
                                verts[i].Normal = Vector3.TransformNormal(verts[i].Normal, inverseMats[(int)verts[i].Index]);
                                verts[i].Tangent = Vector3.TransformNormal(verts[i].Tangent, inverseMats[(int)verts[i].Index]);
                            }
                        }
                        vertexBuffer.SetData<VertexPNTTI>(verts);

                        for (int i = 0; i < nodes.Length; i++)
                        {
                            Vector3 Rotation = nodes[i].Rotation;
                            Matrix transform = Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z);
                            transform.Translation = nodes[i].Translation;
                            nodes[i].Transform = transform;
                        }

                    }
                }
            }
        }
Пример #4
0
        public AnimationNode[] GetRootNodes(out SortedList<string, AnimationNode> nodeCollection)
        {
            nodeCollection = new SortedList<string, AnimationNode>();

            if (rootNodes == null)
                return null;

            AnimationNode[] dupNodes = new AnimationNode[rootNodes.Length];
            for (int i = 0; i < rootNodes.Length; i++)
                dupNodes[i] = rootNodes[i].RecursiveCopy(nodeCollection);

            return dupNodes;
        }