/// <summary> /// コンストラクタ /// </summary> /// <param name="rigids">剛体情報</param> /// <param name="joints">関節情報</param> /// <param name="model">モデル情報</param> public PhysicsManager(MMDRigid[] rigids, MMDJoint[] joints, MMDModel model) { List<RigidBody> rbodies = new List<RigidBody>(); List<Generic6DofSpringConstraint> dofjoints = new List<Generic6DofSpringConstraint>(); motionState = new List<MMDMotionState>(); List<short> groups = new List<short>(); List<short> masks = new List<short>(); //剛体の作成 for (int i = 0; i < rigids.Length; i++) { MMDMotionState mstate; short group; rbodies.Add(CreateRigidBody(rigids[i], model, out group, out mstate)); motionState.Add(mstate); groups.Add(group); masks.Add((short)rigids[i].GroupTarget); } //ジョイント(拘束)の作成 for (int i = 0; i < joints.Length; i++) { RigidBody phisic0 = rbodies[(int)joints[i].RigidBodyA]; RigidBody phisic1 = rbodies[(int)joints[i].RigidBodyB]; dofjoints.Add(CreateJoint(phisic0, phisic1, joints[i], model)); } Rigids = new ReadOnlyCollection<RigidBody>(rbodies); this.groups = groups.ToArray(); this.masks = masks.ToArray(); Joints = new ReadOnlyCollection<Generic6DofSpringConstraint>(dofjoints); bSetup = true; //イベントをフック PhysicsThreadManager.Instanse.Synchronize += new Action(Update); PhysicsThreadManager.Instanse.DropFrame += new Action<int>(DropFrame); }
/// <summary> /// デフォルトコンストラクタ /// </summary> /// <param name="rigid">MMD剛体データ</param> /// <param name="Model">MMDモデルデータ</param> public MMDMotionState(MMDRigid rigid, MMDModel Model) { UserData = null; m_rigid = rigid; //初期の姿勢を計算 Matrix startTransform; if (!string.IsNullOrEmpty(rigid.RelatedBoneName)) startTransform = Model.BoneManager[rigid.RelatedBoneName].GlobalTransform; else { if (Model.BoneManager.IndexOf("センター") >= 0) startTransform = Model.BoneManager[Model.BoneManager.IndexOf("センター")].GlobalTransform; else startTransform = Matrix.Identity; } //ボーンと剛体とのズレを計算 Matrix RigidBias = CreateRigidBias(rigid); //初期姿勢を計算 startTransform = RigidBias * startTransform * Model.Transform; //初期の姿勢をMotionStateに設定 btTransform startTrans; MMDXMath.TobtTransform(ref startTransform, out startTrans); m_graphicsWorldTrans = startTrans; m_centerOfMassOffset = btTransform.Identity; m_startWorldTrans = startTrans; //これからの計算ように確保 m_rigidBias = RigidBias; RelatedBoneName = rigid.RelatedBoneName; m_model = Model; }
private RigidBody CreateRigidBody(MMDRigid rigid, MMDModel Model,out short group, out MMDMotionState motionStateStart) { CollisionShape collision; RigidBody body; //衝突スキンの作成 switch (rigid.ShapeType) { case 0: collision = new SphereShape(rigid.ShapeWidth); break; case 1: collision = new BoxShape(new btVector3(rigid.ShapeWidth, rigid.ShapeHeight, rigid.ShapeDepth)); break; case 2: collision = new CapsuleShape(rigid.ShapeWidth, rigid.ShapeHeight); break; default: throw new NotImplementedException("不明な剛体タイプ"); } motionStateStart = new MMDMotionState(rigid, Model); btVector3 localInertia = btVector3.Zero; //イナーシャの計算 if (rigid.Type != 0) collision.calculateLocalInertia(rigid.Weight, out localInertia); //剛体を作成 body = new RigidBody((rigid.Type != 0 ? rigid.Weight : 0), motionStateStart, collision, localInertia); //ダンピング値、摩擦、Restitutionをセット body.setDamping(rigid.LinerDamping, rigid.AngularDamping); body.Friction = rigid.Friction; body.Restitution = rigid.Restitution; //ボーン追従型はKinematicにする if (rigid.Type == 0) { body.ActivationState |= ActivationStateFlags.DISABLE_DEACTIVATION; body.CollisionFlags = CollisionFlags.CF_KINEMATIC_OBJECT; if (!string.IsNullOrEmpty(rigid.RelatedBoneName)) Model.BoneManager[rigid.RelatedBoneName].IsPhysics = false; } else {//物理演算型はボーンのフラグをオンにする if (!string.IsNullOrEmpty(rigid.RelatedBoneName)) Model.BoneManager[rigid.RelatedBoneName].IsPhysics = true; } //グループのフラグをセット group = (short)Math.Pow(2, rigid.GroupIndex); return body; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="modelParts">モデルパーツ</param> /// <param name="boneManager">ボーンマネージャ</param> /// <param name="faceManager">表情マネージャ</param> /// <param name="attachedMotion">付属モーション</param> /// <param name="rigids">剛体</param> /// <param name="joints">ジョイント</param> public MMDXModel(List<IMMDModelPart> modelParts, MMDBoneManager boneManager, IMMDFaceManager faceManager, Dictionary<string, MMDMotion> attachedMotion, MMDRigid[] rigids, MMDJoint[] joints) : base(modelParts, boneManager, faceManager, attachedMotion, rigids, joints) { #if XBOX //ボーンマネージャ・表情マネージャを変換しておく this.boneManager = (MMDXBoxBoneManager)boneManager; this.faceManager = (MMDXBoxFaceManager)faceManager; //グラフィックデバイスの抜き出し if (modelParts.Count > 0) { GraphicsDevice graphics = ((MMDModelPart)modelParts[0]).GraphicsDevice; //頂点バッファの作成 skinVertexBuffer = new WritableVertexBuffer(graphics, this.boneManager.SKinTransformXBox.Length * 4, typeof(VertexSkinning)); this.faceManager.SetUp(graphics); } #endif }
/// <summary> /// コンストラクタ /// </summary> /// <param name="vertex">頂点データ</param> /// <param name="modelParts">モデルパーツ</param> /// <param name="boneManager">ボーンマネージャ</param> /// <param name="faceManager">表情マネージャ</param> /// <param name="attachedMotion">付随モーション</param> /// <param name="rigids">剛体情報</param> /// <param name="joints">関節情報</param> public SlimMMDModel(MMDVertexNmTx[] vertex, List<IMMDModelPart> modelParts, MMDBoneManager boneManager, MMDFaceManager faceManager, Dictionary<string, MMDMotion> attachedMotion, MMDRigid[] rigids, MMDJoint[] joints) : base(modelParts, boneManager, faceManager, attachedMotion, rigids, joints) { m_vertex = vertex; //データのコピー verticesSource = new VertexPNmTx[m_vertex.LongLength]; for (long i = 0; i < m_vertex.LongLength; ++i) { verticesSource[i].Position = m_vertex[i].Position; verticesSource[i].Normal = m_vertex[i].Normal; verticesSource[i].Texture = m_vertex[i].TextureCoordinate; } InitGraphicsResource(); SlimMMDXCore.Instance.LostDevice += OnLostDevice; SlimMMDXCore.Instance.ResetDevice += OnResetDevice; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="modelParts">モデルパーツ</param> /// <param name="boneManager">ボーンマネージャ</param> /// <param name="faceManager">表情マネージャ</param> /// <param name="attachedMotion">付随モーション</param> /// <param name="rigids">剛体情報</param> /// <param name="joints">関節情報</param> public MMDModel(List<IMMDModelPart> modelParts, MMDBoneManager boneManager, IMMDFaceManager faceManager, Dictionary<string, MMDMotion> attachedMotion, MMDRigid[] rigids, MMDJoint[] joints) { Transform = Matrix.Identity; this.modelParts = modelParts; this.boneManager = boneManager; this.faceManager = faceManager; this.attachedMotion = attachedMotion; Culling = true; boneManager.CalcGlobalTransform(); this.physicsManager = new PhysicsManager(rigids, joints, this); foreach (var part in modelParts) part.SetModel(this); Parts = new ReadOnlyCollection<IMMDModelPart>(modelParts); animationPlayer = new AnimationPlayer(boneManager, faceManager); //イベントフック MMDCore.Instance.OnBoneUpdate += new Action<float>(BoneUpdate); MMDCore.Instance.OnSkinUpdate += new Action<float>(SkinUpdate); }
Matrix CreateRigidBias(MMDRigid rigid) { return MMDXMath.CreateMatrixFromYawPitchRoll(rigid.Rotation[1], rigid.Rotation[0], rigid.Rotation[2]) * MMDXMath.CreateTranslationMatrix(rigid.Position[0], rigid.Position[1], rigid.Position[2]); }