2011-03-29 51 views
5

我有很多在三維空間排列的精靈,他們的父容器有旋轉應用。 我如何反轉精靈3D旋轉,他們總是面對相機(Actionscript 3)?在3D中反轉旋轉,使對象始終面向相機?

繼承人的代碼進行測試:

package{ 
import flash.display.Sprite; 
import flash.events.Event; 
public class test extends Sprite{ 

var canvas:Sprite = new Sprite(); 
var sprites:Array = [] 

public function test(){ 
    addChild(canvas) 
    for (var i:int=0;i<20;i++){ 
     var sp:Sprite = new Sprite(); 
     canvas.addChild(sp); 
     sp.graphics.beginFill(0xFF0000); 
     sp.graphics.drawCircle(0,0,4); 
     sp.x = Math.random()*400-200; 
     sp.y = Math.random()*400-200; 
     sp.z = Math.random()*400-200; 
     sprites.push(sp); 
    } 
    addEventListener(Event.ENTER_FRAME,function():void{ 
     canvas.rotationX++; 
     canvas.rotationY = canvas.rotationY+Math.random()*2; 
     canvas.rotationZ++; 
     for (var i:int=0;i<20;i++){ 
      //this is not working... 
      sprites[i].rotationX = -canvas.rotationX 
      sprites[i].rotationY = -canvas.rotationY 
      sprites[i].rotationZ = -canvas.rotationZ 
     } 
    }) 
} 
} 
} 

我猜我必須做一些與魔法精靈的rotation3D矩陣... 我試圖執行這個腳本:http://ughzoid.wordpress.com/2011/02/03/papervision3d-sprite3d/,但曾經如此成功
感謝您的幫助。

回答

17

最簡單的方法是「清算」的變換矩陣的旋轉部分。典型的同質轉型看起來是這樣的

| xx xy xz xw | 
| yx yy yz yw | 
| zx zy zz zw | 
| wx wy wz ww | 

與WX = WY = WZ = 0,WW = 1。如果你仔細看,你會看到,實際上這個矩陣是由一個3x3的子矩陣定義的旋轉,3子向量的翻譯和均勻排0 0 0 1

| R  T | 
| (0,0,0) 1 | 

對於要保留翻譯,但擺脫了旋轉,即R = I的情況下,一些廣告牌/精靈規模應用,身份需要被縮放。

這給出以下recipie:

d = SQRT(xx²+yx²+zx²)

| d 0 0 T.x | 
| 0 d 0 T.y | 
| 0 0 d T.z | 
| 0 0 0 1 | 

加載這個矩陣可以繪製相機對準精靈。

+0

好的,問題是:你如何得到任何特定對象的「全局」矩陣,如你所描述的那樣操縱它,然後將它設置回這個精靈? AFAIK,你不能設置一個「全局」轉換矩陣到一個對象,只有一個「本地」的! 「pointAt」Matrix3D方法能解決這個問題嗎? – 2012-10-02 19:28:22

+0

@BillKotsias:您有責任跟蹤場景中物體的變換矩陣。你通常有某種轉換層次:'view·t_1·t_2·t_3 ...'。這是你的「全局」轉換矩陣。現在,如果你想在這個轉換鏈中畫一些物體,但是使它面對相機,你可以採用這種複合矩陣並按照我所描述的方式進行改變。實際上,這只是將視圖中的對象轉換爲視圖中的正確位置,而不會將其從「相機」中移開。 – datenwolf 2012-10-02 19:34:59

+0

我完全不理解這一點。它只會縮放物體並將其移動一段距離,但它不會「定向」平面,使其面向相機(它面向相機,因爲平面的法線與一條線平行從相機的原點到飛機的中心)。 – user18490 2015-01-17 13:55:25

1

道歉提前爲這是一個建議,而不是一個解決方案:

如果你的目的是模擬3D球旋轉,你的最簡單的途徑是放棄了2.5D API,只需使用簡單的縮放和正弦/餘弦計算定位。

一個有趣的地方開始:http://www.reflektions.com/miniml/template_permalink.asp?id=329

+0

我認爲它更容易使用隨Flashplayer 10(displayobjects的.z屬性)一起提供的3D API - 這允許在3D空間中輕鬆定位。如果我在1-2天內沒有找到解決方案,請用sin/cos計算模擬旋轉,或者絕對使用zedbox – sydd 2011-03-29 20:18:21

+0

。這兩種方法有不同的'外觀',因爲當使用'z'或任何特定於軸的旋轉時,displayObjects被轉換爲位圖。檢查Matrix3D.invert()方法。 – NickHubben 2011-03-29 21:02:31

1

我已經使用維基百科,矩陣和黑魔法解決它。我選擇實現自定義旋轉而不是反轉所有對象的旋轉。如果任何人有興趣 繼承人的代碼:

package{ 
import flash.display.Sprite; 
import flash.events.Event; 

public class test extends Sprite{ 

private var canvas:Sprite = new Sprite(); 
private var sprites:Array = [] 
private var rotx:Number=0,roty:Number=0,rotz:Number=0; 
private var mm:Matrix3 = new Matrix3(); 
public function test(){ 
    addChild(canvas); 
    canvas.x = canvas.y = 230 
    for (var i:int=0;i<30;i++){ 
     var sp:Sprite = new Sprite(); 
     canvas.addChild(sp); 
     sp.graphics.beginFill(0xFF0000); 
     sp.graphics.drawCircle(0,0,2); 
     sp.x = Math.random()*200-100; 
     sp.y = Math.random()*200-100; 
     sp.z = Math.random()*200-100; 
     sprites.push(sp); 
     rotx=0.06; //from top to bottom 
     //roty=0.1; //from right to left 
     rotz=0.1; //clockwise 
     mm.make3DTransformMatrix(rotx,roty,rotz); 
    } 
    addEventListener(Event.ENTER_FRAME,function():void{ 
     for (var i:int=0;i<sprites.length;i++){ 
      var s:Sprite = sprites[i]; 
      mm.rotateByAngles(s); 
     } 
    }) 
} 
} 
} 

和matrix3類:要做到這一點

public class Matrix3{ 

    private var da:Vector.<Number>; // rows 

    public function make3DTransformMatrix(rotx:Number,roty:Number,rotz:Number):void{ 
     var cosx:Number = Math.cos(rotx); 
     var cosy:Number = Math.cos(roty); 
     var cosz:Number = Math.cos(rotz); 
     var sinx:Number = Math.sin(rotx); 
     var siny:Number = Math.sin(roty); 
     var sinz:Number = Math.sin(rotz); 
     da = new <Number>[ 
      cosy*cosz, -cosx*sinz+sinx*siny*cosz, sinx*sinz+cosx*siny*cosz, 
      cosy*sinz, cosx*cosz+sinx*siny*sinz , -sinx*cosz+cosx*siny*sinz, 
      -siny ,   sinx*cosy  ,  cosx*cosy   ]; 
    } 

    public function rotateByAngles(d:DisplayObject):void{ 
     var dx:Number,dy:Number,dz:Number; 
     dx = da[0]*d.x+da[1]*d.y+da[2]*d.z; 
     dy = da[3]*d.x+da[4]*d.y+da[5]*d.z; 
     dz = da[6]*d.x+da[7]*d.y+da[8]*d.z; 
     d.x = dx; 
     d.y = dy; 
     d.z = dz; 
    } 
} 
}