2012-04-25 2 views
4

다음 권리는 있습니까?XNA의 쿼터니온 교체

분명히 그렇지 않다면 나는 여기에 질문을 게시하지 않을 것이지만 다른 모델 주위로 모델의 쿼터니언 회전을하려고합니다.

내가 vector3 위치와 float 회전 각도를 가진 박스 모델을 가지고 있다고 가정 해 보겠습니다. 나는 또한 상자 모델을 향하고있는 절두체 모양의 모델을 가지고 있으며, 그 위치는 상자 모델에서 50 단위라고 말할 수 있습니다. 절두체에는 vector3 위치와 Quaternion 회전이 있습니다.

시나리오 1에서 상자와 절두체는 "회전되지 않음"입니다. 이것은 모두 괜찮아요. 시나리오 2에서는 상자 만 회전시키고 절두체가 항상 상자를 똑바로 향하고 회전하지 않은 거리에서 상자에서 같은 거리에있는 절두체를 사용하여 절두체를 회전 시키려고합니다 (추격 카메라와 비슷합니다). 분명히 상자와 절두체 모두 Matrix.CreateRotationY()를 사용하여 모델과 절두체를 회전하면 절두체가 측면에 약간 오프셋됩니다.

그래서 상자 주위의 절두체의 쿼터니언 회전이 가장 좋을 것이라고 생각 했습니까? 이 목적을 위해 나는 행운이없이 다음을 시도했다. 그것은 내 모델을 화면에 그려지지만 화면에 거대한 상자처럼 보이는 것을 그리고 아무리 멀리 카메라를 움직여도 항상 상자가 있습니다

테스트 목적으로, 내 GAME1 클래스 3 개 상자와 자신의 3 관련 frustums 나는 위치와 회전

boxObject[0].Position = new Vector3(10, 10, 10); 
boxObject[1].Position = new Vector3(10, 10, 10); 
boxObject[2].Position = new Vector3(10, 10, 10); 

boxObject[0].Rotation = 0.0f; 
boxObject[1].Rotation = 45.0f; 
boxObject[2].Rotation = -45.0f; 

함께 상자 [0] 초기화 그래서 같은 위치에 있지만 다른 각도에서 그려 3 개 상자.()을

frustumObject[0].ModelRotation = new Quaternion(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f, 0); 
frustumObject[0].ModelRotation = new Quaternion(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f, 45); 
frustumObject[0].ModelRotation = new Quaternion(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f, -45); 

그리고 마지막으로, 모델을 그려, 나는 그리기 : 그럼 내가 시작, 자신의 위치 frustums을 할 :

float f = 50.0f; 
frustumObject[0].Position = new Vector3(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f); 
frustumObject[1].Position = new Vector3(boxObject[1].Position.X, 
      boxObject[1].Position.Y, boxObject[1].Position.Z + f); 
frustumObject[2].Position = new Vector3(boxObject[2].Position.X, 
      boxObject[2].Position.Y, boxObject[2].Position.Z + f); 

을 그리고 시도 및 관련 상자 모델을 중심으로 회전 내 게임 모델 클래스에 :

public Model CameraModel { get; set; } 
public Vector3 Position { get; set; } 
public float Rotation { get; set; } 
public Quaternion ModelRotation { get; set; } 

public void Draw(Matrix view, Matrix projection) 
    { 
     transforms = new Matrix[CameraModel.Bones.Count]; 
     CameraModel.CopyAbsoluteBoneTransformsTo(transforms); 

     // Draw the model 
     foreach (ModelMesh myMesh in CameraModel.Meshes) 
     { 
      foreach (BasicEffect myEffect in myMesh.Effects) 
      { 
       // IS THIS CORRECT????? 
       myEffect.World = transforms[myMesh.ParentBone.Index] * 
        Matrix.CreateRotationY(Rotation) * Matrix.CreateFromQuaternion(ModelRotation) * Matrix.CreateTranslation(Position); 

       myEffect.View = view; 
       myEffect.Projection = projection; 

       myEffect.EnableDefaultLighting(); 
       myEffect.SpecularColor = new Vector3(0.25f); 
       myEffect.SpecularPower = 16; 
      } 

      myMesh.Draw(); 
     } 
    } 

내가 잘못 가고있는 곳을 누구나 찾아 낼 수 있습니까? 그것은 Draw()에서 두 가지 유형의 회전을 수행하기 때문입니까?

는 myEffect.World 변환 = [myMesh.ParentBone.Index * Matrix.CreateRotationY (회전) * Matrix.CreateFromQuaternion (ModelRotation) * Matrix.CreateTranslation (위치);

+1

코드에 깊게 파고 들지 않으면, 나를 때리는 첫 번째 일은 (바보 일 수 있음) 행렬의 순서입니다. 나는 쿼터니언이 번역 후에 있어야한다고 생각합니다. 이것은 아마도 그것을 고칠 수는 없지만 한번 시도해 볼 가치가 있습니다. – annonymously

+0

고마움, 아픈이 시도를주고 당신이 어떻게 일어나는지 알려주십시오. – heyred

+0

아니, 그 속임수도하지 못해서 미안해. 상자와 절두체를위한 두 개의 다른 Draw() 메서드를 시도해보십시오 (절두체 그리기의 상자 그리기 및 Quartenion 회전의 일반적인 회전). 그리고 이것이 어떻게 진행되는지보십시오. – heyred

답변

4

Quaternion.CreateFromAxisAngle(Vector3. UnitY, rotation)과 같은 정적 작성 메소드를 사용하여 Quaternions를 만드는 것이 가장 좋습니다. Quaternion의 X, Y, Z 및 W 값은 어떤 식 으로든 위치와 관련이 없습니다. 편리한 정적 메서드는 까다로운 수학을 처리합니다.

상황에 따라 상자가 회전 할 때 상자의 동일한면을 가리키는 절두체를 유지하려는 것처럼 보이므로 상자에 대한 절두체가 회전합니다. 그리기 방법에서 수행 된 번역에 약간 다른 접근 방식이 필요합니다.

오브젝트를 다른 오브젝트에 대해 회전하려면 먼저 원하는 회전의 중심이 원점에 오도록 오브젝트를 변환해야합니다.그런 다음 객체를 회전하고 첫 번째 단계와 동일한 양만큼 다시 번역합니다.

상황에 따라 다음과 같이해야합니다 (테스트되지 않은 예제 코드).

// Construct the objects 

boxObject.Position = new Vector3(10, 10, 10); 
boxObject.Rotation = 45.0f; 

frustumObject.Position = new Vector3(0, 0, 50f); // Note: this will be relative to the box (makes the math a bit simpler) 
frustumObject.TargetPosition = boxObject.Position; 
frustumObject.ModelRotation = Quaternion.CreateFromAxisAngle(Vector3. UnitY, boxObject.Rotation); // Note: this rotation angle may need to be in radians. 


// Box Draw() 
// Draw the box at its position, rotated about its centre. 
myEffect.World = transforms[myMesh.ParentBone.Index] * Matrix.CreateTranslation(Position) * Matrix.CreateRotationY(Rotation); 

// Frustum Draw() 
// Draw the frustum facing the box and rotated about the boxes centre. 
myEffect.World = transforms[myMesh.ParentBone.Index] * Matrix.CreateTranslation(Position) * Matrix.CreateFromQuaternion(ModelRotation) * Matrix.CreateTranslation(TargetPosition); 

가정 :

  • 상자가
  • 절두체 박스에 직면 유지하고 상자의 중심을 중심으로 회전 자신의 중심을 중심으로 회전

희망 이것은 도움이됩니다.