Ejemplo n.º 1
0
        /// <summary>
        /// laske luurangolle asento.
        /// </summary>
        void InterpolateSkeletons(ref MD5Joint[,] skel, int curFrame, int nextFrame, int num_joints, float interp)
        {
            for (int i = 0; i < num_joints; ++i)
            {
                /* Copy parent index */
                skeleton[i].parent = skel[curFrame, i].parent;

                /* Linear interpolation for Position */
                skeleton[i].pos.X = skel[curFrame, i].pos.X + interp * (skel[nextFrame, i].pos.X - skel[curFrame, i].pos.X);
                skeleton[i].pos.Y = skel[curFrame, i].pos.Y + interp * (skel[nextFrame, i].pos.Y - skel[curFrame, i].pos.Y);
                skeleton[i].pos.Z = skel[curFrame, i].pos.Z + interp * (skel[nextFrame, i].pos.Z - skel[curFrame, i].pos.Z);

                /* Spherical linear interpolation for orientation */
                skeleton[i].orient = QuaternionExt.Slerp(skel[curFrame, i].orient, skel[nextFrame, i].orient, interp);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Prepare mesh for rendering
        /// </summary>
        void PrepareMesh()
        {
            int i, j, k;

            meshes.Clear();

            // Calculate the final Position ingame Position of all the model vertexes
            for (k = 0; k < numMesh; k++)
            {
                numOfFaces   = model[k].numTris;
                VertexBuffer = new Vertex[numOfFaces * 3];

                for (i = 0; i < model[k].numVert; i++)
                {
                    Vector3 finalVertex = new Vector3(0, 0, 0);
                    for (j = 0; j < model[k].verts[i].countw; j++)
                    {
                        MD5Weight wt    = model[k].weights[model[k].verts[i].startw + j];
                        MD5Joint  joint = skeleton[wt.joint];

                        Vector3 wv = QuaternionExt.RotatePoint(joint.orient, wt.pos);
                        finalVertex.X += (joint.pos.X + wv.X) * wt.bias;
                        finalVertex.Y += (joint.pos.Y + wv.Y) * wt.bias;
                        finalVertex.Z += (joint.pos.Z + wv.Z) * wt.bias;
                    }
                    finalVert[i] = finalVertex;
                }

                int count = 0;
                // Organize the final vertexes acording to the meshes triangles
                for (i = 0; i < model[k].numTris; i++)
                {
                    VertexBuffer[count]     = new Vertex(finalVert[(int)model[k].faces[i][0]], normals[(int)model[k].faces[i][0]], model[k].verts[(int)model[k].faces[i][0]].uv);
                    VertexBuffer[count + 1] = new Vertex(finalVert[(int)model[k].faces[i][1]], normals[(int)model[k].faces[i][1]], model[k].verts[(int)model[k].faces[i][1]].uv);
                    VertexBuffer[count + 2] = new Vertex(finalVert[(int)model[k].faces[i][2]], normals[(int)model[k].faces[i][2]], model[k].verts[(int)model[k].faces[i][2]].uv);

                    count += 3;
                }
                meshes.Add(VertexBuffer);

                if (model[k].vbo != null)
                {
                    model[k].vbo.Update(VertexBuffer);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// lataa md5-animaatio.
        /// </summary>
        public override void LoadMD5Animation(string animName, string fileName)
        {
            if (fileName == null || fileName == "")
            {
                return;
            }

            Animation anim = new Animation();

            anim.animName = animName;

            Buffer t = new Buffer();

            MD5JointInfo[]      jointInfos    = null;
            MD5BaseFrameJoint[] baseFrame     = null;
            float[]             animFrameData = null;
            int numAnimatedComponents         = 0;
            int frame_index;
            int i;

            using (System.IO.StreamReader file = new System.IO.StreamReader(Settings.ModelDir + fileName))
            {
                string line;
                while ((line = file.ReadLine()) != null)
                {
                    if (line == "")
                    {
                        continue;
                    }

                    // Read number of joints
                    if (ParseLine(ref t, line, "numFrames %d"))
                    {
                        /* Allocate memory for skeleton frames and bounding boxes */
                        anim.numFrames = t.ibuffer[0];
                        if (anim.numFrames > 0)
                        {
                            anim.bboxes = new MD5BoundingBox[anim.numFrames];
                        }
                    }

                    if (ParseLine(ref t, line, "numJoints %d"))
                    {
                        /* Allocate memory for joints of each frame */
                        anim.numJoints = t.ibuffer[0];
                        if (anim.numJoints > 0)
                        {
                            /* Allocate temporary memory for building skeleton frames */
                            jointInfos = new MD5JointInfo[anim.numJoints];
                            baseFrame  = new MD5BaseFrameJoint[anim.numJoints];
                        }
                        anim.skelFrames = new MD5Joint[anim.numFrames, anim.numJoints];
                    }

                    if (ParseLine(ref t, line, "frameRate %d"))
                    {
                        anim.frameRate = t.ibuffer[0];
                    }

                    if (ParseLine(ref t, line, "numAnimatedComponents %d"))
                    {
                        numAnimatedComponents = t.ibuffer[0];
                        if (numAnimatedComponents > 0)
                        {
                            /* Allocate memory for animation frame data */
                            animFrameData = new float[numAnimatedComponents];
                        }
                    }

                    if (line.Equals("hierarchy {"))
                    {
                        for (i = 0; i < anim.numJoints; ++i)
                        {
                            /* Read whole line */
                            line = file.ReadLine();
                            Cleanstring(ref line);

                            /* Read joint info */
                            ParseLine(ref t, line, "%s %d %d %d");
                            jointInfos[i].name       = t.sbuffer;
                            jointInfos[i].parent     = t.ibuffer[0];
                            jointInfos[i].flags      = t.ibuffer[1];
                            jointInfos[i].startIndex = t.ibuffer[2];
                        }
                    }

                    if (line.Equals("bounds {"))
                    {
                        for (i = 0; i < anim.numFrames; ++i)
                        {
                            /* Read whole line */
                            line = file.ReadLine();
                            Cleanstring(ref line);

                            /* Read bounding box */
                            ParseLine(ref t, line, "( %f %f %f ) ( %f %f %f )");
                            anim.bboxes[i].min.X = t.fbuffer[0];
                            anim.bboxes[i].min.Y = t.fbuffer[1];
                            anim.bboxes[i].min.Z = t.fbuffer[2];
                            anim.bboxes[i].max.X = t.fbuffer[3];
                            anim.bboxes[i].max.Y = t.fbuffer[4];
                            anim.bboxes[i].max.Z = t.fbuffer[5];
                        }
                    }

                    if (line.Equals("baseframe {"))
                    {
                        for (i = 0; i < anim.numJoints; ++i)
                        {
                            /* Read whole line */
                            line = file.ReadLine();
                            Cleanstring(ref line);

                            /* Read base frame joint */
                            ParseLine(ref t, line, "( %f %f %f ) ( %f %f %f )");

                            if (t.fbuffer.Length == 6)
                            {
                                baseFrame[i].pos.X    = t.fbuffer[0];
                                baseFrame[i].pos.Y    = t.fbuffer[1];
                                baseFrame[i].pos.Z    = t.fbuffer[2];
                                baseFrame[i].orient.X = t.fbuffer[3];
                                baseFrame[i].orient.Y = t.fbuffer[4];
                                baseFrame[i].orient.Z = t.fbuffer[5];

                                /* Compute the w component */
                                QuaternionExt.ComputeW(ref baseFrame[i].orient);
                            }
                        }
                    }

                    if (ParseLine(ref t, line, "frame %d"))
                    {
                        frame_index = t.ibuffer[0];

                        /* Read frame data */
                        for (i = 0; i < numAnimatedComponents;)
                        {
                            line = file.ReadLine();
                            if (line[0] == '}')
                            {
                                break;
                            }
                            Cleanstring(ref line);
                            string[] splt = line.Split(' ');
                            for (int ww = 0; ww < splt.Length; ww++)
                            {
                                animFrameData[i++] = MathExt.GetFloat(splt[ww]);
                            }
                        }
                        /* Build frame skeleton from the collected data */
                        BuildFrameSkeleton(ref jointInfos, ref baseFrame, ref animFrameData, frame_index, anim.numJoints, ref anim);
                    }
                }

                anim.curFrame  = 0;
                anim.nextFrame = 1;

                anim.lastTime = 0;
                anim.maxTime  = 1.0f / anim.frameRate;

                /* Allocate memory for animated skeleton */
                skeleton = new MD5Joint[anim.numJoints];
                animated = true;

                Vector3 min = new Vector3(9999, 9999, 9999);
                Vector3 max = new Vector3(-9999, -9999, -9999);

                // laske bboxit
                for (int q = 0; q < anim.numFrames; q++)
                {
                    if (anim.bboxes[q].min.X < min.X)
                    {
                        min.X = anim.bboxes[q].min.X;
                    }
                    if (anim.bboxes[q].min.Y < min.Y)
                    {
                        min.Y = anim.bboxes[q].min.Y;
                    }
                    if (anim.bboxes[q].min.Z < min.Z)
                    {
                        min.Z = anim.bboxes[q].min.Z;
                    }

                    if (anim.bboxes[q].max.X > max.X)
                    {
                        max.X = anim.bboxes[q].max.X;
                    }
                    if (anim.bboxes[q].max.Y > max.Y)
                    {
                        max.Y = anim.bboxes[q].max.Y;
                    }
                    if (anim.bboxes[q].max.Z > max.Z)
                    {
                        max.Z = anim.bboxes[q].max.Z;
                    }
                }

                Boundings = new BoundingSphere();
                Boundings.CreateBoundingVolume(this, min, max);

                Update(0);
                animations.Add(anim);

                Log.WriteLine("Animation: " + fileName, false);

                SetAnimation(animName);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// luo luuranko.
        /// </summary>
        void BuildFrameSkeleton(ref MD5JointInfo[] jointInfos,
                                ref MD5BaseFrameJoint[] baseFrame,
                                ref float[] animFrameData,
                                int frameIndex,
                                int num_joints, ref Animation md5anim)
        {
            for (int i = 0; i < num_joints; ++i)
            {
                MD5BaseFrameJoint baseJoint = baseFrame[i];
                Vector3           animatedPos;
                Quaternion        animatedOrient;
                int j = 0;

                animatedPos    = baseJoint.pos;
                animatedOrient = baseJoint.orient;

                if ((jointInfos[i].flags & 1) > 0) /* Tx */
                {
                    animatedPos.X = animFrameData[jointInfos[i].startIndex + j];
                    ++j;
                }

                if ((jointInfos[i].flags & 2) > 0) /* Ty */
                {
                    animatedPos.Y = animFrameData[jointInfos[i].startIndex + j];
                    ++j;
                }

                if ((jointInfos[i].flags & 4) > 0) /* Tz */
                {
                    animatedPos.Z = animFrameData[jointInfos[i].startIndex + j];
                    ++j;
                }

                if ((jointInfos[i].flags & 8) > 0) /* Qx */
                {
                    animatedOrient.X = animFrameData[jointInfos[i].startIndex + j];
                    ++j;
                }

                if ((jointInfos[i].flags & 16) > 0) /* Qy */
                {
                    animatedOrient.Y = animFrameData[jointInfos[i].startIndex + j];
                    ++j;
                }

                if ((jointInfos[i].flags & 32) > 0) /* Qz */
                {
                    animatedOrient.Z = animFrameData[jointInfos[i].startIndex + j];
                    ++j;
                }

                /* Compute orient quaternion's w value */
                QuaternionExt.ComputeW(ref animatedOrient);

                int parent = jointInfos[i].parent;
                md5anim.skelFrames[frameIndex, i].parent = parent;
                md5anim.skelFrames[frameIndex, i].name   = jointInfos[i].name;

                /* Has parent? */
                if (md5anim.skelFrames[frameIndex, i].parent < 0)
                {
                    md5anim.skelFrames[frameIndex, i].pos    = animatedPos;
                    md5anim.skelFrames[frameIndex, i].orient = animatedOrient;
                }
                else
                {
                    MD5Joint parentJoint = md5anim.skelFrames[frameIndex, parent];
                    Vector3  rpos; /* Rotated Position */

                    /* Add positions */
                    rpos = QuaternionExt.RotatePoint(parentJoint.orient, animatedPos);

                    md5anim.skelFrames[frameIndex, i].pos.X = rpos.X + parentJoint.pos.X;
                    md5anim.skelFrames[frameIndex, i].pos.Y = rpos.Y + parentJoint.pos.Y;
                    md5anim.skelFrames[frameIndex, i].pos.Z = rpos.Z + parentJoint.pos.Z;

                    /* Concatenate rotations */
                    md5anim.skelFrames[frameIndex, i].orient = Quaternion.Multiply(parentJoint.orient, animatedOrient);
                    md5anim.skelFrames[frameIndex, i].orient = Quaternion.Normalize(md5anim.skelFrames[frameIndex, i].orient);
                }
            }
        }
Ejemplo n.º 5
0
        void LoadMD5(string fileName)
        {
            Name = fileName;

            // Initialize everything
            string line, textureName = "";
            int    i;
            Buffer t = new Buffer();

            meshCount = 0;
            using (System.IO.StreamReader file = new System.IO.StreamReader(Settings.ModelDir + fileName))
            {
                {
                    while ((line = file.ReadLine()) != null)
                    {
                        Cleanstring(ref line);

                        // Read number of joints
                        if (ParseLine(ref t, line, "numJoints %d"))
                        {
                            numJoints = t.ibuffer[0];
                            baseSkel  = new MD5Joint[numJoints];
                        }
                        // Read number os meshes
                        if (ParseLine(ref t, line, "numMeshes %d"))
                        {
                            numMesh = t.ibuffer[0];
                            model   = new MD5Mesh[numMesh];

                            meshes = new List <Vertex[]>(numMesh);
                        }
                        // Parse model joints
                        if (line.Equals("joints {"))
                        {
                            for (i = 0; i < numJoints; i++)
                            {
                                line = file.ReadLine();
                                Cleanstring(ref line);

                                ParseLine(ref t, line, "%s %d ( %f %f %f ) ( %f %f %f )");
                                baseSkel[i].name   = t.sbuffer;
                                baseSkel[i].parent = t.ibuffer[0];
                                baseSkel[i].pos.X  = t.fbuffer[0];
                                baseSkel[i].pos.Y  = t.fbuffer[1];
                                baseSkel[i].pos.Z  = t.fbuffer[2];
                                baseSkel[i].orient = new Quaternion(t.fbuffer[3], t.fbuffer[4], t.fbuffer[5], 1);

                                QuaternionExt.ComputeW(ref baseSkel[i].orient);
                            }
                        }
                        // Parse model meshes
                        if (line.Equals("mesh {"))
                        {
                            while (!line.Equals("}"))
                            {
                                line = file.ReadLine();
                                Cleanstring(ref line);

                                // Read texture name
                                if (line.StartsWith("shader"))
                                {
                                    string str = line.Substring(7);
                                    textureName = Settings.TextureDir + str;
                                    textureName = textureName.Replace(",", ".");
                                }

                                // Read mesh data
                                if (ParseLine(ref t, line, "numverts %d"))
                                {
                                    model[meshCount].numVert = t.ibuffer[0];
                                    model[meshCount].verts   = new MD5Vertex[model[meshCount].numVert];

                                    model[meshCount].texture = Texture.Load(textureName);

                                    for (i = 0; i < model[meshCount].numVert; i++)
                                    {
                                        line = file.ReadLine();
                                        ParseLine(ref t, line, "vert %d ( %f %f ) %d %d");
                                        model[meshCount].verts[t.ibuffer[0]].uv.X   = t.fbuffer[0];
                                        model[meshCount].verts[t.ibuffer[0]].uv.Y   = 1 - t.fbuffer[1];
                                        model[meshCount].verts[t.ibuffer[0]].startw = t.ibuffer[1];
                                        model[meshCount].verts[t.ibuffer[0]].countw = t.ibuffer[2];
                                    }
                                }
                                if (ParseLine(ref t, line, "numtris %d"))
                                {
                                    model[meshCount].numTris = t.ibuffer[0];
                                    model[meshCount].faces   = new int[model[meshCount].numTris][];
                                    for (i = 0; i < model[meshCount].numTris; i++)
                                    {
                                        line = file.ReadLine();
                                        ParseLine(ref t, line, "tri %d %d %d %d");

                                        model[meshCount].faces[t.ibuffer[0]]    = new int[3];
                                        model[meshCount].faces[t.ibuffer[0]][0] = t.ibuffer[3]; // poly toisin päin
                                        model[meshCount].faces[t.ibuffer[0]][1] = t.ibuffer[2];
                                        model[meshCount].faces[t.ibuffer[0]][2] = t.ibuffer[1];
                                    }
                                }
                                if (ParseLine(ref t, line, "numweights %d"))
                                {
                                    model[meshCount].numWeights = t.ibuffer[0];
                                    model[meshCount].weights    = new MD5Weight[model[meshCount].numWeights];
                                    for (i = 0; i < model[meshCount].numWeights; i++)
                                    {
                                        line = file.ReadLine();
                                        ParseLine(ref t, line, "weight %d %d %f ( %f %f %f )");
                                        model[meshCount].weights[t.ibuffer[0]].joint = t.ibuffer[1];
                                        model[meshCount].weights[t.ibuffer[0]].bias  = t.fbuffer[0];
                                        model[meshCount].weights[t.ibuffer[0]].pos.X = t.fbuffer[1];
                                        model[meshCount].weights[t.ibuffer[0]].pos.Y = t.fbuffer[2];
                                        model[meshCount].weights[t.ibuffer[0]].pos.Z = t.fbuffer[3];
                                    }
                                }
                            }
                            meshCount++;
                        }
                    }
                }
            }

            int maxvert = 0;

            for (int k = 0; k < numMesh; k++)
            {
                if (model[k].numVert > maxvert)
                {
                    maxvert = model[k].numVert;
                }
            }
            for (int k = 0; k < numMesh; k++)
            {
                finalVert = new Vector3[maxvert];
                normals   = new Vector3[maxvert];
            }

            skeleton = baseSkel;

            // prepare model for rendering
            PrepareMesh();

            for (int q = 0; q < numMesh; q++)
            {
                Vertex[] v   = meshes[q];
                ushort[] ind = new ushort[v.Length];
                for (ushort w = 0; w < ind.Length; w++)
                {
                    ind[w] = w;
                }

                // luo vbo ja datat sinne
                model[q].vbo = new VBO(BufferUsageHint.DynamicDraw);
                model[q].vbo.DataToVBO(v, ind, VBO.VertexMode.UV1);
            }

            // laske normaalit
            for (int k = 0; k < numMesh; k++)
            {
                MathExt.CalcNormals(ref finalVert, ref model[k].faces, ref normals, false);
            }

            Log.WriteLine("Model: " + Name, false);
        }
Ejemplo n.º 6
0
        /*
         * protected void processLightAttenuation(XmlElement XMLNode, Light pLight)
         * {
         *  // Process attributes
         *  float range = XML.GetAttribReal(XMLNode, "range");
         *  float constant = XML.GetAttribReal(XMLNode, "constant");
         *  float linear = XML.GetAttribReal(XMLNode, "linear");
         *  float quadratic = XML.GetAttribReal(XMLNode, "quadratic");
         *  // Setup the light attenuation
         *  pLight.SetAttenuation(range, constant, linear, quadratic);
         * }
         *
         * protected void processLightRange(XmlElement XMLNode, Light pLight)
         * {
         *  // Process attributes
         *  float inner = XML.GetAttribReal(XMLNode, "inner");
         *  float outer = XML.GetAttribReal(XMLNode, "outer");
         *  float falloff = XML.GetAttribReal(XMLNode, "falloff", 1.0f);
         *  // Setup the light range
         *  pLight.SetSpotlightRange(new Radian((Degree)inner), new Radian((Degree)outer), falloff);
         * }
         */

        protected void processNode(XmlElement XMLNode, Node pParent)
        {
            // Construct the node's name
            String name = XML.GetAttrib(XMLNode, "name");

            // Create the scene node
            Node       pNode = new Node();
            Vector3    pos = Vector3.Zero, scale = Vector3.Zero;
            Quaternion orientation = new Quaternion();

            // Process other attributes
            XmlElement pElement;

            // Process position
            pElement = (XmlElement)XMLNode.SelectSingleNode("position");
            if (pElement != null)
            {
                pos = XML.ParseVector3(pElement);
            }

            // Process rotation
            pElement = (XmlElement)XMLNode.SelectSingleNode("rotation");
            if (pElement != null)
            {
                orientation = XML.ParseOrientation(pElement);
            }

            // Process scale
            pElement = (XmlElement)XMLNode.SelectSingleNode("scale");
            if (pElement != null)
            {
                scale = XML.ParseVector3(pElement);
            }

            // Process ogremesh
            pElement = (XmlElement)XMLNode.SelectSingleNode("entity");
            if (pElement != null)
            {
                pNode = processEntity(pElement);
                if (pNode == null)
                {
                    return;
                }

                // jos .scene tiedostossa näkyy että pathin position, rotation tai scale on muuttunut,
                // silloin path ei toimi oikein koska niitä ei tässä oteta huomioon ollenkaan
                // (joten path voi ollaki ihan eri kohdassa missä pitäis).

                // ratkaisu on että pathia EI liikuteta, pyöritetä eikä skaalata 3dsmaxissa!
                // pivot point pitää olla origossa ja muokkaukset tehdään vain vertex edit moodissa.
            }

            // Process light
            pElement = (XmlElement)XMLNode.SelectSingleNode("light");
            if (pElement != null)
            {
                pNode          = processLight(pElement);
                pNode.Rotation = QuaternionExt.QuatToEuler(orientation);

                pElement = (XmlElement)XMLNode.NextSibling;
                if (pElement != null)
                {
                    string nname = XML.GetAttrib(pElement, "name");
                    if (nname.Contains(".Target"))
                    {
                        Vector3 targetPos;
                        pElement = (XmlElement)pElement.SelectSingleNode("position");
                        if (pElement != null)
                        {
                            targetPos = XML.ParseVector3(pElement);
                        }
                        else
                        {
                            targetPos = Vector3.Zero;
                        }

                        pNode.OrigOrientationMatrix = Matrix4.LookAt(pos, targetPos, Vector3.UnitY);
                    }
                    pNode.Name     = name;
                    pNode.Position = pos;
                    pNode.Scale    = scale;
                    pParent.Add(pNode);
                    return;
                }
            }

            // Process camera
            pElement = (XmlElement)XMLNode.SelectSingleNode("camera");
            if (pElement != null)
            {
                pNode          = processCamera(pElement);
                pNode.Rotation = QuaternionExt.QuatToEuler(orientation);
            }

            // Process childnodes
            pElement = (XmlElement)XMLNode.SelectSingleNode("node");
            while (pElement != null)
            {
                processNode(pElement, pNode);
                pElement = (XmlElement)pElement.NextSibling;
            }

            pNode.Name     = name;
            pNode.Position = pos;
            pNode.Scale    = scale;
            Matrix4Ext.CreateFromQuaternion(ref orientation, out pNode.OrigOrientationMatrix);

            pParent.Add(pNode);
        }