在3D中反转旋转,使对象始终面向相机?

时间:2011-03-29 01:41:46

标签: flash actionscript-3 3d

我在3D空间中排列了很多精灵,并且它们的父容器已经应用了旋转。 如何反转精灵3D旋转,他们总是面对相机(Actionscript 3)?

下载一个代码来测试它:

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

我猜我必须用sprites的rotation3D矩阵做一些魔术...... 我试图实现这个脚本:http://ughzoid.wordpress.com/2011/02/03/papervision3d-sprite3d/,但是取得了如此成功 谢谢你的帮助。

4 个答案:

答案 0 :(得分:20)

最简单的方法是“清除”变换矩阵的旋转部分。您典型的同质转换看起来像这样

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

wx = wy = wz = 0,ww = 1.如果仔细观察,你会发现实际上这个矩阵由一个定义旋转的3x3子矩阵,一个用于平移的3个子矢量和一个同质的矩阵组成。 row 0 0 0 1

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

对于广告牌/精灵,你想保留翻译,但摆脱旋转,即R = I.如果应用了一些缩放,身份也需要缩放。

这给出了以下收件人:

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

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

加载此矩阵可以绘制相机对齐的精灵。

答案 1 :(得分:1)

提前道歉,这是一个建议,而不是解决方案:

如果您的目的是模拟3D球形旋转,那么最简单的方法就是放弃2.5D API,只需使用简单的缩放和正弦/余弦计算进行定位。

一个有趣的起点:http://www.reflektions.com/miniml/template_permalink.asp?id=329

答案 2 :(得分: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;
    }
}
}

答案 3 :(得分:0)

enter image description here

如上图所示,右侧的摄像头设置为面向四边形(左侧),因此其法线正好相反。旋转摄像机时,为使四边形仍然具有相反的法线,必须将四边形沿与摄像机相同的角度沿相反的方向旋转。因此,我只需将四边形绕y轴旋转-camera.Yaw就可以产生正确的效果。