void カメラモーション.モーションを更新する(カメラ camera, 射影 projection)
        {
            if (!_追跡対象のボーン.TryGetTarget(out PMXボーン bone) ||
                !_追跡対象のモデル.TryGetTarget(out PMXModel model))
            {
                return;
            }

            // ボーンのワールド座標を求める行列を作成

            Matrix ボーンポーズ行列 =
                bone.モデルポーズ行列 *
                Matrix.Scaling(model.モデル状態.率) *
                Matrix.RotationQuaternion(model.モデル状態.回転) *
                Matrix.Translation(model.モデル状態.位置);

            var ボーン位置 = Vector3.TransformCoordinate(bone.ローカル位置, ボーンポーズ行列);

            var 注視点からカメラの場所に向かうベクトル = Vector3.TransformNormal(-見る方向, ボーンポーズ行列);

            注視点からカメラの場所に向かうベクトル.Normalize();

            camera.カメラの位置  = ボーン位置 + カメラとボーンとの距離 * 注視点からカメラの場所に向かうベクトル;
            camera.カメラの注視点 = ボーン位置;

            if (カメラから見てZ軸方向に回転する)
            {
                var newUp = Vector3.TransformNormal(new Vector3(0, 1, 0), ボーンポーズ行列);
                newUp.Normalize();

                camera.カメラの上方向ベクトル = newUp;
            }
        }
コード例 #2
0
        public 照明行列管理(行列管理 manager)
        {
            _行列管理 = manager;

            ビュー行列管理   = new カメラ(new Vector3(0, 0, -20), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
            射影行列プロバイダ = new 射影();
        }
コード例 #3
0
        public void モーションを更新する(カメラ camera, 射影 projection)
        {
            if (0 == _前回の時刻msec)
            {
                _前回の時刻msec = _stopWatch.ElapsedMilliseconds;
            }
            else
            {
                // フレーム番号を更新

                long 現在の時刻msec = _stopWatch.ElapsedMilliseconds;
                long 経過時間msec  = 現在の時刻msec - _前回の時刻msec;

                if (_再生中)
                {
                    現在のフレーム番号 += 経過時間msec / 30f;
                }

                if (_反復再生する && 最終のフレーム番号 < 現在のフレーム番号)
                {
                    現在のフレーム番号 = 0;
                }

                _前回の時刻msec = 現在の時刻msec;
            }

            if (0 == _カメラフレームリスト.Count)
            {
                return;
            }

            // フレームの更新は、現在のフレーム番号で進行度合いを測る。

            for (int i = 0; i < _カメラフレームリスト.Count - 1; i++)
            {
                if (_カメラフレームリスト[i].フレーム番号 < 現在のフレーム番号 &&
                    _カメラフレームリスト[i + 1].フレーム番号 >= 現在のフレーム番号)
                {
                    // frame は [i] と [i+1] の間にある

                    uint フレーム間隔 =
                        _カメラフレームリスト[i + 1].フレーム番号 -
                        _カメラフレームリスト[i].フレーム番号;

                    float 進行度合い0to1 = (現在のフレーム番号 - _カメラフレームリスト[i].フレーム番号) / (float)フレーム間隔;      // 0.0~1.0

                    _フレームを更新する(_カメラフレームリスト[i], _カメラフレームリスト[i + 1], camera, projection, 進行度合い0to1);

                    return;
                }
            }

            // returnされなかったとき=つまり最終フレーム以降のとき

            _フレームを更新する(_カメラフレームリスト.Last(), _カメラフレームリスト.Last(), camera, projection, 0);
        }
コード例 #4
0
        public void モーションを更新する(カメラ camera, 射影 projection)
        {
            _カメラモーション.モーションを更新する(camera, projection);

            var サイドカメラの位置 = camera.カメラの位置 - camera.カメラの注視点;

            サイドカメラの位置 = Vector3.TransformNormal(サイドカメラの位置, Matrix.RotationQuaternion(_回転量));

            camera.カメラの位置 = camera.カメラの注視点 + サイドカメラの位置;
        }
コード例 #5
0
        void カメラモーション.モーションを更新する(カメラ cp1, 射影 proj)
        {
            var camera2la = Vector3.TransformCoordinate(
                new Vector3(0, 0, 1),
                Matrix.RotationQuaternion(_カメラの注視点を中心とする回転量));

            _X軸 = Vector3.Cross(camera2la, cp1.カメラの上方向ベクトル);
            _X軸.Normalize();

            _Y軸 = Vector3.Cross(_X軸, camera2la);
            _Y軸.Normalize();

            cp1.カメラの注視点 += _X軸 * _カメラの注視点の変形行列.X + _Y軸 * _カメラの注視点の変形行列.Y;

            cp1.カメラの位置 = cp1.カメラの注視点 + _距離 * (-camera2la);

            _カメラの注視点の変形行列 = Vector2.Zero;
        }
コード例 #6
0
        public ScreenContext ScreenContextを作成する(Control control)
        {
            var カメラ = new カメラ(
                カメラの初期位置: new Vector3(0, 20, -40),
                カメラの初期注視点: new Vector3(0, 3, 0),
                カメラの初期上方向ベクトル: new Vector3(0, 1, 0));

            var 射影行列 = new 射影();

            射影行列.射影行列を初期化する((float)Math.PI / 4f, 1.618f, 1, 200);

            var matrixManager = new 行列管理(new ワールド行列(), カメラ, 射影行列);

            var context = new ScreenContext(control, matrixManager);

            this.ControltoScreenContextマップ.Add(control, context);

            return(context);
        }
コード例 #7
0
        private void _フレームを更新する(カメラフレーム cameraFrame1, カメラフレーム cameraFrame2, カメラ camera, 射影 projection, float 進行度合い0to1)
        {
            float ProgX = cameraFrame1.ベジェ曲線[0].横位置Pxに対応する縦位置Pyを返す(進行度合い0to1);
            float ProgY = cameraFrame1.ベジェ曲線[1].横位置Pxに対応する縦位置Pyを返す(進行度合い0to1);
            float ProgZ = cameraFrame1.ベジェ曲線[2].横位置Pxに対応する縦位置Pyを返す(進行度合い0to1);
            float ProgR = cameraFrame1.ベジェ曲線[3].横位置Pxに対応する縦位置Pyを返す(進行度合い0to1);
            float ProgL = cameraFrame1.ベジェ曲線[4].横位置Pxに対応する縦位置Pyを返す(進行度合い0to1);
            float ProgP = cameraFrame1.ベジェ曲線[5].横位置Pxに対応する縦位置Pyを返す(進行度合い0to1);

            // カメラ(ビュー)

            camera.移動する(
                注視点からの距離: CGHelper.Lerp(cameraFrame1.距離, cameraFrame2.距離, ProgL),
                注視点の位置: CGHelper.ComplementTranslate(cameraFrame1, cameraFrame2, new Vector3(ProgX, ProgY, ProgZ)),
                回転: CGHelper.ComplementRotateQuaternion(cameraFrame1, cameraFrame2, ProgR));

            // 射影

            float angle = CGHelper.Lerp(cameraFrame1.視野角, cameraFrame2.視野角, ProgP);

            projection.視野角rad = CGHelper.ToRadians(angle);
        }
コード例 #8
0
 public 行列管理(ワールド行列 world, カメラ camera, 射影 projection)
 {
     this.ワールド行列管理 = world;
     this.ビュー行列管理  = camera;
     this.射影行列管理   = projection;
 }