//描画ターゲットの初期化とデバイスへの接続を行います。 void Start() { _model = PdkManager.CreateStandardModelPS(); //ボーンを一つ残らず初期配置 //NOTE: ここではボーンの階層構造を作らずすべてRoot直下に置いてる事に注意! _spheres = _model.Bones .ToDictionary( bone => bone.Key, bone => { var s = GameObject.CreatePrimitive(PrimitiveType.Sphere); s.name = bone.Value.Name; s.transform.parent = this.transform; s.transform.localScale = new Vector3(.05f, .05f, .05f); var t = bone.Value.InitialWorldMatrix.Translate; //NOTE: QUMARIONのボーンはcm単位らしいので0.01倍に縮める s.transform.localPosition = 0.01f * new Vector3(-t.X, t.Y, t.Z); return(s); }); //ボーン間の線を書くためのオブジェクトを用意 _drawableBones = _model.Bones .Where(kvp => kvp.Key != StandardPSBones.Hips) .Select(kvp => { var childSphere = _spheres[kvp.Key]; var parentSphere = _spheres[StandardPSBonesUtil.GetStandardPSBone(_model.Bones[kvp.Key].Parent.Name)]; return(new DrawableBone(parentSphere, childSphere)); }) .ToArray(); if (PdkManager.ConnectedDeviceCount == 0) { Debug.LogWarning("QUMARION was not found"); } else { _model.AttachQumarion(PdkManager.GetDefaultQumarion()); _model.AttachedQumarion.EnableAccelerometer = false; _model.AccelerometerMode = AccelerometerMode.Direct; _model.AccelerometerRestrictMode = AccelerometerRestrictMode.None; } }
/// <summary>Qumarion側のボーン情報と親ボーンを指定してインスタンスを初期化します。</summary> /// <param name="bone">Qumarion側のボーン</param> /// <param name="boneType">Qumarion側のボーンが標準ボーンのどれに該当するか</param> /// <param name="parent">親ボーン(ルートのボーンを生成する場合nullを指定)</param> public QumaBone2Humanoid(Bone bone, StandardPSBones boneType, QumaBone2Humanoid parent) { _bone = bone; _parent = parent; QumaBoneType = boneType; //StandardPSBones -> HumanBodyBoneの対応付けがあれば登録し、無い場合は無いことを確認。 try { HumanBodyBone = QmBoneToAnimatorBone.GetHumanBodyBone(boneType); IsValidHumanBodyBone = true; } catch (KeyNotFoundException) { HumanBodyBone = HumanBodyBones.Hips; IsValidHumanBodyBone = false; } InitialRotation = MatrixToQuaternionWithCoordinateModify(_bone.InitialLocalMatrix); //ゼロ回転状態での固定座標軸を参照するため親のワールド座標を確認: ルート(Hips)はワールド座標直下。 Matrix4f initMat = (_bone.Parent != null) ? _bone.Parent.InitialWorldMatrix : Matrix4f.Unit; //疑似座標系の初期化: Qumarion側の行列は右手系(左-上-前)なので正負補正が必要な事に注意。 //NOTE: Qumarionの場合ルートが原点、回転は無しとみなすと次のように簡単化される xAxis = new Vector3(initMat.M11, -initMat.M21, -initMat.M31); yAxis = new Vector3(-initMat.M12, initMat.M22, initMat.M32); zAxis = new Vector3(-initMat.M13, initMat.M23, initMat.M33); //再帰的に子ボーンを初期化。 _childs = bone .Childs .Select(b => new QumaBone2Humanoid(b, StandardPSBonesUtil.GetStandardPSBone(b.Name), this)) .ToArray(); }
/// <summary>Qumarion側のボーン情報と親ボーンを指定してインスタンスを初期化します。</summary> /// <param name="bone">Qumarion側のボーン</param> /// <param name="boneType">Qumarion側のボーンが標準ボーンのどれに該当するか</param> /// <param name="parent">親ボーン(ルートのボーンを生成する場合nullを指定)</param> public QumaBone2MikuMikuMoving(Bone bone, StandardPSBones boneType, QumaBone2MikuMikuMoving parent) { _bone = bone; _parent = parent; QumaBoneType = boneType; //StandardPSBones -> MMDBoneの対応確認 try { MMDBone = QumaBone2MMDBone.GetMMDBone(boneType); IsValidBone = true; } catch (KeyNotFoundException) { MMDBone = MMDStandardBone.Hip; IsValidBone = false; } InitialRotation = CreateQuaternion(_bone.InitialLocalMatrix); //ゼロ回転状態での固定座標軸を参照するため親のワールド座標を確認: ルート(Hips)はワールド座標直下。 Matrix4f initMat = (_bone.Parent != null) ? _bone.Parent.InitialWorldMatrix : Matrix4f.Unit; //疑似座標系の初期化: QumarionもMMMも右手系(左-上-前)で一緒なのでほぼそのまま使ってOK xAxis = new Vector3(initMat.M11, initMat.M21, initMat.M31); yAxis = new Vector3(initMat.M12, initMat.M22, initMat.M32); zAxis = new Vector3(initMat.M13, initMat.M23, initMat.M33); //再帰的に子ボーンを初期化。 _childs = bone .Childs .Select(b => new QumaBone2MikuMikuMoving(b, StandardPSBonesUtil.GetStandardPSBone(b.Name), this)) .ToArray(); }