/// <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); } } }
/// <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); } } }
/// <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); } }