2

エンティティを 3D ベクトルに向けようとしています。(基本的に、エンティティの角度を設定して、3D 空間内の位置を指すようにします)。現時点では、ベクトルから角度を取得することにこだわっています。

//Vectors in the bracket are 3D, first is the entity position, second is a position in space where I want to point at.
( myEntity.Pos - posToPointAt ).Angle

私は現在、方向ベクトルを角度に変換することに固執しています。助けていただければ幸いです。

4

1 に答える 1

2

エンティティの位置を使用する代わりに、エンティティが現在どの方向を指しているかを把握する必要があります。その情報を取得することは、現在の回転行列を使用し、それを z 軸 (またはエンティティの「ニュートラル」方向が何であれ) に沿って単位ベクトルで乗算するのと同じくらい簡単かもしれませんが、それはすべて特定の設定に依存します。

両方方向ベクトル (現在の方向と、新しい目的の場所への方向...最後のものは正規化された "myEntity.Pos - posToPointAt") を取得したら、以下のような関数を使用して方向間の回転を計算します。 . ここでクォータニオンを使用していることに注意してください。回転行列が必要になる場合があります。

function RotationBetweenVectors( const aV1, aV2: TVector3): TQuaternion;
const
  EPSILON = 0.000001;

var
  v1: TVector3;
  v2: TVector3;
  dot: FloatT;
  s: FloatT;
  invS: FloatT;
  c: TVector3;

begin
  v1 := aV1.normalize;
  v2 := aV2.normalize;

  dot := VectorDotProduct( v1, v2 );

  if dot >= 1 then
  begin
      // INFO: DotProduct = 1 -> vectors are the same
      result := QUATERNION_IDENTITY
  end
  else if ( dot < EPSILON - 1 ) then
  begin
      raise Exception.create( '180 degree rotation currently not supported.' );
  end
  else
  begin
      s := sqrt( 2 * ( 1 + dot ));
      invS := 1 / s;

      c := VectorCrossProduct( v1, v2 );

      result.x := c.x * invS;
      result.y := c.y * invS;
      result.z := c.z * invS;
      result.w := 0.5 * s;
      result := result.normalize;
  end;
end;
于 2010-10-16T19:24:14.390 に答える