在3D中反转旋转,使对象始终面向相机?
我有很多在三维空间排列的精灵,他们的父容器有旋转应用。 我如何反转精灵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/,但曾经如此成功
感谢您的帮助。
最简单的方法是“清算”的变换矩阵的旋转部分。典型的同质转型看起来是这样的
| 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 |
加载这个矩阵可以绘制相机对准精灵。
道歉提前为这是一个建议,而不是一个解决方案:
如果你的目的是模拟3D球旋转,你的最简单的途径是放弃了2.5D API,只需使用简单的缩放和正弦/余弦计算定位。
一个有趣的地方开始:http://www.reflektions.com/miniml/template_permalink.asp?id=329
我认为它更容易使用随Flashplayer 10(displayobjects的.z属性)一起提供的3D API - 这允许在3D空间中轻松定位。如果我在1-2天内没有找到解决方案,请用sin/cos计算模拟旋转,或者绝对使用zedbox – sydd 2011-03-29 20:18:21
。这两种方法有不同的'外观',因为当使用'z'或任何特定于轴的旋转时,displayObjects被转换为位图。检查Matrix3D.invert()方法。 – NickHubben 2011-03-29 21:02:31
我已经使用*,矩阵和黑魔法解决它。我选择实现自定义旋转而不是反转所有对象的旋转。如果任何人有兴趣 继承人的代码:
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;
}
}
}
好的,问题是:你如何得到任何特定对象的“全局”矩阵,如你所描述的那样操纵它,然后将它设置回这个精灵? AFAIK,你不能设置一个“全局”转换矩阵到一个对象,只有一个“本地”的! “pointAt”Matrix3D方法能解决这个问题吗? – 2012-10-02 19:28:22
@BillKotsias:您有责任跟踪场景中物体的变换矩阵。你通常有某种转换层次:'view·t_1·t_2·t_3 ...'。这是你的“全局”转换矩阵。现在,如果你想在这个转换链中画一些物体,但是使它面对相机,你可以采用这种复合矩阵并按照我所描述的方式进行改变。实际上,这只是将视图中的对象转换为视图中的正确位置,而不会将其从“相机”中移开。 – datenwolf 2012-10-02 19:34:59
我完全不理解这一点。它只会缩放物体并将其移动一段距离,但它不会“定向”平面,使其面向相机(它面向相机,因为平面的法线与一条线平行从相机的原点到飞机的中心)。 – user18490 2015-01-17 13:55:25