From f58bdfcb66353bb77213cab580bc49ef890417ad Mon Sep 17 00:00:00 2001 From: olamedia Date: Sun, 23 Dec 2012 11:30:36 +0600 Subject: 0.1.7 --- src/jp/nyatla/nymmd/MmdException.java | 70 ++++ src/jp/nyatla/nymmd/MmdMotionPlayer.java | 434 +++++++++++++++++++++++ src/jp/nyatla/nymmd/MmdMotionPlayerGL2.java | 434 +++++++++++++++++++++++ src/jp/nyatla/nymmd/MmdPmdModel.java | 74 ++++ src/jp/nyatla/nymmd/MmdPmdModel_BasicClass.java | 317 +++++++++++++++++ src/jp/nyatla/nymmd/MmdVmdMotion.java | 55 +++ src/jp/nyatla/nymmd/MmdVmdMotion_BasicClass.java | 290 +++++++++++++++ src/jp/nyatla/nymmd/core/PmdBone.java | 224 ++++++++++++ src/jp/nyatla/nymmd/core/PmdFace.java | 108 ++++++ src/jp/nyatla/nymmd/core/PmdIK.java | 194 ++++++++++ src/jp/nyatla/nymmd/struct/DataReader.java | 120 +++++++ src/jp/nyatla/nymmd/struct/StructReader.java | 82 +++++ src/jp/nyatla/nymmd/struct/StructType.java | 48 +++ src/jp/nyatla/nymmd/struct/pmd/PMD_Bone.java | 66 ++++ src/jp/nyatla/nymmd/struct/pmd/PMD_FACE.java | 74 ++++ src/jp/nyatla/nymmd/struct/pmd/PMD_FACE_VTX.java | 75 ++++ src/jp/nyatla/nymmd/struct/pmd/PMD_Header.java | 69 ++++ src/jp/nyatla/nymmd/struct/pmd/PMD_IK.java | 83 +++++ src/jp/nyatla/nymmd/struct/pmd/PMD_Material.java | 82 +++++ src/jp/nyatla/nymmd/struct/pmd/PMD_Vertex.java | 78 ++++ src/jp/nyatla/nymmd/struct/vmd/VMD_Face.java | 60 ++++ src/jp/nyatla/nymmd/struct/vmd/VMD_Header.java | 63 ++++ src/jp/nyatla/nymmd/struct/vmd/VMD_Motion.java | 94 +++++ src/jp/nyatla/nymmd/types/BoneKeyFrame.java | 62 ++++ src/jp/nyatla/nymmd/types/FaceData.java | 45 +++ src/jp/nyatla/nymmd/types/FaceKeyFrame.java | 53 +++ src/jp/nyatla/nymmd/types/MmdColor3.java | 53 +++ src/jp/nyatla/nymmd/types/MmdColor4.java | 59 +++ src/jp/nyatla/nymmd/types/MmdMatrix.java | 377 ++++++++++++++++++++ src/jp/nyatla/nymmd/types/MmdTexUV.java | 59 +++ src/jp/nyatla/nymmd/types/MmdVector3.java | 209 +++++++++++ src/jp/nyatla/nymmd/types/MmdVector4.java | 137 +++++++ src/jp/nyatla/nymmd/types/MotionData.java | 125 +++++++ src/jp/nyatla/nymmd/types/PmdMaterial.java | 51 +++ src/jp/nyatla/nymmd/types/PmdSkinInfo.java | 47 +++ 35 files changed, 4471 insertions(+) create mode 100644 src/jp/nyatla/nymmd/MmdException.java create mode 100644 src/jp/nyatla/nymmd/MmdMotionPlayer.java create mode 100644 src/jp/nyatla/nymmd/MmdMotionPlayerGL2.java create mode 100644 src/jp/nyatla/nymmd/MmdPmdModel.java create mode 100644 src/jp/nyatla/nymmd/MmdPmdModel_BasicClass.java create mode 100644 src/jp/nyatla/nymmd/MmdVmdMotion.java create mode 100644 src/jp/nyatla/nymmd/MmdVmdMotion_BasicClass.java create mode 100644 src/jp/nyatla/nymmd/core/PmdBone.java create mode 100644 src/jp/nyatla/nymmd/core/PmdFace.java create mode 100644 src/jp/nyatla/nymmd/core/PmdIK.java create mode 100644 src/jp/nyatla/nymmd/struct/DataReader.java create mode 100644 src/jp/nyatla/nymmd/struct/StructReader.java create mode 100644 src/jp/nyatla/nymmd/struct/StructType.java create mode 100644 src/jp/nyatla/nymmd/struct/pmd/PMD_Bone.java create mode 100644 src/jp/nyatla/nymmd/struct/pmd/PMD_FACE.java create mode 100644 src/jp/nyatla/nymmd/struct/pmd/PMD_FACE_VTX.java create mode 100644 src/jp/nyatla/nymmd/struct/pmd/PMD_Header.java create mode 100644 src/jp/nyatla/nymmd/struct/pmd/PMD_IK.java create mode 100644 src/jp/nyatla/nymmd/struct/pmd/PMD_Material.java create mode 100644 src/jp/nyatla/nymmd/struct/pmd/PMD_Vertex.java create mode 100644 src/jp/nyatla/nymmd/struct/vmd/VMD_Face.java create mode 100644 src/jp/nyatla/nymmd/struct/vmd/VMD_Header.java create mode 100644 src/jp/nyatla/nymmd/struct/vmd/VMD_Motion.java create mode 100644 src/jp/nyatla/nymmd/types/BoneKeyFrame.java create mode 100644 src/jp/nyatla/nymmd/types/FaceData.java create mode 100644 src/jp/nyatla/nymmd/types/FaceKeyFrame.java create mode 100644 src/jp/nyatla/nymmd/types/MmdColor3.java create mode 100644 src/jp/nyatla/nymmd/types/MmdColor4.java create mode 100644 src/jp/nyatla/nymmd/types/MmdMatrix.java create mode 100644 src/jp/nyatla/nymmd/types/MmdTexUV.java create mode 100644 src/jp/nyatla/nymmd/types/MmdVector3.java create mode 100644 src/jp/nyatla/nymmd/types/MmdVector4.java create mode 100644 src/jp/nyatla/nymmd/types/MotionData.java create mode 100644 src/jp/nyatla/nymmd/types/PmdMaterial.java create mode 100644 src/jp/nyatla/nymmd/types/PmdSkinInfo.java (limited to 'src/jp/nyatla') diff --git a/src/jp/nyatla/nymmd/MmdException.java b/src/jp/nyatla/nymmd/MmdException.java new file mode 100644 index 0000000..929d409 --- /dev/null +++ b/src/jp/nyatla/nymmd/MmdException.java @@ -0,0 +1,70 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd; + + + +public class MmdException extends Exception +{ + private static final long serialVersionUID = 1L; + + public MmdException() + { + super(); + } + + public MmdException(Exception e) + { + super(e); + } + + public MmdException(String m) + { + super(m); + } + + public static void trap(String m) throws MmdException + { + throw new MmdException("トラップ:" + m); + } + + public static void notImplement() throws MmdException + { + throw new MmdException("Not Implement!"); + } +} diff --git a/src/jp/nyatla/nymmd/MmdMotionPlayer.java b/src/jp/nyatla/nymmd/MmdMotionPlayer.java new file mode 100644 index 0000000..65b35ae --- /dev/null +++ b/src/jp/nyatla/nymmd/MmdMotionPlayer.java @@ -0,0 +1,434 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd; + +import jp.nyatla.nymmd.core.PmdBone; +import jp.nyatla.nymmd.core.PmdFace; +import jp.nyatla.nymmd.core.PmdIK; +import jp.nyatla.nymmd.types.*; + +public class MmdMotionPlayer { + protected MmdPmdModel_BasicClass _ref_pmd_model; + protected MmdVmdMotion_BasicClass _ref_vmd_motion; + + private PmdBone[] m_ppBoneList; + private PmdFace[] m_ppFaceList; + + public MmdMatrix[] _skinning_mat; + + public PmdBone m_pNeckBone; // 首のボーン + public PmdBone m_centerBone; // センター + public PmdBone m_leftFootIK; // 左足IK先 + public PmdBone m_rightFootIK; // 右足IK先 + public PmdBone m_leftToe; // 左つま先 + public PmdBone m_rightToe; // 右つま先 + public PmdBone m_leftKnee; // 左ひざ + public PmdBone m_rightKnee; // 右ひざ + public PmdBone m_leftAnkle; // 左足首 + public PmdBone m_rightAnkle; // 右足首 + public PmdBone m_leftLeg; // + public PmdBone m_rightLeg; // + public PmdBone m_leftEyeDestination; // 左目先 + public PmdBone m_rightEyeDestination; // 右目先 + public PmdBone m_lowerBody; // 下半身 + public PmdBone m_upperBody; // 上半身 + public PmdBone m_leftArm; // 左腕 + public PmdBone m_rightArm; // 右腕 + public PmdBone m_leftElbow; // 左ひじ + public PmdBone m_rightElbow; // 右ひじ + public PmdBone m_leftWrist; // 左手首 + public PmdBone m_rightWrist; // 右手首 + public PmdBone m_skirtFrontLeft; // + public PmdBone m_skirtFrontRight; // + + public MmdMotionPlayer() { + return; + } + + public void setPmd(MmdPmdModel_BasicClass i_pmd_model) throws MmdException { + this._ref_pmd_model = i_pmd_model; + PmdBone[] bone_array = i_pmd_model.getBoneArray(); + // スキニング用のmatrix + this._skinning_mat = MmdMatrix.createArray(bone_array.length); + // 首^H頭のボーンを探しておく + this.m_pNeckBone = null; + for (int i = 0; i < bone_array.length; i++) { + System.err.println("" + bone_array[i].getName() + ""); + if (bone_array[i].getName().equals("頭")) { + this.m_pNeckBone = bone_array[i]; + // break; + } + // センター先 + if (bone_array[i].getName().equals("下半身")) { + this.m_lowerBody = bone_array[i]; + } + if (bone_array[i].getName().equals("上半身")) { + this.m_upperBody = bone_array[i]; + } + + if (bone_array[i].getName().equals("左ス前2")) { + this.m_skirtFrontLeft = bone_array[i]; + } + if (bone_array[i].getName().equals("左スカート前")) { + this.m_skirtFrontLeft = bone_array[i]; + } + if (bone_array[i].getName().equals("右ス前2")) { + this.m_skirtFrontRight = bone_array[i]; + } + if (bone_array[i].getName().equals("右スカート前")) { + this.m_skirtFrontRight = bone_array[i]; + } + if (bone_array[i].getName().equals("左腕")) { + this.m_leftArm = bone_array[i]; + } + if (bone_array[i].getName().equals("右腕")) { + this.m_rightArm = bone_array[i]; + } + + if (bone_array[i].getName().equals("左手首")) { + this.m_leftWrist = bone_array[i]; + } + if (bone_array[i].getName().equals("右手首")) { + this.m_rightWrist = bone_array[i]; + } + if (bone_array[i].getName().equals("左ひじ")) { + this.m_leftElbow = bone_array[i]; + } + if (bone_array[i].getName().equals("右ひじ")) { + this.m_rightElbow = bone_array[i]; + } + if (bone_array[i].getName().equals("左足")) { + this.m_leftLeg = bone_array[i]; + } + if (bone_array[i].getName().equals("右足")) { + this.m_rightLeg = bone_array[i]; + } + if (bone_array[i].getName().equals("左足首")) { + this.m_leftAnkle = bone_array[i]; + } + if (bone_array[i].getName().equals("右足首")) { + this.m_rightAnkle = bone_array[i]; + } + if (bone_array[i].getName().equals("左つま先")) { + this.m_leftToe = bone_array[i]; + } + if (bone_array[i].getName().equals("右つま先")) { + this.m_rightToe = bone_array[i]; + } + if (bone_array[i].getName().equals("左ひざ")) { + this.m_leftKnee = bone_array[i]; + } + if (bone_array[i].getName().equals("右ひざ")) { + this.m_rightKnee = bone_array[i]; + } + if (bone_array[i].getName().equals("左目")) { + this.m_leftEyeDestination = bone_array[i]; + } + if (bone_array[i].getName().equals("右目先")) { + this.m_rightEyeDestination = bone_array[i]; + } + if (bone_array[i].getName().equals("左足IK")) { + this.m_leftFootIK = bone_array[i]; + } + if (bone_array[i].getName().equals("右足IK先")) { + this.m_rightFootIK = bone_array[i]; + } + if (bone_array[i].getName().equals("センター先")) { + this.m_centerBone = bone_array[i]; + } + } + // PMD/VMDが揃った? + if (this._ref_vmd_motion != null) { + makeBoneFaceList(); + } + return; + } + + public void setVmd(MmdVmdMotion_BasicClass i_vmd_model) throws MmdException { + this._ref_vmd_motion = i_vmd_model; + // 操作対象ボーンのポインタを設定する + MotionData[] pMotionDataList = i_vmd_model.refMotionDataArray(); + this.m_ppBoneList = new PmdBone[pMotionDataList.length]; + // 操作対象表情のポインタを設定する + FaceData[] pFaceDataList = i_vmd_model.refFaceDataArray(); + this.m_ppFaceList = new PmdFace[pFaceDataList.length]; + // PMD/VMDが揃った? + if (this._ref_pmd_model != null) { + makeBoneFaceList(); + } + return; + } + + private void makeBoneFaceList() { + MmdPmdModel_BasicClass pmd_model = this._ref_pmd_model; + MmdVmdMotion_BasicClass vmd_model = this._ref_vmd_motion; + + // 操作対象ボーンのポインタを設定する + MotionData[] pMotionDataList = vmd_model.refMotionDataArray(); + this.m_ppBoneList = new PmdBone[pMotionDataList.length]; + for (int i = 0; i < pMotionDataList.length; i++) { + this.m_ppBoneList[i] = pmd_model.getBoneByName(pMotionDataList[i].szBoneName); + } + // 操作対象表情のポインタを設定する + FaceData[] pFaceDataList = vmd_model.refFaceDataArray(); + this.m_ppFaceList = new PmdFace[pFaceDataList.length]; + for (int i = 0; i < pFaceDataList.length; i++) { + this.m_ppFaceList[i] = pmd_model.getFaceByName(pFaceDataList[i].szFaceName); + } + return; + } + + /** + * VMDの再生時間長を返します。 + * + * @return + * ms単位の再生時間 + */ + public float getTimeLength() { + return (float) (this._ref_vmd_motion.getMaxFrame() * (100.0 / 3)); + } + + /** + * 指定した時刻のモーションに更新します。 + * + * @param i_position_in_msec + * モーションの先頭からの時刻をms単位で指定します。 + * @throws MmdException + */ + public void updateMotion(float i_position_in_msec) throws MmdException { + final PmdIK[] ik_array = this._ref_pmd_model.getIKArray(); + final PmdBone[] bone_array = this._ref_pmd_model.getBoneArray(); + assert i_position_in_msec >= 0; + // 描画するフレームを計算する。 + float frame = (float) (i_position_in_msec / (100.0 / 3)); + // 範囲外を除外 + if (frame > this._ref_vmd_motion.getMaxFrame()) { + frame = this._ref_vmd_motion.getMaxFrame(); + } + this.updateFace(frame); + + // モーション更新 + // this.updateBone(frame); + + // ボーン行列の更新 + for (int i = 0; i < bone_array.length; i++) { + bone_array[i].updateMatrix(); + } + + // IKの更新 + for (int i = 0; i < ik_array.length; i++) { + ik_array[i].update(); + } + for (int i = 0; i < bone_array.length; i++) { + bone_array[i].updateMatrix(); + } + // Lookme! + if (this._lookme_enabled) { + this.manualUpdateNeckBone();// updateNeckBone(); + } + // + // スキニング用行列の更新 + for (int i = 0; i < bone_array.length; i++) { + bone_array[i].updateSkinningMat(this._skinning_mat[i]); + } + this.onUpdateSkinningMatrix(this._skinning_mat); + return; + } + + public void update() throws MmdException { + final PmdIK[] ik_array = this._ref_pmd_model.getIKArray(); + final PmdBone[] bone_array = this._ref_pmd_model.getBoneArray(); + for (int i = 0; i < ik_array.length; i++) { + // ik_array[i].update(); + } + for (int i = 0; i < bone_array.length; i++) { + bone_array[i].updateMatrix(); + } + for (int i = 0; i < bone_array.length; i++) { + bone_array[i].updateSkinningMat(this._skinning_mat[i]); + } + this.onUpdateSkinningMatrix(this._skinning_mat); + } + + protected void onUpdateSkinningMatrix(MmdMatrix[] i_skinning_mat) throws MmdException { + throw new MmdException("Must be override onUpdateSkinningMatrix."); + } + + public void setLookVector(float i_x, float i_y, float i_z) { + this._looktarget.x = i_x; + this._looktarget.y = i_y; + this._looktarget.z = i_z; + } + + public void lookMeEnable(boolean i_enable) { + this._lookme_enabled = i_enable; + } + + private MmdVector3 _looktarget = new MmdVector3(); + private boolean _lookme_enabled = false; + + /** + * look me + * + * @param pvec3LookTarget + */ + private void updateNeckBone() { + if (this.m_pNeckBone == null) { + return; + } + this.m_pNeckBone.lookAt(this._looktarget); + + PmdBone[] bone_array = this._ref_pmd_model.getBoneArray(); + int i; + for (i = 0; i < bone_array.length; i++) { + if (this.m_pNeckBone == bone_array[i]) { + break; + } + } + for (; i < bone_array.length; i++) { + bone_array[i].updateMatrix(); + } + return; + } + + public void manualUpdateNeckBone() { + if (this.m_pNeckBone == null) { + return; + } + + PmdBone[] bone_array = this._ref_pmd_model.getBoneArray(); + int i; + for (i = 0; i < bone_array.length; i++) { + // if (this.m_pNeckBone == bone_array[i]) { + // break; + // } + // } + // for (; i < bone_array.length; i++) { + bone_array[i].updateMatrix(); + } + return; + } + + private void updateBone(float i_frame) throws MmdException { + // --------------------------------------------------------- + // 指定フレームのデータでボーンを動かす + final PmdBone[] ppBone = this.m_ppBoneList; + + MotionData[] pMotionDataList = _ref_vmd_motion.refMotionDataArray(); + for (int i = 0; i < pMotionDataList.length; i++) { + if (ppBone[i] == null) { + continue; + } + pMotionDataList[i].getMotionPosRot(i_frame, ppBone[i]); + // ppBone[i].m_vec3Position.setValue(vec3Position); + // 補間あり + // Vector3Lerp( &((*pBone)->m_vec3Position), + // &((*pBone)->m_vec3Position), &vec3Position, fLerpValue ); + // QuaternionSlerp( &((*pBone)->m_vec4Rotate), + // &((*pBone)->m_vec4Rotate), &vec4Rotate, fLerpValue ); + } + return; + } + + /** + * 指定フレームのデータで表情を変形する + * + * @param i_frame + * @throws MmdException + */ + private void updateFace(float i_frame) throws MmdException { + final MmdVector3[] position_array = this._ref_pmd_model.getPositionArray(); + PmdFace[] ppFace = this.m_ppFaceList; + FaceData[] pFaceDataList = _ref_vmd_motion.refFaceDataArray(); + for (int i = 0; i < pFaceDataList.length; i++) { + final float fFaceRate = getFaceRate(pFaceDataList[i], i_frame); + if (ppFace[i] == null) { + continue; + } + if (fFaceRate == 1.0f) { + ppFace[i].setFace(position_array); + } else if (0.001f < fFaceRate) { + ppFace[i].blendFace(position_array, fFaceRate); + } + } + return; + } + + private float getFaceRate(FaceData pFaceData, float fFrame) { + int i; + int ulNumKeyFrame = pFaceData.ulNumKeyFrames; + + // 最終フレームを過ぎていた場合 + if (fFrame > pFaceData.pKeyFrames[ulNumKeyFrame - 1].fFrameNo) { + fFrame = pFaceData.pKeyFrames[ulNumKeyFrame - 1].fFrameNo; + } + + // 現在の時間がどのキー近辺にあるか + for (i = 0; i < ulNumKeyFrame; i++) { + if (fFrame <= pFaceData.pKeyFrames[i].fFrameNo) { + break; + } + } + + // 前後のキーを設定 + int lKey0 = i - 1; + int lKey1 = i; + + if (lKey0 <= 0) { + lKey0 = 0; + } + if (i == ulNumKeyFrame) { + lKey1 = ulNumKeyFrame - 1; + } + + // 前後のキーの時間 + float fTime0 = pFaceData.pKeyFrames[lKey0].fFrameNo; + float fTime1 = pFaceData.pKeyFrames[lKey1].fFrameNo; + + // 前後のキーの間でどの位置にいるか + float fLerpValue; + if (lKey0 != lKey1) { + fLerpValue = (fFrame - fTime0) / (fTime1 - fTime0); + return (pFaceData.pKeyFrames[lKey0].fRate * (1.0f - fLerpValue)) + + (pFaceData.pKeyFrames[lKey1].fRate * fLerpValue); + } else { + return pFaceData.pKeyFrames[lKey0].fRate; + } + } + +} diff --git a/src/jp/nyatla/nymmd/MmdMotionPlayerGL2.java b/src/jp/nyatla/nymmd/MmdMotionPlayerGL2.java new file mode 100644 index 0000000..c2f2882 --- /dev/null +++ b/src/jp/nyatla/nymmd/MmdMotionPlayerGL2.java @@ -0,0 +1,434 @@ +package jp.nyatla.nymmd; + +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; +import java.util.ArrayList; +import java.util.Vector; + +import javax.imageio.ImageIO; +import javax.media.opengl.GL; +import javax.media.opengl.GL2; +import javax.media.opengl.GLContext; + +import com.jogamp.opengl.util.texture.Texture; + +import ru.olamedia.olacraft.game.Game; +import ru.olamedia.texture.TextureManager; + +import jp.nyatla.nymmd.core.PmdBone; +import jp.nyatla.nymmd.types.*; + +public class MmdMotionPlayerGL2 extends MmdMotionPlayer { + private float minY = Float.MAX_VALUE; + private float maxY = Float.MAX_VALUE; + public float minX = Float.MAX_VALUE; + public float maxX = Float.MAX_VALUE; + public float minZ = Float.MAX_VALUE; + public float maxZ = Float.MAX_VALUE; + public float height = 0; + public float offsetX = 0; + public float offsetZ = 0; + + private class TextureList extends ArrayList { + /** + * + */ + private static final long serialVersionUID = 1L; + + class Item { + public int gl_texture_id; + public String file_name; + } + + public void clear() { + final GL2 gl = GLContext.getCurrentGL().getGL2(); + for (TextureList.Item i : this) { + final int[] ids = { i.gl_texture_id }; + gl.glDeleteTextures(1, ids, 0); + } + super.clear(); + } + + private TextureList.Item createTexture(String szFileName, InputStream i_st) throws MmdException { + final GL2 gl = GLContext.getCurrentGL().getGL2(); + String ext = szFileName.substring(szFileName.length() - 3).toUpperCase(); + String format = ext; + if (ext.equals("SPH")) { + format = "BMP"; + } + if (ext.equals("SPA")) { + format = "BMP"; + } + Texture tex = TextureManager.get(szFileName, i_st, format); + tex.setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR); + tex.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR); + if (ext.equals("SPH") || ext.equals("SPA")) { + tex.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE); + tex.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE); + } else { + tex.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, GL2.GL_REPEAT); + tex.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, GL2.GL_REPEAT); + } + TextureList.Item ret = new TextureList.Item(); + ret.file_name = szFileName; + ret.gl_texture_id = tex.getTextureObject(gl); + /* + * toonTexture.setWrap(Texture.WrapAxis.S, + * Texture.WrapMode.EdgeClamp); + * toonTexture.setWrap(Texture.WrapAxis.T, + * Texture.WrapMode.EdgeClamp); + * toonTexture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); + */ + if (ext.equals("SPH")) { + } + if (ext.equals("SPA")) { + } + return ret; + /* + * IntBuffer texid = IntBuffer.allocate(1); + * BufferedImage img; + * try { + * img = ImageIO.read(i_st); + * } catch (Exception e) { + * throw new MmdException("Error while reading " + szFileName); + * } + * gl.glGenTextures(1, texid); + * gl.glBindTexture(GL.GL_TEXTURE_2D, texid.get(0)); + * gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 4); + * + * gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, + * GL.GL_LINEAR); + * gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, + * GL.GL_LINEAR); + * gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, + * GL.GL_REPEAT); + * gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, + * GL.GL_REPEAT); + * // 転写 + * + * int[] rgb_array = img.getRGB(0, 0, img.getWidth(), + * img.getHeight(), null, 0, img.getWidth()); + * gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, img.getWidth(), + * img.getHeight(), 0, GL.GL_RGBA, + * GL.GL_UNSIGNED_BYTE, IntBuffer.wrap(rgb_array)); + * FloatBuffer prio = FloatBuffer.allocate(1); + * prio.put(0, 1.0f); + * gl.glPrioritizeTextures(1, texid, prio); + */ + } + + public int getTexture(String i_name, MmdPmdModel_BasicClass.IResourceProvider i_io) throws MmdException { + try { + for (TextureList.Item i : this) { + if (i.file_name.equalsIgnoreCase(i_name)) { + // 読み込み済みのテクスチャを発見 + return i.gl_texture_id; + } + } + // なければファイルを読み込んでテクスチャ作成 + TextureList.Item ret = this.createTexture(i_name, i_io.getTextureStream(i_name)); + if (ret != null) { + this.add(ret); + return ret.gl_texture_id; + } + } catch (Exception e) { + throw new MmdException(e); + } + // テクスチャ読み込みか作成失敗 + throw new MmdException(); + } + } + + private class Material { + public final float[] color = new float[12];// Diffuse,Specular,Ambientの順 + public float fShininess; + public ShortBuffer indices; + public int ulNumIndices; + public int texture_id; + public int sph_texture_id; + public int unknown; + } + + public MmdMotionPlayerGL2() { + super(); + this._tex_list = new TextureList(); + } + + public void dispose() { + this._tex_list.clear(); + } + + private TextureList _tex_list; + private final MmdMatrix __tmp_matrix = new MmdMatrix(); + private Material[] _materials; + private float[] _fbuf; + private FloatBuffer _pos_array; + private FloatBuffer _nom_array; + private FloatBuffer _tex_array; + + public void setPmd(MmdPmdModel_BasicClass i_pmd_model) throws MmdException { + super.setPmd(i_pmd_model); + + // 確保済みリソースのリセット + this._tex_list.clear(); + // OpenGLResourceの生成 + final int number_of_vertex = i_pmd_model.getNumberOfVertex(); + this._pos_array = makeFloatBuffer(number_of_vertex * 3); + this._nom_array = makeFloatBuffer(number_of_vertex * 3); + this._tex_array = makeFloatBuffer(this._ref_pmd_model.getUvArray().length * 2); + this._fbuf = new float[number_of_vertex * 3 * 2]; + + MmdPmdModel_BasicClass.IResourceProvider tp = i_pmd_model.getResourceProvider(); + + // Material配列の作成 + PmdMaterial[] m = i_pmd_model.getMaterials();// this._ref_materials; + Vector materials = new Vector(); + for (int i = 0; i < m.length; i++) { + final Material new_material = new Material(); + new_material.unknown = m[i].unknown; + // D,A,S[rgba] + m[i].col4Diffuse.getValue(new_material.color, 0); + m[i].col4Ambient.getValue(new_material.color, 4); + m[i].col4Specular.getValue(new_material.color, 8); + new_material.fShininess = m[i].fShininess; + if (m[i].texture_name != null) { + new_material.texture_id = this._tex_list.getTexture(m[i].texture_name, tp); + System.out.println("" + m[i].texture_name); + } else { + new_material.texture_id = 0; + } + if (m[i].sphere_name != null) { + new_material.sph_texture_id = this._tex_list.getTexture(m[i].sphere_name, tp); + System.out.println("" + m[i].sphere_name); + } else { + new_material.sph_texture_id = 0; + } + new_material.indices = ShortBuffer.wrap(m[i].indices); + new_material.ulNumIndices = m[i].indices.length; + materials.add(new_material); + } + this._materials = materials.toArray(new Material[materials.size()]); + // Integer.MAX_VALUE + FloatBuffer tex_array = this._tex_array; + tex_array.position(0); + final MmdTexUV[] texture_uv = this._ref_pmd_model.getUvArray(); + for (int i = 0; i < number_of_vertex; i++) { + tex_array.put(texture_uv[i].u); + tex_array.put(texture_uv[i].v); + } + // find model height + MmdVector3[] org_pos_array = _ref_pmd_model.getPositionArray(); + + for (int i = 0; i < _ref_pmd_model.getNumberOfVertex(); i++) { + MmdVector3 vp = org_pos_array[i]; + if (minY == Float.MAX_VALUE) { + minY = maxY = vp.y; + minX = maxX = vp.x; + minZ = maxZ = vp.z; + } else { + if (vp.y < minY) { + minY = vp.y; + } + if (vp.y > maxY) { + maxY = vp.y; + } + if (vp.x < minX) { + minX = vp.x; + } + if (vp.x > maxX) { + maxX = vp.x; + } + if (vp.z < minZ) { + minZ = vp.z; + } + if (vp.z > maxZ) { + maxZ = vp.z; + } + } + } + height = maxY - minY; + offsetX = minX + (maxX - minX) / 2; + offsetZ = minZ + (maxZ - minZ) / 2; + return; + } + + public void setVmd(MmdVmdMotion_BasicClass i_vmd_model) throws MmdException { + super.setVmd(i_vmd_model); + } + + /** + * この関数はupdateMotionがskinning_matを更新するを呼び出します。 + */ + protected void onUpdateSkinningMatrix(MmdMatrix[] i_skinning_mat) throws MmdException { + MmdVector3 vp; + MmdMatrix mat; + MmdVector3[] org_pos_array = this._ref_pmd_model.getPositionArray(); + MmdVector3[] org_normal_array = this._ref_pmd_model.getNormatArray(); + PmdSkinInfo[] org_skin_info = this._ref_pmd_model.getSkinInfoArray(); + + int number_of_vertex = this._ref_pmd_model.getNumberOfVertex(); + float[] ft = this._fbuf; + int p1 = 0; + int p2 = number_of_vertex * 3; + for (int i = 0; i < this._ref_pmd_model.getNumberOfVertex(); i++) { + PmdSkinInfo info_ptr = org_skin_info[i]; + if (info_ptr.fWeight == 0.0f) { + mat = i_skinning_mat[info_ptr.unBoneNo_1]; + } else if (info_ptr.fWeight >= 0.9999f) { + mat = i_skinning_mat[info_ptr.unBoneNo_0]; + } else { + final MmdMatrix mat0 = i_skinning_mat[info_ptr.unBoneNo_0]; + final MmdMatrix mat1 = i_skinning_mat[info_ptr.unBoneNo_1]; + mat = this.__tmp_matrix; + mat.MatrixLerp(mat0, mat1, info_ptr.fWeight); + } + vp = org_pos_array[i]; + ft[p1++] = ((float) (vp.x * mat.m00 + vp.y * mat.m10 + vp.z * mat.m20 + mat.m30)); + ft[p1++] = ((float) (vp.x * mat.m01 + vp.y * mat.m11 + vp.z * mat.m21 + mat.m31)); + ft[p1++] = ((float) (vp.x * mat.m02 + vp.y * mat.m12 + vp.z * mat.m22 + mat.m32)); + + vp = org_normal_array[i]; + ft[p2++] = ((float) (vp.x * mat.m00 + vp.y * mat.m10 + vp.z * mat.m20)); + ft[p2++] = ((float) (vp.x * mat.m01 + vp.y * mat.m11 + vp.z * mat.m21)); + ft[p2++] = ((float) (vp.x * mat.m02 + vp.y * mat.m12 + vp.z * mat.m22)); + } + this._pos_array.position(0); + this._pos_array.put(ft, 0, number_of_vertex * 3); + this._nom_array.position(0); + this._nom_array.put(ft, number_of_vertex * 3, number_of_vertex * 3); + return; + } + + public void render() throws MmdException { + final GL2 gl = GLContext.getCurrentGL().getGL2(); + // gl.glEnable(GL.GL_CULL_FACE); + gl.glEnable(GL.GL_DEPTH_TEST); + gl.glShadeModel(GL2.GL_SMOOTH); + // gl.glCullFace(GL.GL_FRONT); + gl.glCullFace(GL.GL_BACK); + gl.glEnable(GL2.GL_NORMALIZE); + gl.glEnable(GL2.GL_BLEND); + // GLUtils.texImage2D generates premultiplied-alpha texture. so we use + // GL_ONE instead of GL_ALPHA + gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA); + // gl.glEnableClientState(GL2.GL_COLOR_ARRAY); + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); + gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); + gl.glEnable(GL2.GL_COLOR_MATERIAL); + gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE); + gl.glEnable(GL2.GL_LIGHTING); + gl.glEnable(GL2.GL_LIGHT0); + final float[] diffuseColor = Game.client.getScene().dayTime.getClearColor(); + gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, new float[] { 1.0f, 1.0f, 1.0f }, 0); + gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, diffuseColor, 0);//new float[] { 0f, 0f, 0f } + gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuseColor, 0);// new + // float[] + // { + // 1.0f, + // 1.0f, + // 1.0f + // } + // とりあえずbufferに変換しよう + this._pos_array.position(0); + this._nom_array.position(0); + this._tex_array.position(0); + // とりあえず転写用 + + // 頂点座標、法線、テクスチャ座標の各配列をセット + gl.glVertexPointer(3, GL.GL_FLOAT, 0, this._pos_array); + gl.glNormalPointer(GL.GL_FLOAT, 0, this._nom_array); + gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, this._tex_array); + if (null == this._materials) { + throw new MmdException("no materials"); + } + for (int i = this._materials.length - 1; i >= 0; i--) { + final Material mt_ptr = this._materials[i]; + // マテリアル設定 +// gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE, mt_ptr.color, 0); +// gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, mt_ptr.color, 4); +// gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, mt_ptr.color, 8); +// gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL2.GL_SHININESS, mt_ptr.fShininess); + final float wi = 0.6f; + final float[] color = mt_ptr.color; + gl.glColor4f((color[0] * wi + color[8 + 0]), (color[1] * wi + color[8 + 1]), + (color[2] * wi + color[8 + 2]), color[3]);// * wi + // + + // color[8 + // + + // 3] + // don't cull face that has alpha value 0.99 + if (color[3] < 1) { + gl.glDisable(GL2.GL_CULL_FACE); + } else { + gl.glEnable(GL2.GL_CULL_FACE); + } + // カリング判定:何となくうまくいったから + // if ((0x100 & mt_ptr.unknown) == 0x100) { + // gl.glDisable(GL.GL_CULL_FACE); + // } else { + // gl.glEnable(GL.GL_CULL_FACE); + // } + + if (mt_ptr.texture_id != 0) { + // テクスチャありならBindする + gl.glEnable(GL.GL_TEXTURE_2D); + gl.glBindTexture(GL.GL_TEXTURE_2D, mt_ptr.texture_id); + } else { + // テクスチャなし + gl.glDisable(GL.GL_TEXTURE_2D); + } + if (mt_ptr.ulNumIndices > 0 && mt_ptr.indices.limit() > 0) { + // 頂点インデックスを指定してポリゴン描画 + gl.glDrawElements(GL.GL_TRIANGLES, mt_ptr.ulNumIndices, GL.GL_UNSIGNED_SHORT, mt_ptr.indices); + } + if (mt_ptr.sph_texture_id != 0) { + gl.glEnable(GL.GL_TEXTURE_2D); + gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); + gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); + // gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, + // GL2.GL_REFLECTION_MAP); + + gl.glEnable(GL2.GL_TEXTURE_GEN_S); + gl.glEnable(GL2.GL_TEXTURE_GEN_T); + // gl.glEnable(GL2.GL_TEXTURE_GEN_R); + gl.glBindTexture(GL.GL_TEXTURE_2D, mt_ptr.sph_texture_id); + } + if (mt_ptr.ulNumIndices > 0 && mt_ptr.indices.limit() > 0) { + // 頂点インデックスを指定してポリゴン描画 + gl.glDrawElements(GL.GL_TRIANGLES, mt_ptr.ulNumIndices, GL.GL_UNSIGNED_SHORT, mt_ptr.indices); + } + if (mt_ptr.sph_texture_id != 0) { + gl.glDisable(GL2.GL_TEXTURE_GEN_S); + gl.glDisable(GL2.GL_TEXTURE_GEN_T); + // gl.glDisable(GL2.GL_TEXTURE_GEN_R); + } + + } + // gl.glDisableClientState(GL2.GL_COLOR_ARRAY); + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); + gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY); + return; + } + + private static FloatBuffer makeFloatBuffer(int i_size) { + ByteBuffer bb = ByteBuffer.allocateDirect(i_size * 4); + bb.order(ByteOrder.nativeOrder()); + FloatBuffer fb = bb.asFloatBuffer(); + return fb; + } + + public void reset() { + final PmdBone[] bone_array = _ref_pmd_model.getBoneArray(); + for (int i = 0; i < bone_array.length; i++) { + // bone_array[i].reset(); + } + } + +} diff --git a/src/jp/nyatla/nymmd/MmdPmdModel.java b/src/jp/nyatla/nymmd/MmdPmdModel.java new file mode 100644 index 0000000..e4a4d10 --- /dev/null +++ b/src/jp/nyatla/nymmd/MmdPmdModel.java @@ -0,0 +1,74 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +/** + * ファイルシステムからPMDファイルを読み込むようにラップした{@link MmdPmdModel_BasicClass} + */ +public class MmdPmdModel extends MmdPmdModel_BasicClass { + public MmdPmdModel(String i_pmd_file_path) throws FileNotFoundException, MmdException { + super(new FileInputStream(i_pmd_file_path), new FileResourceProvider(i_pmd_file_path)); + } + + protected MmdPmdModel(InputStream i_stream, IResourceProvider i_res_provider) throws FileNotFoundException, + MmdException { + super(i_stream, i_res_provider); + } + + protected static class FileResourceProvider implements IResourceProvider { + String _dir; + + public FileResourceProvider(String i_pmd_file_path) { + File f = new File(i_pmd_file_path);// pmdのパス + this._dir = (f.getParentFile().getPath()); + } + + public InputStream getTextureStream(String i_name) throws MmdException { + try { + return new FileInputStream(this._dir + File.separator + i_name); + } catch (Exception e) { + throw new MmdException(e); + } + } + } +} diff --git a/src/jp/nyatla/nymmd/MmdPmdModel_BasicClass.java b/src/jp/nyatla/nymmd/MmdPmdModel_BasicClass.java new file mode 100644 index 0000000..9c48c92 --- /dev/null +++ b/src/jp/nyatla/nymmd/MmdPmdModel_BasicClass.java @@ -0,0 +1,317 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd; + +import java.util.*; +import java.io.*; + +import com.jogamp.opengl.util.texture.Texture; + +import jp.nyatla.nymmd.core.*; +import jp.nyatla.nymmd.struct.*; +import jp.nyatla.nymmd.struct.pmd.*; +import jp.nyatla.nymmd.types.*; + +class DataComparator implements java.util.Comparator { + public int compare(PmdIK o1, PmdIK o2) { + return (int) (o1.getSortVal() - o2.getSortVal()); + } +} + +/** + * PmdModelデータの格納クラス。PmdModelに関わるデータを提供します。 + * 抽象関数 getResourceProviderを実装してください。 + */ +public abstract class MmdPmdModel_BasicClass { + private String _name; // モデル名 + private int _number_of_vertex; // 頂点数 + + private PmdFace[] m_pFaceArray; // 表情配列 + private PmdBone[] m_pBoneArray; // ボーン配列 + private PmdIK[] m_pIKArray; // IK配列 + + private MmdVector3[] _position_array; // 座標配列 + private MmdVector3[] _normal_array; // 法線配列 + private MmdTexUV[] _texture_uv; // テクスチャ座標配列 + private PmdSkinInfo[] _skin_info_array; + private PmdMaterial[] _materials; // マテリアル配列 + private IResourceProvider _res_provider; + + public interface IResourceProvider { + public InputStream getTextureStream(String i_name) throws MmdException; + } + + public MmdPmdModel_BasicClass(InputStream i_stream, IResourceProvider i_provider) throws MmdException { + initialize(i_stream); + this._res_provider = i_provider; + return; + } + + public int getNumberOfVertex() { + return this._number_of_vertex; + } + + public PmdMaterial[] getMaterials() { + return this._materials; + } + + public MmdTexUV[] getUvArray() { + return this._texture_uv; + } + + public MmdVector3[] getPositionArray() { + return this._position_array; + } + + public MmdVector3[] getNormatArray() { + return this._normal_array; + } + + public PmdSkinInfo[] getSkinInfoArray() { + return this._skin_info_array; + } + + public PmdFace[] getFaceArray() { + return this.m_pFaceArray; + } + + public PmdBone[] getBoneArray() { + return this.m_pBoneArray; + } + + public PmdIK[] getIKArray() { + return this.m_pIKArray; + } + + public PmdBone getBoneByName(String i_name) { + final PmdBone[] bone_array = this.m_pBoneArray; + for (int i = 0; i < bone_array.length; i++) { + final PmdBone bone = bone_array[i]; + if (bone.getName().equals(i_name)) + return bone; + } + return null; + } + + public PmdFace getFaceByName(String i_name) { + final PmdFace[] face_array = this.m_pFaceArray; + for (int i = 0; i < face_array.length; i++) { + final PmdFace face = face_array[i]; + if (face.getName().equals(i_name)) + return face; + } + return null; + } + + private void initialize(InputStream i_stream) throws MmdException { + DataReader reader = new DataReader(i_stream); + PMD_Header pPMDHeader = new PMD_Header(); + pPMDHeader.read(reader); + if (!pPMDHeader.szMagic.equalsIgnoreCase("PMD")) { + throw new MmdException(); + } + + this._name = pPMDHeader.szName; + + // ----------------------------------------------------- + // 頂点数取得 + this._number_of_vertex = reader.readInt();// + if (this._number_of_vertex < 0) { + throw new MmdException(); + } + + // 頂点配列をコピー + this._position_array = MmdVector3.createArray(this._number_of_vertex); + this._normal_array = MmdVector3.createArray(this._number_of_vertex); + this._texture_uv = MmdTexUV.createArray(this._number_of_vertex); + this._skin_info_array = new PmdSkinInfo[this._number_of_vertex]; + + PMD_Vertex tmp_pmd_vertex = new PMD_Vertex(); + for (int i = 0; i < _number_of_vertex; i++) { + tmp_pmd_vertex.read(reader); + _position_array[i].setValue(tmp_pmd_vertex.vec3Pos); + _normal_array[i].setValue(tmp_pmd_vertex.vec3Normal); + _texture_uv[i].setValue(tmp_pmd_vertex.uvTex); + + this._skin_info_array[i] = new PmdSkinInfo(); + this._skin_info_array[i].fWeight = tmp_pmd_vertex.cbWeight / 100.0f; + this._skin_info_array[i].unBoneNo_0 = tmp_pmd_vertex.unBoneNo[0]; + this._skin_info_array[i].unBoneNo_1 = tmp_pmd_vertex.unBoneNo[1]; + } + // ----------------------------------------------------- + // 頂点インデックス数取得 + short[] indices_array = createIndicesArray(reader); + + // ----------------------------------------------------- + // マテリアル数取得 + int number_of_materials = reader.readInt(); + + // マテリアル配列をコピー + this._materials = new PmdMaterial[number_of_materials]; + + PMD_Material tmp_pmd_material = new PMD_Material(); + + int indices_ptr = 0; + for (int i = 0; i < number_of_materials; i++) { + tmp_pmd_material.read(reader); + PmdMaterial pmdm = new PmdMaterial(); + pmdm.unknown = tmp_pmd_material.unknown; + final int num_of_indices = tmp_pmd_material.ulNumIndices; + + pmdm.indices = new short[num_of_indices]; + System.arraycopy(indices_array, indices_ptr, pmdm.indices, 0, num_of_indices); + indices_ptr += num_of_indices; + + pmdm.col4Diffuse.setValue(tmp_pmd_material.col4Diffuse); + + pmdm.col4Specular.r = tmp_pmd_material.col3Specular.r; + pmdm.col4Specular.g = tmp_pmd_material.col3Specular.g; + pmdm.col4Specular.b = tmp_pmd_material.col3Specular.b; + pmdm.col4Specular.a = 1.0f; + + pmdm.col4Ambient.r = tmp_pmd_material.col3Ambient.r; + pmdm.col4Ambient.g = tmp_pmd_material.col3Ambient.g; + pmdm.col4Ambient.b = tmp_pmd_material.col3Ambient.b; + pmdm.col4Ambient.a = 1.0f; + + pmdm.fShininess = tmp_pmd_material.fShininess; + + pmdm.texture_name = tmp_pmd_material.szTextureFileName; + if (pmdm.texture_name.length() < 1) { + pmdm.texture_name = null; + final int toon = tmp_pmd_material.toon + 1; + String t = "" + toon; + if (toon < 9 && toon > 0) { + t = "0" + t; + } + pmdm.texture_name = "toon" + t + ".bmp"; + } else { + if (pmdm.texture_name.indexOf("*") >= 0) { + pmdm.sphere_name = pmdm.texture_name.substring(pmdm.texture_name.indexOf("*") + 1); + pmdm.texture_name = pmdm.texture_name.substring(0, pmdm.texture_name.indexOf("*")); + } + } + + System.err.println(pmdm.texture_name); + this._materials[i] = pmdm; + + } + + // Boneの読み出し + this.m_pBoneArray = createBoneArray(reader); + // IK配列の読み出し + this.m_pIKArray = createIKArray(reader, this.m_pBoneArray); + // Face配列の読み出し + this.m_pFaceArray = createFaceArray(reader); + + final PmdFace[] face_array = this.m_pFaceArray; + if (face_array != null) { + face_array[0].setFace(this._position_array); + } + return; + } + + private static short[] createIndicesArray(DataReader i_reader) throws MmdException { + int num_of_indeces = i_reader.readInt(); + short[] result = new short[num_of_indeces]; + result = new short[num_of_indeces]; + + // 頂点インデックス配列をコピー + for (int i = 0; i < num_of_indeces; i++) { + result[i] = i_reader.readShort(); + } + return result; + } + + private static PmdBone[] createBoneArray(DataReader i_reader) throws MmdException { + final int number_of_bone = i_reader.readShort(); + PMD_Bone tmp_pmd_bone = new PMD_Bone(); + + PmdBone[] result = new PmdBone[number_of_bone]; + for (int i = 0; i < number_of_bone; i++) { + tmp_pmd_bone.read(i_reader); + // ボーンの親子関係を一緒に読みだすので。 + result[i] = new PmdBone(tmp_pmd_bone, result); + } + for (int i = 0; i < number_of_bone; i++) { + result[i].recalcOffset(); + } + return result; + } + + private static PmdIK[] createIKArray(DataReader i_reader, PmdBone[] i_ref_bone_array) throws MmdException { + final int number_of_ik = i_reader.readShort(); + PMD_IK tmp_pmd_ik = new PMD_IK(); + PmdIK[] result = new PmdIK[number_of_ik]; + // IK配列を作成 + if (number_of_ik > 0) { + + for (int i = 0; i < number_of_ik; i++) { + tmp_pmd_ik.read(i_reader); + result[i] = new PmdIK(tmp_pmd_ik, i_ref_bone_array); + } + Arrays.sort(result, new DataComparator()); + } + return result; + } + + private static PmdFace[] createFaceArray(DataReader i_reader) throws MmdException { + final int number_of_face = i_reader.readShort(); + PMD_FACE tmp_pmd_face = new PMD_FACE(); + PmdFace[] result = new PmdFace[number_of_face]; + + // 表情配列を作成 + if (number_of_face > 0) { + + for (int i = 0; i < number_of_face; i++) { + tmp_pmd_face.read(i_reader); + result[i] = new PmdFace(tmp_pmd_face, result[0]); + } + } + return result; + } + + public String getModelName() { + return this._name; + } + + public IResourceProvider getResourceProvider() { + return this._res_provider; + } + +} diff --git a/src/jp/nyatla/nymmd/MmdVmdMotion.java b/src/jp/nyatla/nymmd/MmdVmdMotion.java new file mode 100644 index 0000000..8f6fdce --- /dev/null +++ b/src/jp/nyatla/nymmd/MmdVmdMotion.java @@ -0,0 +1,55 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +public class MmdVmdMotion extends MmdVmdMotion_BasicClass +{ + public MmdVmdMotion(String i_vmd_file_path) throws FileNotFoundException, MmdException + { + super(new FileInputStream(i_vmd_file_path)); + } + + protected MmdVmdMotion(InputStream i_stream) throws MmdException { + super(i_stream); + } + +} diff --git a/src/jp/nyatla/nymmd/MmdVmdMotion_BasicClass.java b/src/jp/nyatla/nymmd/MmdVmdMotion_BasicClass.java new file mode 100644 index 0000000..75d07b1 --- /dev/null +++ b/src/jp/nyatla/nymmd/MmdVmdMotion_BasicClass.java @@ -0,0 +1,290 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd; + +import java.util.*; + +import java.util.Arrays; +import java.io.*; + + +import jp.nyatla.nymmd.struct.DataReader; +import jp.nyatla.nymmd.struct.vmd.VMD_Face; +import jp.nyatla.nymmd.struct.vmd.VMD_Header; +import jp.nyatla.nymmd.struct.vmd.VMD_Motion; +import jp.nyatla.nymmd.types.*; + +//------------------------------ +//ボーンキーフレームソート用比較関数 +//------------------------------ +class BoneCompare implements java.util.Comparator +{ + public int compare(BoneKeyFrame o1, BoneKeyFrame o2) + { + return (int)(o1.fFrameNo - o2.fFrameNo); + } +} + + +//------------------------------ +//表情キーフレームソート用比較関数 +//------------------------------ +class FaceCompare implements java.util.Comparator +{ + public int compare(FaceKeyFrame o1, FaceKeyFrame o2) + { + return (int)(o1.fFrameNo - o2.fFrameNo); + } +} + +public class MmdVmdMotion_BasicClass +{ + private MotionData[] _motion_data_array; // ボーンごとのキーフレームデータのリスト + private FaceData[] _face_data_array; // 表情ごとのキーフレームデータのリスト + private float _fMaxFrame; // 最後のフレーム番号 + + public MmdVmdMotion_BasicClass(InputStream i_stream) throws MmdException + { + initialize(i_stream); + return; + } + + public MotionData[] refMotionDataArray() + { + return this._motion_data_array; + } + public FaceData[] refFaceDataArray() + { + return this._face_data_array; + } + + public float getMaxFrame() + { + return this._fMaxFrame; + } + + + private boolean initialize(InputStream i_st) throws MmdException + { + + DataReader reader=new DataReader(i_st); + + // ヘッダのチェック + VMD_Header tmp_vmd_header=new VMD_Header(); + tmp_vmd_header.read(reader); + if(!tmp_vmd_header.szHeader.equalsIgnoreCase("Vocaloid Motion Data 0002")) + { + throw new MmdException(); + } + //ボーンと最大フレームを取得 + float[] max_frame=new float[1]; + this._motion_data_array=createMotionDataList(reader,max_frame); + this._fMaxFrame=max_frame[0]; + + //表情と最大フレームを再取得 + this._face_data_array=createFaceDataList(reader,max_frame); + this._fMaxFrame=this._fMaxFrame>max_frame[0]?this._fMaxFrame:max_frame[0]; + + return true; + } + + private static FaceData[] createFaceDataList(DataReader i_reader,float[] o_max_frame) throws MmdException + { + //----------------------------------------------------- + // 表情のキーフレーム数を取得 + Vector result=new Vector(); + int ulNumFaceKeyFrames=i_reader.readInt(); + + //規定フレーム数分表情を読み込み + VMD_Face[] tmp_vmd_face=new VMD_Face[ulNumFaceKeyFrames]; + for(int i=0;i result=new Vector(); + // まずはモーションデータ中のボーンごとのキーフレーム数をカウント + final int ulNumBoneKeyFrames=i_reader.readInt(); + + + //ボーンを指定数読み込み + VMD_Motion[] tmp_vmd_motion=new VMD_Motion[ulNumBoneKeyFrames]; + for(int i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.core; + + +import jp.nyatla.nymmd.struct.pmd.PMD_Bone; +import jp.nyatla.nymmd.types.*; + +public class PmdBone +{ + private String _name; + private final MmdVector3 _pmd_bone_position=new MmdVector3(); + private final MmdVector3 m_vec3Offset=new MmdVector3(); + private final MmdMatrix m_matInvTransform=new MmdMatrix(); // 初期値のボーンを原点に移動させるような行列 + + private PmdBone _parent_bone; + private PmdBone m_pChildBone; + + // 以下は現在の値 + public final MmdMatrix m_matLocal=new MmdMatrix(); + + + //強制public + public final MmdVector3 m_vec3Position=new MmdVector3(); + public final MmdVector4 m_vec4Rotate=new MmdVector4(); + public boolean m_bIKLimitAngle; // IK時に角度制限をするかどうか + //強制public/ + + public String getName() + { + return this._name; + } + + public PmdBone(PMD_Bone pPMDBoneData,PmdBone[] pBoneArray) + { + // ボーン名のコピー + this._name=pPMDBoneData.szName; + + // 位置のコピー + this._pmd_bone_position.setValue(pPMDBoneData.vec3Position); + + // 親ボーンの設定 + if( pPMDBoneData.nParentNo != -1 ) + { + this._parent_bone = pBoneArray[pPMDBoneData.nParentNo]; + if (this._parent_bone != null){ + m_vec3Offset.Vector3Sub(this._pmd_bone_position,this._parent_bone._pmd_bone_position); + }else{ + m_vec3Offset.Vector3Sub(this._pmd_bone_position,new MmdVector3(0,1,0)); + } + }else{ + // 親なし + this._parent_bone=null; + this.m_vec3Offset.setValue(this._pmd_bone_position); + } + + // 子ボーンの設定 + if( pPMDBoneData.nChildNo != -1 ) + { + this.m_pChildBone =pBoneArray[pPMDBoneData.nChildNo]; + } + + this.m_matInvTransform.identity(); + this.m_matInvTransform.m30 = -this._pmd_bone_position.x; + this.m_matInvTransform.m31 = -this._pmd_bone_position.y; + this.m_matInvTransform.m32 = -this._pmd_bone_position.z; + + this.m_bIKLimitAngle = false; + + // 各変数の初期値を設定 + reset(); + } + public void recalcOffset() + { + if(this._parent_bone!=null){ + m_vec3Offset.Vector3Sub(this._pmd_bone_position,this._parent_bone._pmd_bone_position); + } + return; + } + + public void reset() + { + m_vec3Position.x = m_vec3Position.y = m_vec3Position.z = 0.0f; + m_vec4Rotate.x = m_vec4Rotate.y = m_vec4Rotate.z = 0.0f; m_vec4Rotate.w = 1.0f; + + this.m_matLocal.identity(); + this.m_matLocal.m30 = _pmd_bone_position.x; + this.m_matLocal.m31 = _pmd_bone_position.y; + this.m_matLocal.m32 = _pmd_bone_position.z; + } + public void setIKLimitAngle(boolean i_value) + { + this.m_bIKLimitAngle=i_value; + return; + } + + + public void updateSkinningMat(MmdMatrix o_matrix) + { + o_matrix.mul(this.m_matInvTransform,this.m_matLocal); + return; + } + + public void updateMatrix() + { + if(this._parent_bone!=null){ + // クォータニオンと移動値からボーンのローカルマトリックスを作成 + this._mat_tmp1.QuaternionToMatrix(this.m_vec4Rotate ); + this._mat_tmp1.m30 = m_vec3Position.x + m_vec3Offset.x; + this._mat_tmp1.m31 = m_vec3Position.y + m_vec3Offset.y; + this._mat_tmp1.m32 = m_vec3Position.z + m_vec3Offset.z; + // 親があるなら親の回転を受け継ぐ + m_matLocal.mul(this._mat_tmp1,this._parent_bone.m_matLocal); + }else{ + // クォータニオンと移動値からボーンのローカルマトリックスを作成 + this.m_matLocal.QuaternionToMatrix(this.m_vec4Rotate ); + this.m_matLocal.m30 = m_vec3Position.x + m_vec3Offset.x; + this.m_matLocal.m31 = m_vec3Position.y + m_vec3Offset.y; + this.m_matLocal.m32 = m_vec3Position.z + m_vec3Offset.z; + } + return; + } + private final MmdMatrix _mat_tmp1=new MmdMatrix(); + private final MmdMatrix _mat_tmp2=new MmdMatrix(); + private final MmdMatrix _mat_tmp3=new MmdMatrix(); + private final MmdVector3 _lookAt_vec3LocalTgtPosZY=new MmdVector3(); + private final MmdVector3 _lookAt_vec3LocalTgtPosXZ=new MmdVector3(); + private final MmdVector3 _lookAt_vec3Angle=new MmdVector3(); + + + public void lookAt(MmdVector3 pvecTargetPos ) + { + // どうもおかしいので要調整 + final MmdMatrix mat_tmp1=this._mat_tmp1; + final MmdMatrix mat_tmp3=this._mat_tmp3; + final MmdVector3 vec3LocalTgtPosZY=this._lookAt_vec3LocalTgtPosZY; + final MmdVector3 vec3LocalTgtPosXZ=this._lookAt_vec3LocalTgtPosXZ; + + mat_tmp1.identity(); + mat_tmp1.m30 = m_vec3Position.x + m_vec3Offset.x; + mat_tmp1.m31 = m_vec3Position.y + m_vec3Offset.y; + mat_tmp1.m32 = m_vec3Position.z + m_vec3Offset.z; + + if(this._parent_bone!=null) + { + mat_tmp3.inverse(_parent_bone.m_matLocal ); + this._mat_tmp2.mul(mat_tmp1, mat_tmp3 ); + mat_tmp3.inverse(this._mat_tmp2); + vec3LocalTgtPosZY.Vector3Transform(pvecTargetPos, mat_tmp3 ); + }else{ + mat_tmp1.inverse(mat_tmp1); + vec3LocalTgtPosZY.Vector3Transform(pvecTargetPos, mat_tmp1 ); + } + + vec3LocalTgtPosXZ.setValue(vec3LocalTgtPosZY); + vec3LocalTgtPosXZ.y = 0.0f; + vec3LocalTgtPosXZ.Vector3Normalize(vec3LocalTgtPosXZ); + + vec3LocalTgtPosZY.x = 0.0f; + vec3LocalTgtPosZY.Vector3Normalize(vec3LocalTgtPosZY); + + MmdVector3 vec3Angle = this._lookAt_vec3Angle; + vec3Angle.x=vec3Angle.y=vec3Angle.z=0; + + if( vec3LocalTgtPosZY.z > 0.0f ){ + vec3Angle.x = (float)(Math.asin(vec3LocalTgtPosZY.y ) - (20.0*Math.PI/180.0)); + } + if( vec3LocalTgtPosXZ.x < 0.0f ){ + vec3Angle.y = (float)Math.acos(vec3LocalTgtPosXZ.z ); + }else{ + vec3Angle.y = (float)-Math.acos(vec3LocalTgtPosXZ.z ); + } + + if( vec3Angle.x < (-25.0*Math.PI/180.0) ){ + vec3Angle.x = (float)(-25.0*Math.PI/180.0); + } + if( (45.0f*Math.PI/180.0) < vec3Angle.x ) { + vec3Angle.x = (float)( 45.0*Math.PI/180.0); + } + if( vec3Angle.y < (-80.0*Math.PI/180.0) ){ + vec3Angle.y = (float)(-80.0*Math.PI/180.0); + } + if((80.0*Math.PI/180.0) < vec3Angle.y ){ + vec3Angle.y =(float)( 80.0*Math.PI/180.0); + } + + m_vec4Rotate.QuaternionCreateEuler(vec3Angle); + } +} diff --git a/src/jp/nyatla/nymmd/core/PmdFace.java b/src/jp/nyatla/nymmd/core/PmdFace.java new file mode 100644 index 0000000..033e1a3 --- /dev/null +++ b/src/jp/nyatla/nymmd/core/PmdFace.java @@ -0,0 +1,108 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.core; + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.pmd.PMD_FACE; +import jp.nyatla.nymmd.struct.pmd.PMD_FACE_VTX; +import jp.nyatla.nymmd.types.MmdVector3; + +public class PmdFace +{ + private String _name; + + private PMD_FACE_VTX[] _face_vertex; // 表情頂点データ + + public PmdFace(PMD_FACE pPMDFaceData, PmdFace pPMDFaceBase) + { + // 表情名のコピー + this._name = pPMDFaceData.szName; + + // 表情頂点データのコピー + final int number_of_vertex = pPMDFaceData.ulNumVertices; + + this._face_vertex = PMD_FACE_VTX.createArray(number_of_vertex); + for (int i = 0; i < this._face_vertex.length; i++) { + this._face_vertex[i].setValue(pPMDFaceData.pVertices[i]); + } + // baseとの相対インデックスを絶対インデックスに変換 + if (pPMDFaceBase != null) { + final PMD_FACE_VTX[] vertex_array = this._face_vertex; + for (int i =this._face_vertex.length-1; i>=0 ; i--) { + final PMD_FACE_VTX vertex = vertex_array[i]; + vertex.vec3Pos.Vector3Add(pPMDFaceBase._face_vertex[vertex.ulIndex].vec3Pos, vertex.vec3Pos); + vertex.ulIndex = pPMDFaceBase._face_vertex[vertex.ulIndex].ulIndex; + } + } + return; + } + + public void setFace(MmdVector3[] pvec3Vertices) throws MmdException + { + if (this._face_vertex == null) { + throw new MmdException(); + } + + final PMD_FACE_VTX[] vertex_array = this._face_vertex; + for (int i = vertex_array.length-1; i>=0 ; i--) { + final PMD_FACE_VTX vertex = vertex_array[i]; + pvec3Vertices[vertex.ulIndex].setValue(vertex.vec3Pos); + } + return; + } + + public void blendFace(MmdVector3[] pvec3Vertices, float fRate) throws MmdException + { + if (this._face_vertex == null) { + throw new MmdException(); + } + + PMD_FACE_VTX[] vertex_array = this._face_vertex; + for (int i = vertex_array.length-1; i >=0 ; i--) { + final PMD_FACE_VTX vertex = vertex_array[i]; + MmdVector3 vec=pvec3Vertices[vertex.ulIndex]; + vec.Vector3Lerp(vec, vertex.vec3Pos, fRate); + } + return; + } + + public String getName() + { + return this._name; + } +} diff --git a/src/jp/nyatla/nymmd/core/PmdIK.java b/src/jp/nyatla/nymmd/core/PmdIK.java new file mode 100644 index 0000000..5135858 --- /dev/null +++ b/src/jp/nyatla/nymmd/core/PmdIK.java @@ -0,0 +1,194 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.core; + +import jp.nyatla.nymmd.struct.pmd.PMD_IK; +import jp.nyatla.nymmd.types.*; + +public class PmdIK +{ + private PmdBone m_pTargetBone; // IKターゲットボーン + private PmdBone m_pEffBone; // IK先端ボーン + + private int m_unCount; + private double _fact; + private int m_nSortVal; + + private PmdBone[] m_ppBoneList; // IKを構成するボーンの配列 + + private final MmdVector3[] _work_vector3=MmdVector3.createArray(4); + private final MmdVector4 _work_vector4=new MmdVector4(); + public PmdIK(PMD_IK pPMDIKData, PmdBone[] i_ref_bone_array) + { + // IKターゲットボーン + this.m_pTargetBone = i_ref_bone_array[pPMDIKData.nTargetNo]; + + // IK先端ボーン + this.m_pEffBone =i_ref_bone_array[pPMDIKData.nEffNo]; + + this.m_unCount = pPMDIKData.unCount; + this._fact =pPMDIKData.fFact * Math.PI; + this.m_nSortVal = pPMDIKData.punLinkNo[0]; + + // IKリンク配列の作成 + final int number_of_ik_link=pPMDIKData.cbNumLink; + + this.m_ppBoneList = new PmdBone[number_of_ik_link];//参照 + for(int i = 0 ; i < number_of_ik_link ; i++ ) + { + this.m_ppBoneList[i] =i_ref_bone_array[ pPMDIKData.punLinkNo[i] ]; // ボーン番号は降順で格納されている + if(this.m_ppBoneList[i].getName().equals("左ひざ") || this.m_ppBoneList[i].getName().equals("右ひざ")) + { + this.m_ppBoneList[i].setIKLimitAngle(true); + } + } + } + private void limitAngle( MmdVector4 pvec4Out,MmdVector4 pvec4Src ) + { + final MmdVector3 vec3Angle=this._work_vector3[0]; + + // XYZ軸回転の取得 + vec3Angle.QuaternionToEuler(pvec4Src); + + // 角度制限 + if( vec3Angle.x <-Math.PI ){ + vec3Angle.x = (float)-Math.PI; + } + if( -0.002f < vec3Angle.x ){ + vec3Angle.x = -0.002f; + } + vec3Angle.y = 0.0f; + vec3Angle.z = 0.0f; + + // XYZ軸回転からクォータニオンへ + pvec4Out.QuaternionCreateEuler(vec3Angle); + return; + } + + public int getSortVal() + { + return this.m_nSortVal; + } + private final MmdMatrix __update_matInvBone=new MmdMatrix(); + public void update() + { + final MmdMatrix matInvBone=this.__update_matInvBone; + + + final MmdVector3 vec3EffPos=this._work_vector3[0]; + final MmdVector3 vec3TargetPos=this._work_vector3[1]; + final MmdVector3 vec3Diff=this._work_vector3[2]; + final MmdVector3 vec3RotAxis=this._work_vector3[3]; + final MmdVector4 vec4RotQuat=this._work_vector4; + + //事前に全Boneをupdateしてるなら、このコードは要らない? + for(int i =this.m_ppBoneList.length - 1 ; i >= 0 ; i-- ){ + this.m_ppBoneList[i].updateMatrix(); + } + m_pEffBone.updateMatrix(); + + for(int it = this.m_unCount-1 ; it >=0 ; it--) + { + for(int j = 0 ; j < this.m_ppBoneList.length ; j++ ) + { + // エフェクタの位置の取得 + + // ワールド座標系から注目ノードの局所(ローカル)座標系への変換 + matInvBone.inverse(m_ppBoneList[j].m_matLocal ); + + // エフェクタ,到達目標のローカル位置 + vec3EffPos.Vector3Transform(m_pEffBone.m_matLocal, matInvBone ); + vec3TargetPos.Vector3Transform(m_pTargetBone.m_matLocal, matInvBone); + + // 十分近ければ終了 + + vec3Diff.Vector3Sub(vec3EffPos,vec3TargetPos); + if(vec3Diff.Vector3DotProduct(vec3Diff) < 0.0000001f ){ + return; + } + + // (1) 基準関節→エフェクタ位置への方向ベクトル + vec3EffPos.Vector3Normalize(vec3EffPos); + + // (2) 基準関節→目標位置への方向ベクトル + vec3TargetPos.Vector3Normalize(vec3TargetPos); + + // ベクトル (1) を (2) に一致させるための最短回転量(Axis-Angle) + // + // 回転角 + double fRotAngle = Math.acos(vec3EffPos.Vector3DotProduct(vec3TargetPos ) ); + + if( 0.00000001 < Math.abs( fRotAngle)) + { + if( fRotAngle < -this._fact ){ + fRotAngle = -this._fact; + }else if( this._fact < fRotAngle ){ + fRotAngle = this._fact; + } + + // 回転軸 + + vec3RotAxis.Vector3CrossProduct(vec3EffPos,vec3TargetPos); + if( vec3RotAxis.Vector3DotProduct(vec3RotAxis) < 0.0000001 ){ + continue; + } + + vec3RotAxis.Vector3Normalize(vec3RotAxis); + + // 関節回転量の補正 + vec4RotQuat.QuaternionCreateAxis(vec3RotAxis,fRotAngle); + + if( m_ppBoneList[j].m_bIKLimitAngle){ + limitAngle(vec4RotQuat,vec4RotQuat ); + } + + vec4RotQuat.QuaternionNormalize(vec4RotQuat); + + m_ppBoneList[j].m_vec4Rotate.QuaternionMultiply(m_ppBoneList[j].m_vec4Rotate,vec4RotQuat); + m_ppBoneList[j].m_vec4Rotate.QuaternionNormalize(m_ppBoneList[j].m_vec4Rotate); + + for(int i = j ; i >= 0 ; i-- ){ + m_ppBoneList[i].updateMatrix(); + } + m_pEffBone.updateMatrix(); + } + } + } + return; + } +} diff --git a/src/jp/nyatla/nymmd/struct/DataReader.java b/src/jp/nyatla/nymmd/struct/DataReader.java new file mode 100644 index 0000000..fd0f86e --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/DataReader.java @@ -0,0 +1,120 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct; + +import java.io.*; +import java.nio.*; + +import jp.nyatla.nymmd.*; + +public class DataReader +{ + private ByteBuffer _buf; + public DataReader(InputStream i_stream) throws MmdException + { + try{ + //コレなんとかしよう。C#のBinaryReaderみたいに振舞うように。 + int file_len=i_stream.available(); + if(file_len<1){ + file_len=2*1024*1024; + } + byte[] buf=new byte[file_len]; + int buf_len=i_stream.read(buf,0,file_len); + this._buf=ByteBuffer.wrap(buf,0,buf_len); + this._buf.order(ByteOrder.LITTLE_ENDIAN); + return; + }catch(Exception e){ + throw new MmdException(); + } + } + public int readByte() + { + return this._buf.get(); + } + public int read() + { + int v=this._buf.get(); + return (v>=0)?v:0xff+v;//unsignedに戻す + } + public short readShort() + { + return this._buf.getShort(); + } + public int readUnsignedShort() + { + int v=this._buf.getShort(); + return (v>=0)?v:0xffff+v;//unsignedに戻す + } + public int readInt() + { + return this._buf.getInt(); + } + public float readFloat() + { + return this._buf.getFloat(); + } + public double readDouble() + { + return this._buf.getDouble(); + } + public String readAscii(int i_length) throws MmdException + { + try{ + String ret=""; + int len=0; + byte[] tmp=new byte[i_length]; + int i; + for(i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct; + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.types.*; + +public class StructReader +{ + public static void read(MmdColor4 i_dest,DataReader i_reader) throws MmdException + { + i_dest.r=i_reader.readFloat(); + i_dest.g=i_reader.readFloat(); + i_dest.b=i_reader.readFloat(); + i_dest.a=i_reader.readFloat(); + return; + } + public static void read(MmdColor3 i_dest,DataReader i_reader) throws MmdException + { + i_dest.r=i_reader.readFloat(); + i_dest.g=i_reader.readFloat(); + i_dest.b=i_reader.readFloat(); + return; + } + public static void read(MmdTexUV i_dest,DataReader i_reader) throws MmdException + { + i_dest.u=i_reader.readFloat(); + i_dest.v=i_reader.readFloat(); + return; + } + public static void read(MmdVector3 i_dest,DataReader i_reader) throws MmdException + { + i_dest.x=i_reader.readFloat(); + i_dest.y=i_reader.readFloat(); + i_dest.z=i_reader.readFloat(); + return; + } + public static void read(MmdVector4 i_dest,DataReader i_reader) throws MmdException + { + i_dest.x=i_reader.readFloat(); + i_dest.y=i_reader.readFloat(); + i_dest.z=i_reader.readFloat(); + i_dest.w=i_reader.readFloat(); + return; + } +} diff --git a/src/jp/nyatla/nymmd/struct/StructType.java b/src/jp/nyatla/nymmd/struct/StructType.java new file mode 100644 index 0000000..27f19fa --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/StructType.java @@ -0,0 +1,48 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct; + + + +import jp.nyatla.nymmd.MmdException; + +public interface StructType +{ + public void read(DataReader i_reader) throws MmdException; + +} diff --git a/src/jp/nyatla/nymmd/struct/pmd/PMD_Bone.java b/src/jp/nyatla/nymmd/struct/pmd/PMD_Bone.java new file mode 100644 index 0000000..cb949d5 --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/pmd/PMD_Bone.java @@ -0,0 +1,66 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.pmd; + + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.*; +import jp.nyatla.nymmd.types.MmdVector3; + +public class PMD_Bone implements StructType +{ + public String szName; // ボーン名 (0x00 終端,余白は 0xFD) + public int nParentNo; // 親ボーン番号 (なければ -1) + public int nChildNo; // 子ボーン番号 + public int cbKind; // ボーンの種類 + public int unIKTarget; // IK時のターゲットボーン + public final MmdVector3 vec3Position=new MmdVector3(); // モデル原点からの位置 + + public void read(DataReader i_reader) throws MmdException + { + //szName + this.szName=i_reader.readAscii(20); + this.nParentNo=i_reader.readShort(); + this.nChildNo=i_reader.readShort(); + this.cbKind=i_reader.readByte(); + this.unIKTarget=i_reader.readShort(); + StructReader.read(this.vec3Position, i_reader); + return; + } +} diff --git a/src/jp/nyatla/nymmd/struct/pmd/PMD_FACE.java b/src/jp/nyatla/nymmd/struct/pmd/PMD_FACE.java new file mode 100644 index 0000000..e2c4f5c --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/pmd/PMD_FACE.java @@ -0,0 +1,74 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.pmd; + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.*; + +public class PMD_FACE implements StructType +{ + public String szName; // 表情名 (0x00 終端,余白は 0xFD) + public int ulNumVertices; // 表情頂点数 + public int cbType; // 分類 + public PMD_FACE_VTX [] pVertices=PMD_FACE_VTX.createArray(64);// 表情頂点データ + public void read(DataReader i_reader) throws MmdException + { + int i; + //szName + this.szName=i_reader.readAscii(20); + this.ulNumVertices=i_reader.readInt(); + this.cbType=i_reader.read(); + //必要な数だけ配列を確保しなおす。 + if(this.ulNumVertices>this.pVertices.length){ + this.pVertices=PMD_FACE_VTX.createArray(this.ulNumVertices); + } + for(i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.pmd; + + +import jp.nyatla.nymmd.*; +import jp.nyatla.nymmd.struct.*; +import jp.nyatla.nymmd.types.MmdVector3; +public class PMD_FACE_VTX implements StructType +{ + public int ulIndex; + public MmdVector3 vec3Pos=new MmdVector3(); + public void read(DataReader i_reader) throws MmdException + { + this.ulIndex=i_reader.readInt(); + StructReader.read(this.vec3Pos, i_reader); + return; + } + public static PMD_FACE_VTX[] createArray(int i_length) + { + PMD_FACE_VTX[] ret=new PMD_FACE_VTX[i_length]; + for(int i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.pmd; + +import jp.nyatla.nymmd.*; +import jp.nyatla.nymmd.struct.*; + +public class PMD_Header implements StructType +{ + public final static int SIZE_OF_STRUCT=3+4+20+256; + public String szMagic; + public float fVersion; + public String szName; + public String szComment; + + public void read(DataReader i_reader) throws MmdException + { + this.szMagic=i_reader.readAscii(3); + // + this.fVersion=i_reader.readFloat(); + //szName + this.szName=i_reader.readAscii(20); + + //szComment + this.szComment=i_reader.readAscii(256); + return; + } +/* + char szMagic[3]; // "Pmd" + float fVersion; // PMDバージョン番号 + char szName[20]; // モデル名 + char szComment[256]; // コメント(著作権表示など) +*/ +} diff --git a/src/jp/nyatla/nymmd/struct/pmd/PMD_IK.java b/src/jp/nyatla/nymmd/struct/pmd/PMD_IK.java new file mode 100644 index 0000000..d5fceea --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/pmd/PMD_IK.java @@ -0,0 +1,83 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.pmd; + + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.DataReader; +import jp.nyatla.nymmd.struct.StructType; + +public class PMD_IK implements StructType +{ + public int nTargetNo; // IKターゲットボーン番号 + public int nEffNo; // IK先端ボーン番号 + public int cbNumLink; // IKを構成するボーンの数 + public int unCount; + public float fFact; + public int[] punLinkNo;// IKを構成するボーンの配列(可変長配列) + + public void read(DataReader i_reader) throws MmdException + { + this.nTargetNo=i_reader.readShort(); + this.nEffNo=i_reader.readShort(); + this.cbNumLink=i_reader.read(); + this.unCount=i_reader.readUnsignedShort(); + this.fFact=i_reader.readFloat(); + //必要な数だけ配列を確保しなおす。 + this.punLinkNo=new int[this.cbNumLink]; + for(int i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.pmd; + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.DataReader; +import jp.nyatla.nymmd.struct.StructReader; +import jp.nyatla.nymmd.struct.StructType; +import jp.nyatla.nymmd.types.MmdColor3; +import jp.nyatla.nymmd.types.MmdColor4; + +public class PMD_Material implements StructType { + public final MmdColor4 col4Diffuse = new MmdColor4(); + public float fShininess; + public final MmdColor3 col3Specular = new MmdColor3(); + public final MmdColor3 col3Ambient = new MmdColor3(); + public int unknown; + public int toon; + public int edgeFlag; + public int ulNumIndices; // この材質に対応する頂点数 + public String szTextureFileName; // テクスチャファイル名 + public String szSphFileName; // テクスチャファイル名 + + public void read(DataReader i_reader) throws MmdException { + StructReader.read(this.col4Diffuse, i_reader); + this.fShininess = i_reader.readFloat(); + StructReader.read(this.col3Specular, i_reader); + StructReader.read(this.col3Ambient, i_reader); + toon = i_reader.readByte(); + edgeFlag = i_reader.readByte(); + // this.unknown = i_reader.readUnsignedShort(); + this.ulNumIndices = i_reader.readInt(); + this.szTextureFileName = i_reader.readAscii(20); + return; + } + /* + * Color4 col4Diffuse; + * float fShininess; + * Color3 col3Specular, + * col3Ambient; + * + * unsigned short unknown; + * unsigned long ulNumIndices; // この材質に対応する頂点数 + * char szTextureFileName[20]; // テクスチャファイル名 + */ + +} diff --git a/src/jp/nyatla/nymmd/struct/pmd/PMD_Vertex.java b/src/jp/nyatla/nymmd/struct/pmd/PMD_Vertex.java new file mode 100644 index 0000000..efc425d --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/pmd/PMD_Vertex.java @@ -0,0 +1,78 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.pmd; + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.DataReader; +import jp.nyatla.nymmd.struct.StructReader; +import jp.nyatla.nymmd.struct.StructType; +import jp.nyatla.nymmd.types.MmdTexUV; +import jp.nyatla.nymmd.types.MmdVector3; + +public class PMD_Vertex implements StructType +{ + public MmdVector3 vec3Pos=new MmdVector3(); // 座標 + public MmdVector3 vec3Normal=new MmdVector3(); // 法線ベクトル + public MmdTexUV uvTex=new MmdTexUV(); // テクスチャ座標 + + public int[] unBoneNo=new int[2]; // ボーン番号 + public int cbWeight; // ブレンドの重み (0~100%) + public int cbEdge; // エッジフラグ +/* + Vector3 vec3Pos; // 座標 + Vector3 vec3Normal; // 法線ベクトル + TexUV uvTex; // テクスチャ座標 + + unsigned short unBoneNo[2]; // ボーン番号 + unsigned char cbWeight; // ブレンドの重み (0~100%) + unsigned char cbEdge; // エッジフラグ +*/ + public void read(DataReader i_reader) throws MmdException + { + StructReader.read(this.vec3Pos, i_reader); + StructReader.read(this.vec3Normal, i_reader); + StructReader.read(this.uvTex, i_reader); + this.unBoneNo[0]=i_reader.readUnsignedShort(); + this.unBoneNo[1]=i_reader.readUnsignedShort(); + this.cbWeight=i_reader.read(); + this.cbEdge=i_reader.read(); + return; + } + +} diff --git a/src/jp/nyatla/nymmd/struct/vmd/VMD_Face.java b/src/jp/nyatla/nymmd/struct/vmd/VMD_Face.java new file mode 100644 index 0000000..d78ddbe --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/vmd/VMD_Face.java @@ -0,0 +1,60 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.vmd; + + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.DataReader; +import jp.nyatla.nymmd.struct.StructType; + +public class VMD_Face implements StructType +{ + public String szFaceName; + public long ulFrameNo; + public float fFactor; + public void read(DataReader i_reader) throws MmdException + { + //szFaceName + this.szFaceName=i_reader.readAscii(15); + this.ulFrameNo=i_reader.readInt(); + this.fFactor=i_reader.readFloat(); + return; + } + +} diff --git a/src/jp/nyatla/nymmd/struct/vmd/VMD_Header.java b/src/jp/nyatla/nymmd/struct/vmd/VMD_Header.java new file mode 100644 index 0000000..5a61aa7 --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/vmd/VMD_Header.java @@ -0,0 +1,63 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.vmd; + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.DataReader; +import jp.nyatla.nymmd.struct.StructType; + +public class VMD_Header implements StructType +{ + public String szHeader; + public String szModelName; + public void read(DataReader i_reader) throws MmdException + { + //szHeader + this.szHeader=i_reader.readAscii(30); + //szModelName + this.szModelName=i_reader.readAscii(20); + return; + } + + +/* + char szHeader[30]; // "Vocaloid Motion Data 0002" + char szModelName[20]; // 対象モデル名 +*/ +} diff --git a/src/jp/nyatla/nymmd/struct/vmd/VMD_Motion.java b/src/jp/nyatla/nymmd/struct/vmd/VMD_Motion.java new file mode 100644 index 0000000..10512cf --- /dev/null +++ b/src/jp/nyatla/nymmd/struct/vmd/VMD_Motion.java @@ -0,0 +1,94 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.struct.vmd; + + +import jp.nyatla.nymmd.MmdException; +import jp.nyatla.nymmd.struct.*; +import jp.nyatla.nymmd.types.MmdVector3; +import jp.nyatla.nymmd.types.MmdVector4; +public class VMD_Motion implements StructType +{ + public String szBoneName; // ボーン名 + public long ulFrameNo; // フレーム番号 + + public final MmdVector3 vec3Position=new MmdVector3();// 位置 + public final MmdVector4 vec4Rotate=new MmdVector4(); // 回転(クォータニオン) + + public final int[] cInterpolation1=new int[16]; // 補間情報 + public final int[] cInterpolation2=new int[16]; + public final int[] cInterpolation3=new int[16]; + public final int[] cInterpolation4=new int[16]; + + public void read(DataReader i_reader) throws MmdException + { + int i; + //szName + this.szBoneName=i_reader.readAscii(15); + this.ulFrameNo=i_reader.readInt(); + StructReader.read(this.vec3Position, i_reader); + StructReader.read(this.vec4Rotate,i_reader); + for(i=0;i<16;i++){ + this.cInterpolation1[i]=i_reader.readByte(); + } + for(i=0;i<16;i++){ + this.cInterpolation2[i]=i_reader.readByte(); + } + for(i=0;i<16;i++){ + this.cInterpolation3[i]=i_reader.readByte(); + } + for(i=0;i<16;i++){ + this.cInterpolation4[i]=i_reader.readByte(); + } + return; + } + +/* + char szBoneName[15]; // ボーン名 + + unsigned long ulFrameNo; // フレーム番号 + + Vector3 vec3Position; // 位置 + Vector4 vec4Rotate; // 回転(クォータニオン) + + char cInterpolation1[16]; // 補間情報 + char cInterpolation2[16]; + char cInterpolation3[16]; + char cInterpolation4[16]; +*/ +} diff --git a/src/jp/nyatla/nymmd/types/BoneKeyFrame.java b/src/jp/nyatla/nymmd/types/BoneKeyFrame.java new file mode 100644 index 0000000..190c9c2 --- /dev/null +++ b/src/jp/nyatla/nymmd/types/BoneKeyFrame.java @@ -0,0 +1,62 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + + + +public class BoneKeyFrame +{ + public float fFrameNo; // フレーム番号 + public final MmdVector3 vec3Position=new MmdVector3(); // 位置 + public final MmdVector4 vec4Rotate=new MmdVector4(); // 回転(クォータニオン) + public static BoneKeyFrame[] createArray(int i_length) + { + BoneKeyFrame[] ret=new BoneKeyFrame[i_length]; + for(int i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + +public class FaceData +{ + public String szFaceName; // 表情名 + public int ulNumKeyFrames; // キーフレーム数 + public FaceKeyFrame[] pKeyFrames; // キーフレームデータ配列 +} diff --git a/src/jp/nyatla/nymmd/types/FaceKeyFrame.java b/src/jp/nyatla/nymmd/types/FaceKeyFrame.java new file mode 100644 index 0000000..0fec1f1 --- /dev/null +++ b/src/jp/nyatla/nymmd/types/FaceKeyFrame.java @@ -0,0 +1,53 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + +public class FaceKeyFrame +{ + public float fFrameNo; // フレーム番号 + public float fRate; // ブレンド率 + public static FaceKeyFrame[] createArray(int i_length) + { + FaceKeyFrame[] ret=new FaceKeyFrame[i_length]; + for(int i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + + + +public class MmdColor3 +{ + public float r, g, b; + + public void setValue(MmdColor4 v) + { + this.r=v.r; + this.g=v.g; + this.b=v.b; + return; + } +} diff --git a/src/jp/nyatla/nymmd/types/MmdColor4.java b/src/jp/nyatla/nymmd/types/MmdColor4.java new file mode 100644 index 0000000..3f7ebd0 --- /dev/null +++ b/src/jp/nyatla/nymmd/types/MmdColor4.java @@ -0,0 +1,59 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + +public class MmdColor4 +{ + public float r, g, b, a; + public void setValue(MmdColor4 v) + { + this.r=v.r; + this.g=v.g; + this.b=v.b; + this.a=v.a; + return; + } + public void getValue(float[] v,int i_st) + { + v[i_st+0]=this.r; + v[i_st+1]=this.g; + v[i_st+2]=this.b; + v[i_st+3]=this.a; + return; + } +} diff --git a/src/jp/nyatla/nymmd/types/MmdMatrix.java b/src/jp/nyatla/nymmd/types/MmdMatrix.java new file mode 100644 index 0000000..3a9a7d2 --- /dev/null +++ b/src/jp/nyatla/nymmd/types/MmdMatrix.java @@ -0,0 +1,377 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + +public class MmdMatrix +{ + ////// + // + ////// + + /** 行列の要素値です。*/ + public double m00; + /** 行列の要素値です。*/ + public double m01; + /** 行列の要素値です。*/ + public double m02; + /** 行列の要素値です。*/ + public double m03; + /** 行列の要素値です。*/ + public double m10; + /** 行列の要素値です。*/ + public double m11; + /** 行列の要素値です。*/ + public double m12; + /** 行列の要素値です。*/ + public double m13; + /** 行列の要素値です。*/ + public double m20; + /** 行列の要素値です。*/ + public double m21; + /** 行列の要素値です。*/ + public double m22; + /** 行列の要素値です。*/ + public double m23; + /** 行列の要素値です。*/ + public double m30; + /** 行列の要素値です。*/ + public double m31; + /** 行列の要素値です。*/ + public double m32; + /** 行列の要素値です。*/ + public double m33; + /** + * この関数は、オブジェクトの配列を生成して返します。 + * @param i_number + * 配列の長さ + * @return + * 新しいオブジェクト配列 + */ + public static MmdMatrix[] createArray(int i_number) + { + MmdMatrix[] ret=new MmdMatrix[i_number]; + for(int i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + + +public class MmdTexUV +{ + public float u, v; + public static MmdTexUV[] createArray(int i_length) + { + MmdTexUV[] ret=new MmdTexUV[i_length]; + for(int i=0;igmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + + + +public class MmdVector3 +{ + public float x, y, z; + public MmdVector3() + { + } + public MmdVector3(float ix,float iy,float iz) + { + this.x=ix;this.y=iy;this.z=iz; + } + public static MmdVector3[] createArray(int i_length) + { + MmdVector3[] ret=new MmdVector3[i_length]; + for(int i=0;i= 1.0 ){ + temp = 1.0; + }else if( temp <= -1.0 ){ + temp = -1.0; + } + + double yRadian = Math.sin(temp); + + // 他の回転を求める + double xx2 = pvec4Quat.x * x2; + double xy2 = pvec4Quat.x * y2; + double zz2 = pvec4Quat.z * z2; + double wz2 = pvec4Quat.w * z2; + + if( yRadian < 3.1415926f * 0.5f ) + { + if( yRadian > -3.1415926f * 0.5f ) + { + double yz2 = pvec4Quat.y * z2; + double wx2 = pvec4Quat.w * x2; + double yy2 = pvec4Quat.y * y2; + this.x = (float)Math.atan2(yz2 + wx2, (1.0f - (xx2 + yy2)) ); + this.y = (float)yRadian; + this.z = (float)Math.atan2( (xy2 + wz2), (1.0f - (yy2 + zz2)) ); + } + else + { + this.x = (float)-Math.atan2( (xy2 - wz2), (1.0f - (xx2 + zz2)) ); + this.y = (float)yRadian; + this.z = 0.f; + } + } + else + { + this.x = (float)Math.atan2( (xy2 - wz2), (1.0f - (xx2 + zz2)) ); + this.y = (float)yRadian; + this.z = 0.0f; + } + } + + +} diff --git a/src/jp/nyatla/nymmd/types/MmdVector4.java b/src/jp/nyatla/nymmd/types/MmdVector4.java new file mode 100644 index 0000000..f92e6f6 --- /dev/null +++ b/src/jp/nyatla/nymmd/types/MmdVector4.java @@ -0,0 +1,137 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + + +public class MmdVector4 +{ + public double x, y, z, w; + public void setValue(MmdVector4 v) + { + this.x=v.x; + this.y=v.y; + this.z=v.z; + this.w=v.w; + return; + } + public void QuaternionSlerp(MmdVector4 pvec4Src1,MmdVector4 pvec4Src2, double fLerpValue ) + { + + // Qlerp + double qr = pvec4Src1.x * pvec4Src2.x + pvec4Src1.y * pvec4Src2.y + pvec4Src1.z * pvec4Src2.z + pvec4Src1.w * pvec4Src2.w; + double t0 = 1.0f - fLerpValue; + + if( qr < 0 ) + { + this.x = pvec4Src1.x * t0 - pvec4Src2.x * fLerpValue; + this.y = pvec4Src1.y * t0 - pvec4Src2.y * fLerpValue; + this.z = pvec4Src1.z * t0 - pvec4Src2.z * fLerpValue; + this.w = pvec4Src1.w * t0 - pvec4Src2.w * fLerpValue; + } + else + { + this.x = pvec4Src1.x * t0 + pvec4Src2.x * fLerpValue; + this.y = pvec4Src1.y * t0 + pvec4Src2.y * fLerpValue; + this.z = pvec4Src1.z * t0 + pvec4Src2.z * fLerpValue; + this.w = pvec4Src1.w * t0 + pvec4Src2.w * fLerpValue; + } + QuaternionNormalize(this); + return; + } + public void QuaternionNormalize(MmdVector4 pvec4Src) + { + final double fSqr =1.0 / Math.sqrt(( pvec4Src.x * pvec4Src.x + pvec4Src.y * pvec4Src.y + pvec4Src.z * pvec4Src.z + pvec4Src.w * pvec4Src.w)); + + this.x =(pvec4Src.x * fSqr); + this.y =(pvec4Src.y * fSqr); + this.z =(pvec4Src.z * fSqr); + this.w =(pvec4Src.w * fSqr); + } + public void QuaternionCreateAxis(MmdVector3 pvec3Axis, double fRotAngle ) + { + if( Math.abs( fRotAngle ) < 0.0001f ) + { + this.x = this.y = this.z = 0.0f; + this.w = 1.0f; + } + else + { + fRotAngle *= 0.5f; + double fTemp = Math.sin(fRotAngle); + + this.x = pvec3Axis.x * fTemp; + this.y = pvec3Axis.y * fTemp; + this.z = pvec3Axis.z * fTemp; + this.w = Math.cos( fRotAngle ); + } + return; + } + public void QuaternionMultiply(MmdVector4 pvec4Src1,MmdVector4 pvec4Src2) + { + double px, py, pz, pw; + double qx, qy, qz, qw; + + px = pvec4Src1.x; py = pvec4Src1.y; pz = pvec4Src1.z; pw = pvec4Src1.w; + qx = pvec4Src2.x; qy = pvec4Src2.y; qz = pvec4Src2.z; qw = pvec4Src2.w; + + this.x = pw * qx + px * qw + py * qz - pz * qy; + this.y = pw * qy - px * qz + py * qw + pz * qx; + this.z = pw * qz + px * qy - py * qx + pz * qw; + this.w = pw * qw - px * qx - py * qy - pz * qz; + } + + public void QuaternionCreateEuler(MmdVector3 pvec3EulerAngle ) + { + final double xRadian = pvec3EulerAngle.x * 0.5; + final double yRadian = pvec3EulerAngle.y * 0.5; + final double zRadian = pvec3EulerAngle.z * 0.5; + final double sinX = Math.sin( xRadian ); + final double cosX = Math.cos( xRadian ); + final double sinY = Math.sin( yRadian ); + final double cosY = Math.cos( yRadian ); + final double sinZ = Math.sin( zRadian ); + final double cosZ = Math.cos( zRadian ); + + // XYZ + this.x = sinX * cosY * cosZ - cosX * sinY * sinZ; + this.y = cosX * sinY * cosZ + sinX * cosY * sinZ; + this.z = cosX * cosY * sinZ - sinX * sinY * cosZ; + this.w = cosX * cosY * cosZ + sinX * sinY * sinZ; + } + +} diff --git a/src/jp/nyatla/nymmd/types/MotionData.java b/src/jp/nyatla/nymmd/types/MotionData.java new file mode 100644 index 0000000..c8352eb --- /dev/null +++ b/src/jp/nyatla/nymmd/types/MotionData.java @@ -0,0 +1,125 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + +import jp.nyatla.nymmd.core.PmdBone; + + +public class MotionData +{ + public String szBoneName; // ボーン名 + public int ulNumKeyFrames; // キーフレーム数 + public BoneKeyFrame[] pKeyFrames; // キーフレームデータ配列 + /** + * + * @param fFrame + * @param i_pmd_bone + * 出力先オブジェクト + */ + public void getMotionPosRot(float fFrame,PmdBone i_pmd_bone) + { + int ulNumKeyFrame = this.ulNumKeyFrames; + BoneKeyFrame[] bone_key_frame=this.pKeyFrames; + + + // 最終フレームを過ぎていた場合 + if( fFrame > bone_key_frame[ulNumKeyFrame - 1].fFrameNo ) + { + fFrame = bone_key_frame[ulNumKeyFrame - 1].fFrameNo; + } + + // 現在の時間がどのキー近辺にあるか + int lKey0=findByBinarySearch(bone_key_frame,fFrame,0,ulNumKeyFrame-1)-1; + int lKey1=lKey0+1; + if( lKey1 == ulNumKeyFrame ) + { + lKey1 = ulNumKeyFrame - 1; + } + if(lKey0<0){ + lKey0=0; + } + // 前後のキーの時間 + float fTime0 = bone_key_frame[lKey0].fFrameNo; + float fTime1 = bone_key_frame[lKey1].fFrameNo; + + MmdVector3 pvec3Pos= i_pmd_bone.m_vec3Position; + MmdVector4 pvec4Rot= i_pmd_bone.m_vec4Rotate; + + // 前後のキーの間でどの位置にいるか + if( lKey0 != lKey1 ) + { + float fLerpValue = (fFrame - fTime0) / (fTime1 - fTime0); + pvec3Pos.Vector3Lerp(bone_key_frame[lKey0].vec3Position,bone_key_frame[lKey1].vec3Position, fLerpValue); + pvec4Rot.QuaternionSlerp(bone_key_frame[lKey0].vec4Rotate,bone_key_frame[lKey1].vec4Rotate, fLerpValue); + pvec4Rot.QuaternionNormalize(pvec4Rot);//これほんとにいるの? + }else{ + pvec3Pos.setValue(bone_key_frame[lKey0].vec3Position); + pvec4Rot.setValue(bone_key_frame[lKey0].vec4Rotate); + } + } + /** + * @author やねうらお さん + * @param pKeyFrames + * @param fFrame + * @param start + * @param end + * @return + */ + private static int findByBinarySearch(BoneKeyFrame[] pKeyFrames,float fFrame, int start, int end) + { + int diff = end - start; + if (diff < 8) { + // ある程度小さくなったら逐次サーチ。このな かに見つかるはずなんだ。 + for (int i = start; i < end; i++) { + if (fFrame < pKeyFrames[i].fFrameNo) { + return i; + } + } + return end; + } + + // 再帰的に調べる + int mid = (start + end) / 2; + if (fFrame < pKeyFrames[mid].fFrameNo){ + return findByBinarySearch(pKeyFrames, fFrame, start, mid); + } + else{ + return findByBinarySearch(pKeyFrames, fFrame, mid, end); + } + } +} diff --git a/src/jp/nyatla/nymmd/types/PmdMaterial.java b/src/jp/nyatla/nymmd/types/PmdMaterial.java new file mode 100644 index 0000000..16a8890 --- /dev/null +++ b/src/jp/nyatla/nymmd/types/PmdMaterial.java @@ -0,0 +1,51 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + + +public class PmdMaterial +{ + public final MmdColor4 col4Diffuse=new MmdColor4(); + public final MmdColor4 col4Specular=new MmdColor4(); + public final MmdColor4 col4Ambient=new MmdColor4(); + public float fShininess; + public String texture_name; + public String sphere_name; + public short[] indices; + public int unknown; +}; diff --git a/src/jp/nyatla/nymmd/types/PmdSkinInfo.java b/src/jp/nyatla/nymmd/types/PmdSkinInfo.java new file mode 100644 index 0000000..1249ba5 --- /dev/null +++ b/src/jp/nyatla/nymmd/types/PmdSkinInfo.java @@ -0,0 +1,47 @@ +/* + * PROJECT: NyMmd + * -------------------------------------------------------------------------------- + * The MMD for Java is Java version MMD Motion player class library. + * NyMmd is modules which removed the ARToolKit origin codes from ARTK_MMD, + * and was ported to Java. + * + * This is based on the ARTK_MMD v0.1 by PY. + * http://ppyy.if.land.to/artk_mmd.html + * py1024gmail.com + * http://www.nicovideo.jp/watch/sm7398691 + * + * + * The MIT License + * Copyright (C)2008-2012 nyatla + * nyatla39gmail.com + * http://nyatla.jp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +package jp.nyatla.nymmd.types; + + + +public class PmdSkinInfo +{ + public float fWeight;// ウェイト + public int unBoneNo_0; + public int unBoneNo_1; +} \ No newline at end of file -- cgit v1.2.3