/// <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; vertices = 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 = MathExt.RotatePoint(ref joint.orient, ref 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; } // aika laskea normaalit uudelleen? if (updateNormalsCount == FramesBetweenNormalsUpdate) { MathExt.CalcNormals(ref finalVert, ref model[k].faces, ref normals, false); updateNormalsCount = 0; } else { updateAnimCount++; } int count = 0; // Organize the final vertexes acording to the meshes triangles for (i = 0; i < model[k].numTris; i++) { vertices[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); vertices[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); vertices[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(vertices); if (model[k].vbo != null) { model[k].vbo.Update(vertices); } } }
/// <summary> /// laske luurangolle asento. /// </summary> /// <param name="skel"></param> /// <param name="curFrame"></param> /// <param name="nextFrame"></param> /// <param name="num_joints"></param> /// <param name="interp"></param> void InterpolateSkeletons(ref MD5Joint[,] skel, int curFrame, int nextFrame, int num_joints, float interp) { int i; for (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 = MathExt.Slerp(ref skel[curFrame, i].orient, ref skel[nextFrame, i].orient, interp); } }
/// <summary> /// luo luuranko. /// </summary> /// <param name="jointInfos"></param> /// <param name="baseFrame"></param> /// <param name="animFrameData"></param> /// <param name="frameIndex"></param> /// <param name="num_joints"></param> /// <param name="md5anim"></param> void BuildFrameSkeleton(ref MD5JointInfo[] jointInfos, ref MD5BaseFrameJoint[] baseFrame, ref float[] animFrameData, int frameIndex, int num_joints, ref Animation md5anim) { int i; for (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 */ MathExt.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 = MathExt.RotatePoint(ref parentJoint.orient, ref 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 = MathExt.Mult(ref parentJoint.orient, ref animatedOrient); md5anim.skelFrames[frameIndex, i].orient = MathExt.Normalize(ref md5anim.skelFrames[frameIndex, i].orient); } } }