Closed lizhi525 closed 12 years ago
That weird. I investigated this for like 30 minutes and I can't get it... Logged internally as issue 383
Stilled, using rotationY += 0.1 is a VERY bad idea. You should rather use Matrix4x4.appendRotation(0.1, Vector4.Y_AXIS), which is much much faster (plus it works :p).
ok i will try this funciton.
http://game-develop.net/swfs/native3d/nobug.html
http://game-develop.net/swfs/native3d/bug.html
native is mine a small 3d engine http://code.google.com/p/native3d/
package { import flash.display.; import flash.events.; import flash.geom._; import flash.text.TextField; import net.gamedevelop.native3d.controllers.; import net.gamedevelop.native3d.core.; import net.gamedevelop.native3d.materials.; import net.game_develop.native3d.primitives.*;
/**
* ...
* @author sliz http://game-develop.net/blog/
*/
public class Main extends Sprite
{
private var view:View3D;
private var ctrl:FreeRotationController;
private var tf:TextField = new TextField;
private var bmd:BitmapData;
private var ob3d:Obj3D;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
addChild(tf);
removeEventListener(Event.ADDED_TO_STAGE, init);
view = new View3D(400, 400, -4000, this);
addEventListener(Event.ENTER_FRAME, update);
bmd = new BitmapData(200, 200,true,0x88ff0000);
var m1:BitmapMaterial = new BitmapMaterial(bmd);
var m2:LineMaterial = new LineMaterial(0,3);
var m:ComposeMaterial = new ComposeMaterial([m1,m2]);
var pm:PointMaterial = new PointMaterial;
var c:int = 1;
var w:Number = 800;
while (c-->0) {
ob3d = new Cube(pm, w, w, w);
ob3d.culling = TriangleCulling.NONE;
view.scene.add(ob3d);
}
ctrl = new FreeRotationController(ob3d);
}
private function update(e:Event):void
{
view.render();
ob3d.ry += .03;
//ob3d.recompose();
//ob3d.decompose();
tf.text = ob3d.ry + "";
}
}
}
if you add the code get the bug.
//ob3d.recompose(); //ob3d.decompose();
i think the rotation in the minko it is too big.
in the native3d
public function get sy():Number { return components[2].y; }
public function set sy(value:Number):void
{
changed = true;
components[2].y = value;
}
if (obj.changed) { obj.recompose(); }
It looks like the bug is not in the Matrix4x4.rotation getter/setter but rather in the flash_proxy::getProperty() method that can't work properly with the += here.
ddddd 91.6731584284725 Vector3D(1.5099580252808664e-7, 1.599998450279236, 1.5099580252808664e-7) 88.32683838425682 Vector3D(-3.141592502593994, 1.54159414768219, -3.141592502593994) ddddd 94.05641633556506 Vector3D(-3.141592502593994, 1.64159414768219, -3.141592502593994) 85.94358047716428 Vector3D(1.5099580252808664e-7, 1.4999984502792358, 1.5099580252808664e-7) ddddd 91.6731584284725 Vector3D(1.5099580252808664e-7, 1.599998450279236, 1.5099580252808664e-7) 88.32683838425682 Vector3D(-3.141592502593994, 1.54159414768219, -3.141592502593994)
package { import flash.display.Sprite; import flash.events.Event; import flash.geom.Matrix3D; import flash.geom.Orientation3D; import flash.geom.Vector3D; /** * ... * @author lizhi */ public class TestMatr extends Sprite { private var vec:Vector.; private var matr:Matrix3D; public function TestMatr() { matr = new Matrix3D; vec = matr.decompose(); vec[1].y = 1.4999984502792358; matr.recompose(vec); var vec2:Vector. = matr.decompose(); trace(vec2[1].y); addEventListener(Event.ENTER_FRAME, enterFrame); } private function enterFrame(e:Event):void { vec[1].y += .1; trace("ddddd"); trace(vec[1].y*180/Math.PI,vec[1]); matr.recompose(vec); vec = matr.decompose(); trace(vec[1].y*180/Math.PI,vec[1]); } } }
@promethe42
using rotationY += 0.1 is a VERY bad idea. You should rather use Matrix4x4.appendRotation
then why have rotationY at all?
The issue is not rotationY. The issue is the dynamic flash_proxy::getProperty() that works well when you try to access (chained) sub-properties - including method calls - but not when you try to use the actual getters/setters.
// works group.get('//mesh').transform.appendRotation(0.1, Vector4.Y_AXIS); // works group.get('//mesh').transform.rotationY = 0; // doesn't work group.get('//mesh').transform.rotationY += 0.1;
The Matrix4x4.rotationY is not the issue here. It is the fact that it is dyanmically called on a set of objects using the += operator. += operator implies to call the getter, but we're working with a set of objects in the form of a SceneIterator object here.
I think we should remove SceneIterator.flash_proxy::getProperty() and SceneIterator.flash_proxy::setProperty() and use a for each instead:
for each (var mesh : Mesh in group.get('//mesh')) mesh.transform.rotationY += 0.1;
a ha! so you could do ube.transform.rotationY = cube.transform.rotationY + .01; and it would still work, right?
If cube is a Mesh then there has never been any issue doing cube.transform.rotationY += 0.1 Again: the problem is not Matrix4x4.rotationY. The problem is dynamic getter/setters in SceneIterator. So if cube is a SceneIterator, your example still doesn't work because cube.transform.rotationY have an undefined behaviour.
Ok so here is the problem: we tried to use flash_proxy::getProperty() to be able to access (sub) properties of the object set and be able to write them. And it works when you only want to write them.
If you try to read them - and reading includes operators such as += or *= or course - it just can't work. There is no way to tell whether flash_proxy::getProperty() is called to:
For example, there is no practical difference between:
group.get('//mesh').transform
and
group.get('//mesh').transform.rotationY
The first line should return a SceneIterator so that we can continue working on a set of objects and make the second line possible. But doing so, it fails at returning a Matrix4x4 object so it cannot be read as such. That's why this dynamic class stuff can write a property on a set of objects, but not read it.
As there is no fix for this, we just removed the broken feature :( So now if you want to affect a property of the whole result set, you just have to use a "for each" statement:
for each (var mesh : Mesh in group.get('//mesh')) mesh.transform.rotationY += 0.1;
...and only now I understand that group.get('//mesh') referred to multiple objects :neutral_face:
ddddd 91.6731584284725 Vector3D(1.5099580252808664e-7, 1.599998450279236, 1.5099580252808664e-7) 88.32683838425682 Vector3D(-3.141592502593994, 1.54159414768219, -3.141592502593994) ddddd 94.05641633556506 Vector3D(-3.141592502593994, 1.64159414768219, -3.141592502593994) 85.94358047716428 Vector3D(1.5099580252808664e-7, 1.4999984502792358, 1.5099580252808664e-7) ddddd 91.6731584284725 Vector3D(1.5099580252808664e-7, 1.599998450279236, 1.5099580252808664e-7) 88.32683838425682 Vector3D(-3.141592502593994, 1.54159414768219, -3.141592502593994)
package { import flash.display.Sprite; import flash.events.Event; import flash.geom.Matrix3D; import flash.geom.Orientation3D; import flash.geom.Vector3D; /** * ... * @author lizhi */ public class TestMatr extends Sprite { private var vec:Vector.; private var matr:Matrix3D; public function TestMatr() { matr = new Matrix3D; vec = matr.decompose(); vec[1].y = 1.4999984502792358; matr.recompose(vec); var vec2:Vector. = matr.decompose(); trace(vec2[1].y); addEventListener(Event.ENTER_FRAME, enterFrame); } private function enterFrame(e:Event):void { vec[1].y += .1; trace("ddddd"); trace(vec[1].y*180/Math.PI,vec[1]); matr.recompose(vec); vec = matr.decompose(); trace(vec[1].y*180/Math.PI,vec[1]); } } }
the get set matrix3d have bug
This is not the same bug at all. The bug you described originally in this issue was about updating the rotation of a set of objects fetched using a SceneIterator via Group.get().
Matrix4x4 uses Matrix3D and - as such - it has the same flaws. I'll run my own test to see what happens.
[code lang='as3']package { import aerys.minko.example.core.cubes.NormalsShader; import aerys.minko.render.effect.Effect; import aerys.minko.render.Viewport; import aerys.minko.scene.controller.camera.ArcBallController; import aerys.minko.scene.node.Camera; import aerys.minko.scene.node.ISceneNode; import aerys.minko.scene.node.mesh.geometry.Geometry; import aerys.minko.scene.node.mesh.geometry.primitive.CubeGeometry; import aerys.minko.scene.node.mesh.Mesh; import aerys.minko.scene.node.Scene; import aerys.minko.type.math.Vector4; import flash.display.Sprite; import flash.events.Event;
}[/code]
the rotationY no effect