8

我從Molehill開始,在掌握Matrix3D時遇到了很多問題。 我的第一個問題是如何管理描述單個模型方向的Matrix3D。如何在模型的局部空間(不是全局的)中結合X,Y和Z旋轉?

我使用Matrix3D.appendRotation()來執行此操作。但取決於我追加的順序,我得到了不同的結果(顯然,因爲我在全球空間中每次旋轉一個)。 我知道這是一個常見問題,我已經遇到了它與3D軟件建模。但是這一次,我必須通過編程來修復它。這是我需要幫助的地方。

首先,萬一有任何混淆,這裏是圖片的問題:

第1步:我渲染模型。

Start position

步驟2a:我旋轉它在X軸。 看起來正確!

X-axis rotation

步驟2b:我旋轉它在Z軸。 看起來正確!

Z-axis rotation

所以......如果我在模型上的X軸和Z軸旋轉,我想

desired XZ rotation

但是,sadface,我得到這個:

我可以的問題。我在全球空間中一次一個追加循環。我需要在對象的本地空間中旋轉。我不知道如何做到這一點,或者我應該尋找什麼(術語等)。該代碼是簡單的(錯誤):

modelLocalMatrix.identity(); 
modelLocalMatrix.appendRotation(modelZRot, Vector3D.Z_AXIS); 
modelLocalMatrix.appendRotation(modelXRot, Vector3D.X_AXIS); 
//eventually y-axis rotation as well... 
renderMatrix.append(modelLocalMatrix); 

我猜測,而不是使用的Vector3D軸常量,我想用一些單位向量和一些......呃,東西...在地方modelZRot的,modelXRot,並最終modelYRot。任何人都可以告訴我什麼是最佳實踐解決方案適用於以上所需類型的旋轉?

更新:花了一天時間點擊「書籍」(也稱爲YouTube上的KhanAcademy)並從此演示文稿開始:The Mathematics of the 3d Rotation Matrix我偶然發現了一種非常接近我期望的解決方案的「看」方法。不幸的是,我只有50%瞭解它。我仍然希望有人能夠闡明這個話題!

var angleOfRotation:Number = Math.PI/2; //90 degrees... 
var axisOfRotation:Vector3D = new Vector3D(0, 1, 0); //some point to look at... 
//normalize the vector! 
axisOfRotation.normalize(); 
var x:Number = axisOfRotation.x; 
var y:Number = axisOfRotation.y; 
var z:Number = axisOfRotation.z; 
var c:Number = Math.cos(angleOfRotation); 
var s:Number = Math.sin(angleOfRotation); 
var t:Number = 1 - c; 

//Graphics Gems (Glassner, Academic Press, 1990). 
modelLocalMatrix = new Matrix3D(new <Number>[ 
    t * (x * x) + c, t * x * y - s * z, t * x * z + s * y, 0, 
    t * x * y + s * z, t * (y * y) + c, t * y * z - s * x, 0, 
    t * x * z - s * y, t * y * z + s * x, t * (z * z) + c, 0, 
    0,   0,   0,   1 
]); 

事情是,這似乎很笨重。特別是因爲Vector3D的旋轉角度應該是第四(w)值。更重要的是,Matrix3D已經看起來有一個lookAt()方法。我還沒有得到它......請別人救我幾個小時的試驗和錯誤!

回答

2

好的,我基本上已經想通了如何做到這一點。這比我做得更簡單。它也有助於審查Matrix3D API(它有一些非常棒的功能!)。

首先,我用來旋轉在其局部軸我的模型的源代碼:

var raw:Vector.<Number> = modelLocalMatrix.rawData; 
var right:Vector3D = new Vector3D(raw[0], raw[1], raw[2]); 
var up:Vector3D = new Vector3D(raw[4], raw[5], raw[6]); 
var out:Vector3D = new Vector3D(raw[8], raw[9], raw[10]); 

modelLocalMatrix.appendRotation(modelXRot, right); 
modelLocalMatrix.appendRotation(modelYRot, up); 
modelLocalMatrix.appendRotation(modelZRot, out); 

「向上」,「右」和「出」歸一化矢量在我原來的鏈接討論帖子。它們基本上是模型的俯仰,偏航和滾轉軸。只需要說,初始化對象時,這些向量與Vector3D.X_AXIS,Y_AXIS和Z_AXIS相同。我已經使用Matrix3D.rawData屬性提取它們,儘管可能有更好的方法。

現在,您可以根據您的選擇沿着這些軸中的任何一個進行旋轉,但是您所做的瞬間,其他兩個軸的方向會立即發生變化。這是有道理的。你的模型已經旋轉了,它的「正確」,「向上」和「向前」現在是不同的!所以如果你從模型的「右」軸開始旋轉(記住,這和全局的X_AXIS開始一樣),然後你想在你的「out」軸上滾動你的模型,你需要從模型的本地矩陣。顯然,它不再像全球的Z_AXIS一樣。請注意,我不打電話給Matrix3D.identity()。如果我這樣做了,那麼我的模型的軸將被重置!這對我的渲染循環來說是好的,儘管我必須改變我的代碼(以及思考方式),因爲我在應用轉換和旋轉之前重置了所有的矩陣。請注意,modelXRot,modelYRot和modelZRot以度爲單位存儲旋轉值。

我當然希望這可以幫助別人。我無法相信這樣一個簡單解決方案的常見問題無處可尋。無論如何,它肯定會做我想做的事。

相關問題