/// <summary> /// @brief 乗算演算子 /// </summary> /// <param name="left">左辺</param> /// <param name="right">右辺</param> /// <returns>計算結果</returns> public static Vector3 operator *(Quaternion left, Vector3 right) { var v = new Quaternion(); v.x = right.x; v.y = right.y; v.z = right.z; v = left * v * left.Conjugate; return new Vector3 { x = v.x, y = v.y, z = v.z }; }
/// <summary> /// @brief 乗算演算子 /// </summary> /// <param name="left">左辺</param> /// <param name="right">右辺</param> /// <returns>計算結果</returns> public static Vector3 operator *(Vector3 left, Quaternion right) { var v = new Quaternion(); v.x = left.x; v.y = left.y; v.z = left.z; v = right * v * right.Conjugate; return new Vector3 { x = v.x, y = v.y, z = v.z }; }
/// <summary> /// @brief 内積を取得する /// </summary> /// <param name="right">右辺</param> /// <returns>計算結果</returns> public float Dot(Quaternion right) { return x * right.x + y + right.y + z * right.z + w * right.w; }
/// <summary> /// @brief 球面線形補完する /// </summary> /// <param name="end">最終地点</param> /// <param name="t">補完の早さ</param> /// <returns></returns> public Quaternion Slerp(Quaternion end, float t) { Quaternion left = Normalize(); Quaternion right = end.Normalize(); float len1 = left.Length; float len2 = right.Length; if (len1 == 0.0f || len2 == 0.0f) { return Quaternion.Identity; } float cos = left.Dot(right) / (len1 * len2); if (cos >= 1.0f) { return this; } Quaternion ret = new Quaternion(); float w = (float)Math.Acos(cos); float sin_w = (float)Math.Sin(w); float sin_t_w = (float)Math.Sin(t * w); float sin_inv_t_w = (float)Math.Sin((1.0f - t) * w); float mult_q1 = sin_inv_t_w / sin_w; float mult_q2 = sin_t_w / sin_w; ret.x = mult_q1 * left.x + mult_q2 * right.x; ret.y = mult_q1 * left.y + mult_q2 * right.y; ret.z = mult_q1 * left.z + mult_q2 * right.z; ret.w = mult_q1 * left.w + mult_q2 * right.w; return ret; }
/// <summary> /// @brief ビットの移動 /// </summary> private void Move() { if (Game.Instance.InputController.XController != null && !Game.Instance.InputController.XController.IsPullTrigger(Index == BitIndex.BIT_LEFT ? XGameController.Trigger.LEFT : XGameController.Trigger.RIGHT, 128)) { return; } int dir = 0x0000; var Direciton = new Vector3 { x = 1.0f, y = 0.0f, z = 0.0f };//右向きの基本ベクトル float Clockwise = (float)Math.PI / 60;//曲げる分; var b = new Quaternion(Position.LocalAxisZ, Angle);//Zziku Angle分回転する回転量 var c = Direciton * b;//Angle分回転した向きベクトル var EightDirection = XGameController.StickDirection.NONE; // コントローラーが接続されていない場合は判定しない if (Game.Instance.InputController.XController != null) { EightDirection = Game.Instance.InputController.XController.GetStick8Direction(false, 10000); } if (EightDirection == XGameController.StickDirection.LEFTDOWN) {//左下 dir |= 0x0110; } else if (EightDirection == XGameController.StickDirection.LEFTUP) {//左上 dir |= 0x1100; } else if (EightDirection == XGameController.StickDirection.RIGHTDOWN) {//右下 dir |= 0x0011; } else if (EightDirection == XGameController.StickDirection.RIGHTUP) {//右上 dir |= 0x1001; } // 移動処理 if (DX.CheckHitKey(DX.KEY_INPUT_UP) == 1 || EightDirection == XGameController.StickDirection.UP) { dir |= 0x1000; var Purpose = new Vector3 { x = 0.0f, y = -1.0f, z = 0.0f }; var Cross = c.Cross(Purpose); if (((Rot < 270 && Rot > 90) || ((Rot > 270 && Rot < 360) || (Rot >= 0 && Rot < 90))) || Rot == 270) { if (Cross.z >= 0) { Rot -= 3; Clockwise = (float)Math.PI / 60; } else { Rot += 3; Clockwise = -(float)Math.PI / 60; } if (Rot >= 360)//360度を越えたら { Rot -= 360; } if (Rot < 0)//-になったら { Rot += 360; } Position.LocalRotation *= new Quaternion(Vector3.AxisZ, Clockwise); } else { Rot = 90; } } else if (DX.CheckHitKey(DX.KEY_INPUT_DOWN) == 1 || EightDirection == XGameController.StickDirection.DOWN) { dir |= 0x0010; var Purpose = new Vector3 { x = 0.0f, y = 1.0f, z = 0.0f }; var Cross = c.Cross(Purpose); if (((Rot < 270 && Rot > 90) || ((Rot > 270 && Rot < 360) || (Rot >= 0 && Rot < 90))) || Rot == 90) { if (Cross.z >= 0) { Rot -= 3; Clockwise = (float)Math.PI / 60; } else { Rot += 3; Clockwise = -(float)Math.PI / 60; } if (Rot >= 360)//360度を越えたら { Rot -= 360; } if (Rot < 0)//-になったら { Rot += 360; } Position.LocalRotation *= new Quaternion(Vector3.AxisZ, Clockwise); } else { Rot = 270; } } if (DX.CheckHitKey(DX.KEY_INPUT_LEFT) == 1 || EightDirection == XGameController.StickDirection.LEFT) { dir |= 0x0100; var Purpose = new Vector3 { x = -1.0f, y = 0.0f, z = 0.0f }; var Cross = c.Cross(Purpose); if (((Rot > 180 && Rot < 360) || (Rot > 0 && Rot < 180)) || Rot == 0) { if (Cross.z <= 0) { Rot -= 3; Clockwise = (float)Math.PI / 60; } else { Rot += 3; Clockwise = -(float)Math.PI / 60; } if (Rot >= 360)//360度を越えたら { Rot -= 360; } if (Rot < 0)//-になったら { Rot += 360; } Position.LocalRotation *= new Quaternion(Vector3.AxisZ, Clockwise); } else { Rot = 180; } } else if (DX.CheckHitKey(DX.KEY_INPUT_RIGHT) == 1 || EightDirection == XGameController.StickDirection.RIGHT) { dir |= 0x0001; var Purpose = new Vector3 { x = 1.0f, y = 0.0f, z = 0.0f }; var Cross = c.Cross(Purpose); if (((Rot > 180 && Rot < 360) || (Rot > 0 && Rot < 180)) || Rot == 180) { if (Cross.z <= 0) { Rot -= 3; Clockwise = (float)Math.PI / 60; } else { Rot += 3; Clockwise = -(float)Math.PI / 60; } if (Rot >= 360)//360度を越えたら { Rot -= 360; } if (Rot < 0)//-になったら { Rot += 360; } Position.LocalRotation *= new Quaternion(Vector3.AxisZ, Clockwise); } else { Rot = 0; } } float theta; switch (dir) { case 0x0001: theta = 0.0f; break; case 0x0011: theta = (float)Math.PI * 0.25f; break; case 0x0010: theta = (float)Math.PI * 0.5f; break; case 0x0110: theta = (float)Math.PI * 0.75f; break; case 0x0100: theta = (float)Math.PI; break; case 0x1100: theta = (float)Math.PI * 1.25f; break; case 0x1000: theta = (float)Math.PI * 1.5f; break; case 0x1001: theta = (float)Math.PI * 1.75f; break; default: theta = -1.0f; break; } if (theta >= 0.0f) { Position.LocalPosition.x += (float)Math.Cos(theta) * Speed; Position.LocalPosition.y += -(float)Math.Sin(theta) * Speed; } Angle = Rot * -(float)Math.PI / 180; }