2012-11-18 68 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); 
} 
... 

而且現在的draw()方法:

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(); 
} 

編輯: 恐怕無論是我搞砸的地方了,或者你的tehnique做不工作,這就是我所做的。每當我移動整個對象(父)時,我將其Vector3 Position;設置爲該新值。我還將每個MeshProperties Vector3 Position;設置爲該值。然後裏面CreateMatrix() MeshProperties我不喜歡這樣的:

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

其中:

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)); 
} 

RotationVector3RotationMatrixTransform都在構造函數中設置爲Matrix.Identity

問題是,如果我嘗試圍繞例如Y軸旋轉,他應該在「靜止不動」時旋轉一圈。但他在旋轉的同時四處移動。

回答

1

問題是,當我將模型導出爲.FBX時,支點不在模型中心。從而使模型在旋轉時移動。

1

我不完全確定這是你想要的。我假設你有一個對象,其中一些網格物體和位置與主對象位置的位置和方向有偏移,並且你希望圍繞它的本地軸相對於父對象旋轉子對象。

Matrix.CreateTranslation(-Parent.Position) *     //Move mesh back... 
Matric.CreateTranslation(-Mesh.PositionOffset) *    //...to object space 

Matrix.CreateFromAxisAngle(Mesh.LocalAxis, AngleToRotateBy) * //Now rotate around your axis 
Matrix.CreateTranslation(Mesh.PositionOffset) *    //Move the mesh... 
Matrix.CreateTranslation(Parent.Position);     //...back to world space 

當然,你通常存儲,其將來自對象空間到世界空間的網格在一個步驟中的變換矩陣,並且還希望存儲的倒數。您還將網格始終存儲在對象座標中,並僅將其移至世界座標進行渲染。這將簡化事情有點:

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

我想你可以簡單地在你的例子設置Mesh.Transform到這一點,並準備就緒。

我希望這是你正在尋找的!

+0

其實,所有的網格都有相同的位置。我知道這聽起來很奇怪,但它正確地吸引了他們,並不是都在一個地方。我不知道如何可能,任何想法如何?順便說一句,你可以pleease解釋一下這些變量代表:(** Mesh.LocalAxis **,** objectToWorldTransform **和** Parent.Position **)? – user1806687

+0

那麼你說過「圍繞世界軸旋轉它,而不是它的局部軸」,所以mesh.LocalAxis就是你想要旋轉的任何軸! ObjectToWorldTransform是一個從對象空間轉換到世界空間的矩陣,即scale * rotate * translate。 Parent.Position是網格的父的位置,這聽起來像你正在使用多個網格,以表示一個對象,其中parent.Position將是對象的位置,而不是任何特定的網格。 – Martin