何か見逃したことがありますか、それとも私のコードに何か問題がありますか?
次のリンクが役立つ場合があります。
.smd モデル インポーターを作成しましたが、何らかの理由で静止フレーム以外のすべてのフレームが台無しになっています。
まず、ファイルからすべての情報を読み込み、arraylist に保存します。次に、このメソッドを呼び出して、レンダリングのためにすべてを計算します。
private void CalculateMatrices(Model model) {
for(Bone bone : model.bones){
if(bone.boneParentsID >= 0) {
bone.parent = model.bones.get(bone.boneParentsID);
}
Matrix4f defaultBoneTransform = new Matrix4f();
defaultBoneTransform.rotate(bone.defaultRotation.x, new Vector3f(1.0f, 0.0f, 0.0f));
defaultBoneTransform.rotate(bone.defaultRotation.y, new Vector3f(0.0f, 1.0f, 0.0f));
defaultBoneTransform.rotate(bone.defaultRotation.z, new Vector3f(0.0f, 0.0f, 1.0f));
defaultBoneTransform.translate(bone.defaultPosition);
bone.defaultBoneTransform = defaultBoneTransform;
for(Frame frame : bone.frames){
Matrix4f boneTransform = new Matrix4f();
boneTransform.rotate(frame.rotation.x, new Vector3f(1.0f, 0.0f, 0.0f));
boneTransform.rotate(frame.rotation.y, new Vector3f(0.0f, 1.0f, 0.0f));
boneTransform.rotate(frame.rotation.z, new Vector3f(0.0f, 0.0f, 1.0f));
boneTransform.translate(frame.position);
bone.boneTransforms.add(boneTransform);
}
}
for(Bone bone : model.bones){
Matrix4f atRestTransform = new Matrix4f();
if(bone.boneParentsID == -1) {
atRestTransform = new Matrix4f(bone.defaultBoneTransform);
} else {
for (Bone current = bone; current != null; current = current.parent) {
Matrix4f.mul(current.defaultBoneTransform, atRestTransform, atRestTransform);
}
}
bone.boneToWorldDefault = new Matrix4f(atRestTransform);
atRestTransform.invert();
bone.atRestTransform = new Matrix4f(atRestTransform);
for(Frame frame : bone.frames){
Matrix4f boneToWorldTransform = new Matrix4f();
if(bone.boneParentsID == -1) {
boneToWorldTransform = new Matrix4f(bone.boneTransforms.get(frame.time));
} else {
for (Bone current = bone; current != null; current = current.parent) {
Matrix4f.mul(current.boneTransforms.get(frame.time), boneToWorldTransform, boneToWorldTransform);
}
}
bone.boneToWorldTransforms.add(new Matrix4f(boneToWorldTransform));
}
}
for (Vertex vertex : model.vertices) {
for (Frame frame : model.bones.get(0).frames) {
List<Vector4f> vertexPosAnimatedList = new ArrayList<Vector4f>();
for (float boneID : vertex.boneIDs) {
Vector4f vertexPosAnimated = new Vector4f();
Bone bone = model.bones.get((int) boneID);
Matrix4f mul = new Matrix4f();
Matrix4f.mul(bone.boneToWorldTransforms.get(frame.time), bone.atRestTransform, mul);
Vector4f vecPosMod = new Vector4f(vertex.position.x, vertex.position.y, vertex.position.z, 1f);
Matrix4f.transform(mul, vecPosMod, vertexPosAnimated);
vertexPosAnimated.scale(vertex.boneW.get(vertex.boneIDs.indexOf(boneID)));
vertexPosAnimatedList.add(vertexPosAnimated);
}
Vector4f vertexPosAnimated1 = new Vector4f();
for(int i = 0; i < vertexPosAnimatedList.size(); i++) {
if(i == 0) {
vertexPosAnimated1 = vertexPosAnimatedList.get(0);
} else {
Vector4f.add(vertexPosAnimated1, vertexPosAnimatedList.get(i), vertexPosAnimated1);
}
}
Vector3f animatedPos = new Vector3f(vertexPosAnimated1.x, vertexPosAnimated1.y, vertexPosAnimated1.z);
vertex.positionOnFrames.add(animatedPos);
}
}
}
そしてレンダリング:
GL11.glBegin(GL11.GL_TRIANGLES);
for (Vertex vertex : model.vertices) {
Vector3f pos = vertex.positionOnFrames.get(curFrame);
GL11.glNormal3f(model.normals.get(model.vertices.indexOf(vertex)).x, model.normals.get(model.vertices.indexOf(vertex)).y, model.normals.get(model.vertices.indexOf(vertex)).z);
GL11.glTexCoord2f(model.textures.get(model.vertices.indexOf(vertex)).x, model.textures.get(model.vertices.indexOf(vertex)).y);
GL11.glVertex3f(pos.x, pos.y, pos.z);
}
GL11.glEnd();
CalculateMatrices
問題はメソッドのどこかにあると思います。
その方法では:
- ボーンの回転と移動を含む、すべてのボーンとすべてのフレームの変換マトリックスを作成します。
- 骨の静止位置を計算し、それがすべてのフレームのワールド位置です。
- 頂点に複数のボーンを設定するなど、より多くの計算を行います。
- 各頂点をアニメーション化された位置とともに配列リストに格納します。