- 浏览: 167418 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
兰斯洛特1987:
顶!!!!谢谢分享.最近我也在研究这玩意...
Java语言的Hook实现 -
pu02203:
我把Confidant.jar, 丢进去eclipse, 里面 ...
重磅推出诛仙辅助软件第二波:Java版按键精灵 -
泣血端午:
Calculagraph 这是哪个类啊?
A星算法 -
haitaohehe:
我使用的是jstl1.0 可是在使用<c:set va ...
JSTL1.0和JSTL1.1的区别 -
micheal19840929:
学习楼主,我也测试一下~看看兼容性吧。lanlanzhilia ...
手机版飞鸽传书:无线牵
import java.io.InputStream; import java.nio.FloatBuffer; import java.util.Hashtable; import java.util.Vector; import org.lwjgl.BufferUtils; import org.lwjgl.Sys; import org.lwjgl.opengl.GL11; import org.tinder.studio.lwjgl.util.BinaryFileReader; import org.tinder.studio.lwjgl.util.Bounding; import org.tinder.studio.lwjgl.util.GLApp; import org.tinder.studio.lwjgl.util.Matrix4f; import org.tinder.studio.lwjgl.util.Vector3f; import org.tinder.studio.lwjgl.util.Vector4f; /** * * * @Author Micheal Hong * @Email babala_234@163.com * @Version 2010-6-29下午10:33:28 * */ public class MS3DModel { MS3DHeader header; int numVertices; public MS3DVertex[] vertices; float vertex[]; int numTriangles; MS3DTriangle[] triangles; int numMeshs; MS3DMesh[] meshs; int numMaterials; MS3DMaterial[] materials; int numJoints; MS3DJoint[] joints; long lastTime; int currentAnimation; float currentTime; int totalFrames; int endFrame; float animationFPS; boolean loop; boolean loopDone; Vector<MS3DAnimation> allAnimations; Hashtable<String, MS3DJoint> allJoints; Vector<MS3DJoint> rootJoints; String textureDirectory; Bounding bounding; /*************************************************************************************************************************************************************************************************** * MS3DModel () - Constructor **************************************************************************************************************************************************************************************************/ public MS3DModel(InputStream file,String textureDirectory) { this.allJoints = new Hashtable<String, MS3DJoint>(); this.rootJoints = new Vector<MS3DJoint>(); this.allAnimations = new Vector<MS3DAnimation>(); this.currentAnimation = -1; this.loop = true; this.loopDone = false; this.textureDirectory=textureDirectory; this.loadModel(file); this.makeBounding(); } /*************************************************************************************************************************************************************************************************** * loadModel() - Load a ms3d model and prepare it for rendering **************************************************************************************************************************************************************************************************/ protected void loadModel(InputStream file) { try { // Read the model file BinaryFileReader modelFile = new BinaryFileReader(file); // Read header this.header = new MS3DHeader(modelFile); if (!this.header.isValid()) throw new Exception("Model header is invalid! Only versions 1.3 and 1.4 are supported!"); // Read vertices this.numVertices = modelFile.readShort(); this.vertices = new MS3DVertex[this.numVertices]; this.vertex = new float[3 * numVertices]; for (int i = 0; i < this.numVertices; i++) { this.vertices[i] = new MS3DVertex(modelFile); this.vertex[3 * i] = this.vertices[i].vertex.x; this.vertex[3 * i + 1] = this.vertices[i].vertex.y; this.vertex[3 * i + 2] = this.vertices[i].vertex.z; } // Triangles this.numTriangles = modelFile.readShort(); this.triangles = new MS3DTriangle[this.numTriangles]; for (int i = 0; i < this.numTriangles; i++) this.triangles[i] = new MS3DTriangle(modelFile); // Meshs this.numMeshs = modelFile.readShort(); this.meshs = new MS3DMesh[this.numMeshs]; for (int i = 0; i < this.numMeshs; i++) this.meshs[i] = new MS3DMesh(modelFile); // Materials this.numMaterials = modelFile.readShort(); this.materials = new MS3DMaterial[this.numMaterials]; for (int i = 0; i < this.numMaterials; i++) this.materials[i] = new MS3DMaterial(modelFile); // Keyframe data animationFPS = modelFile.readFloat(); currentTime = (long) (modelFile.readFloat() * 1000); totalFrames = modelFile.readInt(); // Joints numJoints = modelFile.readShort(); this.joints = new MS3DJoint[numJoints]; for (int i = 0; i < this.numJoints; i++) { this.joints[i] = new MS3DJoint(modelFile); addJoint(this.joints[i]); } // Load textures this.reloadTextures(); this.makeBones(); this.reset(); } catch (Exception e) { Sys.alert("Error", "Failed to load model '" + file.toString()+ "'!\n\n" + e.getMessage()); e.printStackTrace(); System.exit(0); } } public void addJoint(MS3DJoint joint) { allJoints.put(joint.name, joint); if (joint.parentName.equals("")) rootJoints.addElement(joint); } public Hashtable<String, MS3DJoint> getJoints() { return allJoints; } /*************************************************************************************************************************************************************************************************** * reloadTextures() - Load the texture of each material **************************************************************************************************************************************************************************************************/ public void reloadTextures() { for (int i = 0; i < this.numMaterials; i++) { if (this.materials[i].textureID != 0) GL11.glDeleteTextures(BufferUtils.createIntBuffer(1).put(this.materials[i].textureID)); else { try { this.materials[i].textureID = GLApp.makeTexture(this.textureDirectory+"/"+this.materials[i].texturemap); } catch (Exception e) { System.out.println("Failed to open texture file 'this.materials[i].texturemap'!"); } } } } public void updateModel(long time) { // update the animation updateAnimation(time); boolean texturingEnabled = GL11.glIsEnabled(GL11.GL_TEXTURE_2D); // update the points for (int i = 0; i < numMeshs; i++) { if (this.meshs[i].materialIndex >= 0) { GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT,this.materials[this.meshs[i].materialIndex].ambient); GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE,this.materials[this.meshs[i].materialIndex].diffuse); GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SPECULAR,this.materials[this.meshs[i].materialIndex].specular); GL11.glMaterial(GL11.GL_FRONT, GL11.GL_EMISSION,this.materials[this.meshs[i].materialIndex].emissive); GL11.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS,this.materials[this.meshs[i].materialIndex].shininess); if (this.materials[this.meshs[i].materialIndex].textureID > 0) { GL11.glBindTexture(GL11.GL_TEXTURE_2D,this.materials[this.meshs[i].materialIndex].textureID); GL11.glEnable(GL11.GL_TEXTURE_2D); } else { GL11.glDisable(GL11.GL_TEXTURE_2D); } } else { GL11.glDisable(GL11.GL_TEXTURE_2D); } float[] coords = new float[3]; Vector4f temp = new Vector4f(); Matrix4f matrix=null; GL11.glBegin(GL11.GL_TRIANGLES); for (int j = 0; j < meshs[i].numTriangles; j++) { for (int k = 0; k < 3; k++) { coords[0] = vertex[3 * triangles[meshs[i].triangleIndices[j]].vertexIndices[k]]; coords[1] = vertex[3 * triangles[meshs[i].triangleIndices[j]].vertexIndices[k] + 1]; coords[2] = vertex[3 * triangles[meshs[i].triangleIndices[j]].vertexIndices[k] + 2]; if (vertices[triangles[meshs[i].triangleIndices[j]].vertexIndices[k]].boneID != -1) { matrix = joints[vertices[triangles[meshs[i].triangleIndices[j]].vertexIndices[k]].boneID].finalMatrix; temp.x = coords[0] * matrix.m00 + coords[1] * matrix.m10 + coords[2] * matrix.m20 + matrix.m30; temp.y = coords[0] * matrix.m01 + coords[1] * matrix.m11 + coords[2] * matrix.m21 + matrix.m31; temp.z = coords[0] * matrix.m02 + coords[1] * matrix.m12 + coords[2] * matrix.m22 + matrix.m32; temp.w = coords[0] * matrix.m03 + coords[1] * matrix.m13 + coords[2] * matrix.m23 + matrix.m33; GL11.glNormal3f( triangles[meshs[i].triangleIndices[j]].vertexNormals[0][0], triangles[meshs[i].triangleIndices[j]].vertexNormals[0][1], triangles[meshs[i].triangleIndices[j]].vertexNormals[0][2]); GL11.glTexCoord2f( triangles[meshs[i].triangleIndices[j]].s[k], triangles[meshs[i].triangleIndices[j]].t[k]); GL11.glVertex3f(temp.x, temp.y, temp.z); } } } GL11.glEnd(); } // Reset texture state if (texturingEnabled) GL11.glEnable(GL11.GL_TEXTURE_2D); else GL11.glDisable(GL11.GL_TEXTURE_2D); } /*************************************************************************************************************************************************************************************************** * render() - Render this model **************************************************************************************************************************************************************************************************/ public void render() { // Save texture state boolean texturingEnabled = GL11.glIsEnabled(GL11.GL_TEXTURE_2D); // Render each mesh for (int m = 0; m < this.numMeshs; m++) { // Set texture for this mesh if (this.meshs[m].materialIndex >= 0) { GL11.glMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT,this.materials[this.meshs[m].materialIndex].ambient); GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE,this.materials[this.meshs[m].materialIndex].diffuse); GL11.glMaterial(GL11.GL_FRONT, GL11.GL_SPECULAR,this.materials[this.meshs[m].materialIndex].specular); GL11.glMaterial(GL11.GL_FRONT, GL11.GL_EMISSION,this.materials[this.meshs[m].materialIndex].emissive); GL11.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS,this.materials[this.meshs[m].materialIndex].shininess); if (this.materials[this.meshs[m].materialIndex].textureID > 0) { GL11.glBindTexture(GL11.GL_TEXTURE_2D,this.materials[this.meshs[m].materialIndex].textureID); GL11.glEnable(GL11.GL_TEXTURE_2D); } else { GL11.glDisable(GL11.GL_TEXTURE_2D); } } else { GL11.glDisable(GL11.GL_TEXTURE_2D); } // Render each mesh GL11.glBegin(GL11.GL_TRIANGLES); { for (int t = 0; t < this.meshs[m].numTriangles; t++) { for (int v = 0; v < 3; v++) { GL11.glNormal3f( this.triangles[this.meshs[m].triangleIndices[t]].vertexNormals[v][0], this.triangles[this.meshs[m].triangleIndices[t]].vertexNormals[v][1], this.triangles[this.meshs[m].triangleIndices[t]].vertexNormals[v][2]); GL11.glTexCoord2f( this.triangles[this.meshs[m].triangleIndices[t]].s[v], this.triangles[this.meshs[m].triangleIndices[t]].t[v]); GL11.glVertex3f( this.vertices[this.triangles[this.meshs[m].triangleIndices[t]].vertexIndices[v]].vertex.x, this.vertices[this.triangles[this.meshs[m].triangleIndices[t]].vertexIndices[v]].vertex.y, this.vertices[this.triangles[this.meshs[m].triangleIndices[t]].vertexIndices[v]].vertex.z); } } } GL11.glEnd(); } // Reset texture state if (texturingEnabled) GL11.glEnable(GL11.GL_TEXTURE_2D); else GL11.glDisable(GL11.GL_TEXTURE_2D); } public void reset() { for (int i = 0; i < numJoints; i++) { joints[i].currentRotationKeyframe = 0; joints[i].currentTranslationKeyframe = 0; joints[i].finalMatrix = new Matrix4f(joints[i].absoluteMatrix); } currentTime = 0; if (currentAnimation != -1) { MS3DAnimation ms3dAnimation = (MS3DAnimation) allAnimations.get(currentAnimation); currentTime += ms3dAnimation.startFrame * 1000.0 / animationFPS; } loopDone = false; } public void updateAnimation(long time) { currentTime += time - lastTime; lastTime = time; if (currentAnimation == -1) { endFrame = totalFrames; } else { MS3DAnimation ms3dAnimation = (MS3DAnimation) allAnimations.get(currentAnimation); endFrame = ms3dAnimation.endFrame; } if (currentTime >= (endFrame + 1) * 1000.0 / animationFPS) { if (loop) { reset(); } else { currentTime = (long) ((endFrame + 1) * 1000.0 / animationFPS); loopDone = true; } } for (int i = 0; i < numJoints; i++) { Vector3f transVec = new Vector3f(); Matrix4f transform = new Matrix4f(); transform.setIdentity(); short frame; MS3DJoint joint = joints[i]; if (joint.numRotationKeyframes == 0 && joint.numTranslationKeyframes == 0) { joint.finalMatrix = new Matrix4f(joint.absoluteMatrix); continue; } frame = joint.currentTranslationKeyframe; while (frame < joint.numTranslationKeyframes && joint.translationKeyframes[frame].time < currentTime) { frame++; } // System.out.println("frame:"+frame); joint.currentTranslationKeyframe = frame; if (frame == 0) { transVec.x = joint.translationKeyframes[0].x; transVec.y = joint.translationKeyframes[0].y; transVec.z = joint.translationKeyframes[0].z; } else if (frame == joint.numTranslationKeyframes) { transVec.x = joint.translationKeyframes[frame - 1].x; transVec.y = joint.translationKeyframes[frame - 1].y; transVec.z = joint.translationKeyframes[frame - 1].z; } else { MS3DKeyframe curFrame = joint.translationKeyframes[frame]; MS3DKeyframe prevFrame = joint.translationKeyframes[frame - 1]; float timeDelta = ((float) (curFrame.time - prevFrame.time)); float interpValue = (float) ((currentTime - prevFrame.time) / (float) timeDelta); transVec.x = prevFrame.x + (curFrame.x - prevFrame.x) * interpValue; transVec.y = prevFrame.y + (curFrame.y - prevFrame.y) * interpValue; transVec.z = prevFrame.z + (curFrame.z - prevFrame.z) * interpValue; } // frame = joint.currentRotationKeyframe; while (frame < joint.numRotationKeyframes && joint.rotationKeyframes[frame].time < currentTime) { frame++; } joint.currentRotationKeyframe = frame; if (frame == 0) { setRzRyRxRotationTranspose(transform,joint.rotationKeyframes[0].z,joint.rotationKeyframes[0].y,joint.rotationKeyframes[0].x); } else if (frame == joint.numRotationKeyframes) { setRzRyRxRotationTranspose(transform,joint.rotationKeyframes[frame - 1].z,joint.rotationKeyframes[frame - 1].y,joint.rotationKeyframes[frame - 1].x); } else { MS3DKeyframe curFrame = joint.rotationKeyframes[frame]; MS3DKeyframe prevFrame = joint.rotationKeyframes[frame - 1]; float timeDelta = ((float) (curFrame.time - prevFrame.time)); float interpValue = (float) ((currentTime - prevFrame.time) / timeDelta); Vector3f rotVec = new Vector3f(); rotVec.x = prevFrame.x + (curFrame.x - prevFrame.x) * interpValue; rotVec.y = prevFrame.y + (curFrame.y - prevFrame.y) * interpValue; rotVec.z = prevFrame.z + (curFrame.z - prevFrame.z) * interpValue; setRzRyRxRotationTranspose(transform, rotVec.z, rotVec.y, rotVec.x); } // Translation setTranslationTranspose(transform, transVec.x, transVec.y, transVec.z); Matrix4f relativeFinal = new Matrix4f(); mulTransposeBothTanspose(relativeFinal, joint.relativeMatrix, transform); if (joint.parentName.equals("")) { joint.finalMatrix = relativeFinal; } else { MS3DJoint father = (MS3DJoint) allJoints.get(joint.parentName); joint.finalMatrix = new Matrix4f(); mulTransposeBothTanspose(joint.finalMatrix, father.finalMatrix, relativeFinal); } } } public static void setRzRyRxRotationTranspose(Matrix4f matrix, float z, float y, float x) { if (matrix == null) { matrix = new Matrix4f(); matrix.setIdentity(); } double cosinusX = Math.cos(x); double sinusX = Math.sin(x); double cosinusY = Math.cos(y); double sinusY = Math.sin(y); double cosinusZ = Math.cos(z); double sinusZ = Math.sin(z); matrix.m00 = (float) (cosinusY * cosinusZ); matrix.m01 = (float) (cosinusY * sinusZ); matrix.m02 = (float) (-sinusY); // do not alter m03 matrix.m10 = (float) (sinusX * sinusY * cosinusZ - cosinusX * sinusZ); matrix.m11 = (float) (sinusX * sinusY * sinusZ + cosinusX * cosinusZ); matrix.m12 = (float) (sinusX * cosinusY); // do not alter m13 matrix.m20 = (float) (cosinusX * sinusY * cosinusZ + sinusX * sinusZ); matrix.m21 = (float) (cosinusX * sinusY * sinusZ - sinusX * cosinusZ); matrix.m22 = (float) (cosinusX * cosinusY); // do not alter m23 // do not alter m30 - m33 } public static void setTranslationTranspose(Matrix4f matrix, float x, float y, float z) { if (matrix == null) { matrix = new Matrix4f(); matrix.setIdentity(); } // do not alter m00 - m23 matrix.m30 = x; matrix.m31 = y; matrix.m32 = z; matrix.m33 = 1.0f; } public static void mulTransposeBothTanspose(Matrix4f matrix, Matrix4f matrixA, Matrix4f matrixB) { if (matrix == null) { matrix = new Matrix4f(); } matrix.m00 = matrixA.m00 * matrixB.m00 + matrixA.m10 * matrixB.m01 + matrixA.m20 * matrixB.m02; matrix.m01 = matrixA.m01 * matrixB.m00 + matrixA.m11 * matrixB.m01 + matrixA.m21 * matrixB.m02; matrix.m02 = matrixA.m02 * matrixB.m00 + matrixA.m12 * matrixB.m01 + matrixA.m22 * matrixB.m02; matrix.m03 = 0.0f; matrix.m10 = matrixA.m00 * matrixB.m10 + matrixA.m10 * matrixB.m11 + matrixA.m20 * matrixB.m12; matrix.m11 = matrixA.m01 * matrixB.m10 + matrixA.m11 * matrixB.m11 + matrixA.m21 * matrixB.m12; matrix.m12 = matrixA.m02 * matrixB.m10 + matrixA.m12 * matrixB.m11 + matrixA.m22 * matrixB.m12; matrix.m13 = 0.0f; matrix.m20 = matrixA.m00 * matrixB.m20 + matrixA.m10 * matrixB.m21 + matrixA.m20 * matrixB.m22; matrix.m21 = matrixA.m01 * matrixB.m20 + matrixA.m11 * matrixB.m21 + matrixA.m21 * matrixB.m22; matrix.m22 = matrixA.m02 * matrixB.m20 + matrixA.m12 * matrixB.m21 + matrixA.m22 * matrixB.m22; matrix.m23 = 0.0f; matrix.m30 = matrixA.m00 * matrixB.m30 + matrixA.m10 * matrixB.m31 + matrixA.m20 * matrixB.m32 + matrixA.m30; matrix.m31 = matrixA.m01 * matrixB.m30 + matrixA.m11 * matrixB.m31 + matrixA.m21 * matrixB.m32 + matrixA.m31; matrix.m32 = matrixA.m02 * matrixB.m30 + matrixA.m12 * matrixB.m31 + matrixA.m22 * matrixB.m32 + matrixA.m32; matrix.m33 = 1.0f; } public void addAnimation(MS3DAnimation ms3dAnimation) { allAnimations.addElement(ms3dAnimation); } public void deleteAnimations() { for (int i = 0; i < allAnimations.size(); i++) { allAnimations.remove(i); } } public int numberAnimations() { return allAnimations.size(); } /** * 初始化骨骼和绑定顶点 */ private void makeBones() { MS3DJoint joint = null; MS3DVertex vertex = null; MS3DJoint father = null; // make the bone hierarchy for (int i = 0; i < numJoints; i++) { joint = joints[i]; joint.relativeMatrix = new Matrix4f(); // Rotation MS3DModel.setRzRyRxRotationTranspose(joint.relativeMatrix,joint.rotation[2], joint.rotation[1], joint.rotation[0]); // Translation MS3DModel.setTranslationTranspose(joint.relativeMatrix,joint.translation[0], joint.translation[1],joint.translation[2]); if (!joint.parentName.equals("")) { // 如果是子关节,那么将上一个节点的绝对矩阵乘上这个节点的变幻矩 阵就可以得到这个子节点的绝对矩阵了. father = (MS3DJoint) allJoints.get(joint.parentName); joint.absoluteMatrix = new Matrix4f(); MS3DModel.mulTransposeBothTanspose(joint.absoluteMatrix, father.absoluteMatrix, joint.relativeMatrix); } else { // 如果是根关节那么它的绝对矩阵就是它的相对变换矩阵 joint.absoluteMatrix = new Matrix4f(joint.relativeMatrix); } } // initialize the vertices for (int i = 0; i < numVertices; i++) { vertex = vertices[i]; if (vertex.boneID != -1) { Matrix4f matrix = joints[vertex.boneID].absoluteMatrix; float x = vertex.vertex.x - matrix.m30; float y = vertex.vertex.y - matrix.m31; float z = vertex.vertex.z - matrix.m32; this.vertex[3 * i] = x * matrix.m00 + y * matrix.m01 + z * matrix.m02; this.vertex[3 * i + 1] = x * matrix.m10 + y * matrix.m11 + z * matrix.m12; this.vertex[3 * i + 2] = x * matrix.m20 + y * matrix.m21 + z * matrix.m22; } } } private void makeBounding() { float minX,minY,minZ,maxX,maxY,maxZ; minX=minY=minZ=maxX=maxY=maxZ=0; Vector3f vertex; for(int i=0;i<this.vertices.length;i++) { vertex=this.vertices[i].vertex; if (i == 0) { minX = maxX = vertex.x; minY = maxY = vertex.y; minZ = maxZ = vertex.z; } else { if (vertex.x < minX) minX = vertex.x; else if (vertex.x > maxX) maxX = vertex.x; if (vertex.y < minY) minY = vertex.y; else if (vertex.y > maxY) maxY = vertex.y; if (vertex.z < minZ) minZ = vertex.z; else if (vertex.z > maxZ) maxZ = vertex.z; } } this.bounding=new Bounding(minX, minY, minZ, maxX, maxY, maxZ); } /*************************************************************************************************************************************************************************************************** * Header of a ms3d file **************************************************************************************************************************************************************************************************/ private class MS3DHeader { /** Read the header */ public MS3DHeader(BinaryFileReader modelFile) { this.ID = modelFile.readString(10); this.version = modelFile.readInt(); } /** Check whether the header is valid */ public boolean isValid() { if ((this.ID.equals("MS3D000000") && this.version >= 3 && this.version <= 4)) return true; else return false; } String ID; int version; } /*************************************************************************************************************************************************************************************************** * Vertex as used in ms3d files **************************************************************************************************************************************************************************************************/ @SuppressWarnings("unused") private class MS3DVertex { /** Read a vertex */ public MS3DVertex(BinaryFileReader modelFile) { this.flags = modelFile.readByte(); this.vertex = new Vector3f(modelFile.readFloat(), modelFile.readFloat(), modelFile.readFloat()); this.boneID = modelFile.readByte(); this.refCount = modelFile.readByte(); } Vector3f vertex; int boneID; int flags; int refCount; } /*************************************************************************************************************************************************************************************************** * Triangle as used in ms3d files **************************************************************************************************************************************************************************************************/ @SuppressWarnings("unused") private class MS3DTriangle { /** Read a triangle */ public MS3DTriangle(BinaryFileReader modelFile) { this.flags = modelFile.readShort(); this.vertexIndices[0] = modelFile.readShort(); this.vertexIndices[1] = modelFile.readShort(); this.vertexIndices[2] = modelFile.readShort(); this.vertexNormals[0][0] = modelFile.readFloat(); this.vertexNormals[0][1] = modelFile.readFloat(); this.vertexNormals[0][2] = modelFile.readFloat(); this.vertexNormals[1][0] = modelFile.readFloat(); this.vertexNormals[1][1] = modelFile.readFloat(); this.vertexNormals[1][2] = modelFile.readFloat(); this.vertexNormals[2][0] = modelFile.readFloat(); this.vertexNormals[2][1] = modelFile.readFloat(); this.vertexNormals[2][2] = modelFile.readFloat(); this.s[0] = modelFile.readFloat(); this.s[1] = modelFile.readFloat(); this.s[2] = modelFile.readFloat(); this.t[0] = 1 - modelFile.readFloat(); this.t[1] = 1 - modelFile.readFloat(); this.t[2] = 1 - modelFile.readFloat(); this.smoothingMesh = modelFile.readByte(); this.meshIndex = modelFile.readByte(); } int flags; int vertexIndices[] = new int[3]; float[][] vertexNormals = new float[3][3]; float[] s = new float[3]; float[] t = new float[3]; int smoothingMesh; int meshIndex; } /*************************************************************************************************************************************************************************************************** * Mesh to group triangles which use the same material **************************************************************************************************************************************************************************************************/ @SuppressWarnings("unused") private class MS3DMesh { // Read a mesh public MS3DMesh(BinaryFileReader modelFile) { this.flags = modelFile.readByte(); this.name = modelFile.readString(32); this.numTriangles = modelFile.readShort(); this.triangleIndices = new int[this.numTriangles]; for (int i = 0; i < this.numTriangles; i++) this.triangleIndices[i] = modelFile.readShort(); this.materialIndex = modelFile.readByte(); } String name; int materialIndex; int numTriangles; int[] triangleIndices; int flags; } /*************************************************************************************************************************************************************************************************** * Material as used in ms3d files **************************************************************************************************************************************************************************************************/ @SuppressWarnings("unused") private class MS3DMaterial { // Read a material public MS3DMaterial(BinaryFileReader modelFile) { this.name = modelFile.readString(32); float[] ambientArray = new float[] { modelFile.readFloat(),modelFile.readFloat(), modelFile.readFloat(),modelFile.readFloat() }; float[] diffuseArray = new float[] { modelFile.readFloat(),modelFile.readFloat(), modelFile.readFloat(),modelFile.readFloat() }; float[] specularArray = new float[] { modelFile.readFloat(),modelFile.readFloat(), modelFile.readFloat(),modelFile.readFloat() }; float[] emissiveArray = new float[] { modelFile.readFloat(),modelFile.readFloat(), modelFile.readFloat(),modelFile.readFloat() }; this.shininess = modelFile.readFloat(); this.transparency = modelFile.readFloat(); this.mode = modelFile.readByte(); this.texturemap = modelFile.readString(128); this.alphamap = modelFile.readString(128); // // Fix paths if (this.texturemap.startsWith("..\\")) this.texturemap = this.texturemap.substring(3); if (this.texturemap.startsWith(".\\")) this.texturemap = this.texturemap.substring(2); if (this.alphamap.startsWith("..\\")) this.alphamap = this.alphamap.substring(3); if (this.alphamap.startsWith(".\\")) this.alphamap = this.alphamap.substring(2); // Fill buffers this.ambient.put(ambientArray).flip(); this.diffuse.put(diffuseArray).flip(); this.specular.put(specularArray).flip(); this.emissive.put(emissiveArray).flip(); } String name; String texturemap; int textureID; String alphamap; FloatBuffer ambient = BufferUtils.createFloatBuffer(4); FloatBuffer diffuse = BufferUtils.createFloatBuffer(4); FloatBuffer specular = BufferUtils.createFloatBuffer(4); FloatBuffer emissive = BufferUtils.createFloatBuffer(4); float shininess; float transparency; int mode; } /*************************************************************************************************************************************************************************************************** * Joint information as used in ms3d files **************************************************************************************************************************************************************************************************/ @SuppressWarnings("unused") private class MS3DJoint { // Read Joint public MS3DJoint(BinaryFileReader modelFile) { this.flag = modelFile.readByte(); this.name = modelFile.readString(32); System.out.print(name + ":"); this.parentName = modelFile.readString(32); this.rotation[0] = modelFile.readFloat(); this.rotation[1] = modelFile.readFloat(); this.rotation[2] = modelFile.readFloat(); this.translation[0] = modelFile.readFloat(); this.translation[1] = modelFile.readFloat(); this.translation[2] = modelFile.readFloat(); this.numRotationKeyframes = modelFile.readShort(); this.numTranslationKeyframes = modelFile.readShort(); System.out.println(this.numRotationKeyframes + "," + this.numTranslationKeyframes); this.rotationKeyframes = new MS3DKeyframe[numRotationKeyframes]; for (int i = 0; i < this.numRotationKeyframes; i++) this.rotationKeyframes[i] = new MS3DKeyframe(modelFile); this.translationKeyframes = new MS3DKeyframe[numTranslationKeyframes]; for (int i = 0; i < this.numTranslationKeyframes; i++) this.translationKeyframes[i] = new MS3DKeyframe(modelFile); } int flag; String name; String parentName; float[] rotation = new float[3]; float[] translation = new float[3]; int numRotationKeyframes; int numTranslationKeyframes; MS3DKeyframe[] rotationKeyframes; MS3DKeyframe[] translationKeyframes; Matrix4f absoluteMatrix; Matrix4f relativeMatrix; Matrix4f finalMatrix; short currentRotationKeyframe; short currentTranslationKeyframe; } /*************************************************************************************************************************************************************************************************** * Keyframe as used in ms3d files **************************************************************************************************************************************************************************************************/ private class MS3DKeyframe { // Read Keyframe public MS3DKeyframe(BinaryFileReader modelFile) { this.time = (long) (modelFile.readFloat() * 1000); this.x = modelFile.readFloat(); this.y = modelFile.readFloat(); this.z = modelFile.readFloat(); } float time; // time in seconds float x, y, z; } @SuppressWarnings("unused") private class MS3DAnimation { short startFrame; short endFrame; public MS3DAnimation() { this.startFrame = 0; this.endFrame = 0; } /** Creates a new instance of MS3DAnimation */ public MS3DAnimation(short startFrame, short endFrame) { this.startFrame = startFrame; this.endFrame = endFrame; } public MS3DAnimation(int startFrame, int endFrame) { this.startFrame = (short) startFrame; this.endFrame = (short) endFrame; } } public Bounding getBounding() { return bounding; } }
演示效果如下:
相关推荐
【标题】"演示ms3d动画的例子"是一个关于如何在编程环境中展示MS3D(Microsoft 3D)模型和动画的实例。这个示例项目包含了从加载到渲染MS3D模型的所有关键步骤,旨在帮助开发者理解和应用3D图形技术。 【描述】"ms...
### MS3D模型骨骼动画详解 #### 一、模型动画技术概述 模型动画技术是现代三维图形学中不可或缺的一部分,广泛应用于游戏开发、电影制作、虚拟现实等领域。根据实现方式的不同,模型动画主要分为两大类:**顶点...
ms3d模型ms3d模型ms3d模型ms3d模型ms3d模型ms3d模型ms3d模型
在IT行业中,3D模型与动画的结合是一个重要的领域,特别是在增强现实(AR)、游戏开发、影视制作以及可视化设计中。这里的"3D模型带动画"指的是具有三维形状和细节的数字对象,它们不仅有静态的外观,还能通过预设的...
其中的3D模型使用的是初音,模型质量很高,可以自己用鼠标和键盘控制视角。 【Visual C++】游戏开发笔记之【浅墨DirectX提高班】系列博文 配套详细注释源码之十二 源码配套博文 《【Visual C++】游戏开发笔记四十...
总结来说,这个“Unity 3D模型展示”项目涵盖了3D模型导入与优化、3D标注的创建、环绕相机的实现、步骤列表与拆装动画的构建等多个关键知识点。通过这些技术,开发者可以构建出具有高度互动性和教育价值的3D应用,...
opengl读取一个ms3d的飞行器模型,挺有用的
它支持模型、纹理、骨骼、动画和相机数据。FBX的跨平台特性使得它成为游戏开发、影视特效和视觉设计等行业中广泛使用的标准格式。 "Body.tga" 是一种图像文件,可能作为模型的身体部分的纹理。TGA(Truevision ...
本书提供的MS3D模型文件是MilkShape支持的一种特定格式,用于存储3D模型数据,包括几何形状、纹理、骨架和动画等信息。 MS3D(MilkShape 3D)模型文件格式是专为游戏设计而优化的,它以紧凑和高效的方式保存数据,...
在Unity3D游戏开发中,FBX模型的载入与人物行走动画的播放是至关重要的环节,这涉及到游戏场景的构建、角色交互以及游戏体验的提升。FBX是一种跨平台的三维模型交换格式,广泛应用于游戏开发、电影制作等领域。Unity...
标题中的“安川机器人3D模型 MS165”指的是由日本知名自动化设备制造商安川电机(Yaskawa)生产的MS165型号机器人的一种三维(3D)模型。这款模型通常用于工业自动化领域的设计、仿真和规划,帮助工程师在实际部署前...
【标题】"ms3d教程一套"所涉及的知识点主要围绕MS3D模型格式和相关的3D建模与动画制作技术展开。MS3D是一种流行的3D模型文件格式,尤其在游戏开发和实时渲染领域中常见。这个教程可能包含从基础到高级的各个层次的...
4. **导出与导入**:学习如何将MS3D模型导出为其他游戏引擎支持的格式,如Wavefront OBJ、3DS或MD5,并了解导入其他格式的模型到MilkShape进行编辑。 5. **实例操作**:书中可能提供了一些实际案例,如创建简单的...
《maya3D模型:棒球选手与动画制作解析》 在数字艺术和影视特效领域,maya3D模型是不可或缺的重要元素。本资源“maya3D模型 棒球选手(有动画)”正是这样一个专业级别的3D模型,为创作者提供了丰富的表现力和动态...
MS3D支持多种3D模型和动画格式的导入导出,其中就包括我们关注的骨骼动画系统。 骨骼动画,是3D角色动画的一种核心技术,通过将3D模型的各个部分与虚拟骨骼关联,然后对骨骼进行移动、旋转,就能实现角色的动态表现...
4. **支持多种游戏引擎**:MS3D可以直接导出模型数据到各种游戏引擎支持的格式,如Valve的MDL(用于半条命系列)、ID Software的MDL(用于毁灭战士系列)、以及Unreal Engine的UNR等。 5. **轻量级与高效**:与其他...
总的来说,"ms3d-loader"是一个学习和演示如何在OpenGL环境中处理3D模型和材质的实用工具。它涵盖了文件解析、OpenGL纹理操作、3D模型渲染等多个关键知识点,对于理解3D图形编程和游戏开发具有很高的参考价值。
Helix Toolkit是一个开源项目,专为Windows Presentation Foundation (WPF) 平台提供3D模型和3D动画功能。这个库极大地扩展了WPF的原生3D支持,使得开发者可以更加轻松地创建复杂的3D应用程序,包括但不限于游戏、...
在IT领域,3D模型加载是一项关键的技术,尤其在游戏开发、虚拟现实、建筑设计和可视化应用中至关重要。本文将深入探讨3D模型加载的过程、相关的技术以及如何实现一个可移植的3D模型加载软件。 首先,3D模型是通过...
在XNA框架中,载入3D模型是游戏开发中的重要步骤,这使得我们能够将复杂的3D几何体、纹理和动画引入到游戏环境中。XNA是一个由Microsoft开发的开源游戏开发平台,它为.NET Framework提供了游戏开发工具,特别适合...