2012-11-18 2 views
0

게임에 몇 개의 메쉬가있는 객체가 있는데, 어느 방향 으로든 메쉬를 회전하려고하면 로컬 축이 아닌 월드 축 주위로만 회전합니다. 클래스 생성자에 rotation = Matrix.Identity이 있습니다. 모든 메쉬에는이 클래스가 첨부되어 있습니다. 지금XNA에서 로컬 축을 중심으로 메쉬를 회전하려면 어떻게해야합니까?

... 
public Matrix Transform{ get; set; } 
public void Rotate(Vector3 newRot) 
{ 
    rotation = Matrix.Identity; 
    rotation *= Matrix.CreateFromAxisAngle(rotation.Up, MathHelper.ToRadians(newRot.X)); 
    rotation *= Matrix.CreateFromAxisAngle(rotation.Right, MathHelper.ToRadians(newRot.Y)); 
    rotation *= Matrix.CreateFromAxisAngle(rotation.Forward, MathHelper.ToRadians(newRot.Z)); 

    CreateMatrix(); 
} 

private void CreateMatrix() 
{ 
    Transform = Matrix.CreateScale(scale) * rotation * Matrix.CreateTranslation(Position); 
} 
... 

그리고 그리기() 메소드 : : 그런 다음이 클래스는 메소드를 포함

foreach (MeshProperties mesh in model.meshes) 
{ 
    foreach (BasicEffect effect in mesh.Mesh.Effects)//Where Mesh is a ModelMesh that this class contains information about 
    { 
     effect.View = cam.view; 
     effect.Projection = cam.projection; 
     effect.World = mesh.Transform; 
     effect.EnableDefaultLighting(); 
    } 
    mesh.Mesh.Draw(); 
} 

편집 : 내가 두려워하거나 내가 어딘가 나사, 또는 기법을 이해가 않습니다 일하지 않으면, 내가 한 일이다. 전체 개체 (상위)를 이동할 때마다 해당 Vector3 Position;을 새 값으로 설정합니다. 또한 모든 MeshProperties Vector3 Position;을 해당 값으로 설정합니다. 그리고 내가 그렇게 좋아했다 MeshProperties의 CreateMatrix() 내부 :

public void Rotate(Vector3 newRot) 
{ 
    Rotation = newRot; 
    RotationMatrix = Matrix.CreateFromAxisAngle(Transform.Up,   MathHelper.ToRadians(Rotation.X)) * 
    Matrix.CreateFromAxisAngle(Transform.Forward, MathHelper.ToRadians(Rotation.Z)) * 
    Matrix.CreateFromAxisAngle(Transform.Right, MathHelper.ToRadians(Rotation.Y)); 
} 

그리고 RotationVector3입니다 :

... 
Transform = RotationMatrix * Matrix.CreateScale(x, y, z) * RotationMatrix * Matrix.CreateTranslation(Position) * Matrix.CreateTranslation(Parent.Position); 
... 

. RotationMatrixTransform은 모두 생성자에서 Matrix.Identity으로 설정됩니다.

예를 들어 Y 축을 중심으로 회전하려고하면 "서있는 동안"원에서 회전해야합니다. 그러나 그는 회전하면서 움직인다.

답변

1

문제는 모델을 .FBX로 내보낼 때 피벗 포인트가 모델 센터에 없었기 때문입니다. 따라서 모델이 회전하면서 움직입니다.

1

나는 이것이 당신이 원하는 것이라고 확신하지 않습니다. 저는 여러분이 객체를 가지고 있다고 가정합니다. 메인 객체 위치의 위치와 방향으로부터 오프셋 된 메쉬와 위치가 있습니다. 부모 객체에 대해 로컬 객체를 중심으로 자식 객체를 회전하려고합니다.

물론 개체 공간에서 월드 공간으로 메쉬를 한 단계로 변환하는 변환 행렬을 저장하고 그 역함수도 저장합니다. 또한 메쉬를 항상 오브젝트 좌표에 저장하고 렌더링을 위해 월드 좌표로만 이동시킵니다. 이 일을 조금 단순화 것 :

Matrix.CreateFromAxisAngle(Mesh.LocalAxis, AngleToRotateBy) * //We're already in object space, so just rotate 
ObjectToWorldTransform * 
Matrix.CreateTranslation(Parent.Position); 

난 당신이 단순히이에 예에 Mesh.Transform을 설정할 수 있다고 생각하고 모든 설정합니다.

이 정보가 도움이되기를 바랍니다.

+0

사실 모든 메쉬의 위치는 같습니다. 나는 그것이 이상하게 들린다는 것을 안다. 그러나 그것들을 정확하게 그리고 한 곳에서 모두 끌어들이지는 않는다. 나는 그것이 어떻게 가능한지, 어떤 생각을 모르는가? Btw는 이러한 변수가 나타내는 것을 약간 설명 할 수 있습니다 : ** Mesh.LocalAxis **, ** objectToWorldTransform ** 및 ** Parent.Position **)? – user1806687

+0

글쎄, "세계 축을 중심으로 회전하고 로컬 축은 회전시키지 않는다"고 했으므로, mesh.LocalAxis는 회전하고자하는 축이 무엇이든간에! ObjectToWorldTransform은 객체 공간에서 월드 공간으로 변환하는 행렬입니다 (예 : scale * rotate * translate). 부모 위치는 메쉬의 부모 위치입니다. 여러 메쉬를 사용하여 하나의 객체를 표현한 것처럼 보입니다. parent.Position은 특정 메쉬가 아닌 객체의 위치가됩니다. – Martin

관련 문제