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; } }
public 照明行列管理(行列管理 manager) { _行列管理 = manager; ビュー行列管理 = new カメラ(new Vector3(0, 0, -20), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); 射影行列プロバイダ = new 射影(); }
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); }
public void モーションを更新する(カメラ camera, 射影 projection) { _カメラモーション.モーションを更新する(camera, projection); var サイドカメラの位置 = camera.カメラの位置 - camera.カメラの注視点; サイドカメラの位置 = Vector3.TransformNormal(サイドカメラの位置, Matrix.RotationQuaternion(_回転量)); camera.カメラの位置 = camera.カメラの注視点 + サイドカメラの位置; }
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; }
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); }
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); }
public 行列管理(ワールド行列 world, カメラ camera, 射影 projection) { this.ワールド行列管理 = world; this.ビュー行列管理 = camera; this.射影行列管理 = projection; }