Fork me on GitHub
Not signed in (Sign In)
    • CommentAuthordesunit
    • CommentTimeAug 11th 2010 edited
     
    I've noticed a strange bug with Flint particle system together with Away3D. If you place Emitter3D in quite long length from camera then an emiter won't be initialized correctly and the starting position appeard offset from the set position. It looks like the Emitter3D jumps from one point to another. Here you are quick steps to reproduce it (once you run it - click the left mouse button on the screen). I'm using the version from trunk and the latest Away3D. Any ideas where I can fix it?

    Main.as:
    package
    {
    import away3d.containers.View3D;
    import away3d.core.math.Number3D;

    import org.flintparticles.threeD.away3d.Away3DRenderer;
    import org.flintparticles.threeD.emitters.Emitter3D;

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.*;

    [SWF(width='400', height='400', frameRate='61', backgroundColor='#000000')]

    public class Main extends Sprite
    {
    private var view:View3D;
    private var renderer:Away3DRenderer;
    private var emitter : Emitter3D = null;

    public function Main()
    {
    view = new View3D({x:200,y:200});
    view.camera.y = 150;
    view.camera.z = 1000;
    view.camera.lookAt( new Number3D( 0, 0, 0 ) );
    addChild(view);
    renderer = new Away3DRenderer( view.scene );

    addEventListener( Event.ENTER_FRAME, render, false, 0, true );
    stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    }


    private function onMouseDown( ev:Event ):void
    {
    if (emitter != null) { emitter.stop(); renderer.removeEmitter(emitter); }
    emitter = new Explosion(new Number3D(-100, 0, -5000));
    emitter.start( );
    renderer.addEmitter( emitter );
    }

    private function render( ev:Event ):void
    {
    // render the view
    view.render();
    }

    }
    }


    Explosion.as:
    package
    {
    import away3d.core.math.Number3D;

    import org.flintparticles.common.actions.*;
    import org.flintparticles.common.counters.*;
    import org.flintparticles.common.energyEasing.Quadratic;
    import org.flintparticles.common.initializers.*;
    import org.flintparticles.common.displayObjects.RadialDot;
    import org.flintparticles.threeD.actions.*;
    import org.flintparticles.threeD.emitters.Emitter3D;
    import org.flintparticles.threeD.geom.Point3D;
    import org.flintparticles.threeD.geom.Vector3D;
    import org.flintparticles.threeD.initializers.*;
    import org.flintparticles.threeD.zones.*;

    import org.flintparticles.threeD.away3d.initializers.A3DDisplayObjectClass;


    public class Explosion extends Emitter3D
    {
    public function Explosion(position:Number3D)
    {
    super();
    counter = new Blast( 20 );

    addInitializer( new Position( new PointZone( new Point3D(position.x, position.y, position.z) ) ) );
    addInitializer( new ColorInit( 0xFF99FFFF, 0xFFFFFFFFF ) );
    addInitializer( new Velocity( new SphereZone( Point3D.ZERO, 250 ) ) );
    addInitializer( new Lifetime( 0.5 ) );
    addInitializer( new A3DDisplayObjectClass( RadialDot, 50 ) );

    addAction( new Age( Quadratic.easeOut ) );
    addAction( new Move( ) );
    }
    }
    }
    • CommentAuthordesunit
    • CommentTimeAug 15th 2010
     
    I've spent more time on this and found that the problem lays somewhere in Position Initializer. The following line works perfectly and smoothly:

    addInitializer( new Position( new PointZone( new Point3D(-100, 0, 0) ) ) );

    But once Z value is increased till 2000:

    addInitializer( new Position( new PointZone( new Point3D(-100, 0, 2000) ) ) );

    jumps are appeared again. I think something is wrong with initial projection (the first value before interation), maybe you can guide where to start looking at that problem?

    Thanks!
    • CommentAuthorRichard
    • CommentTimeAug 15th 2010 edited
     
    Hi

    I've been looking into this today but unfortunately haven't found the solution.

    The projection is handled by Away3d, so if you want to check out the projection you'll need to delve into the Away3d source code. Flint simply uses the properties of the particle to set the properties of an Away3d object and leaves Away3d to handle the rendering.

    I believe the jump is happening at all distances. The further the distance from the camera (or origin - I'm not sure which), the greater the jump so the more obvious it is.

    To me, it looks like Away3d is rendering the particles once in a default position, perhaps (0,0,0), before then rendering them in their correct position. I'm not sure about this, and I'm not saying it's Away3d's fault, it's just what the effect looks like to me. I've tried adjusting the code that copies the particle's properties to the Away3d object, which is in the Away3dRenderer class, but to no effect.

    Tracking the position of the particle as recorded in the particle class and transfered to the Away3d object shows there is nothing wrong with the position property of the particle object in the first or subsequent frame of the effect.

    Also, the jump doesn't occur when rendering the same effect using either the Papervision3D renderer or Flint's internal renderer.

    The only solution would seem to be delving deeply into Away3d to figure out what is happening when the particle is rendered to screen, something I haven't time to do at the moment. If you get any further with this or find a solution please do let me know.

    If you continue to investigate please do continue to ask questions and let me know what you find. I'll help where I can.
    • CommentAuthordesunit
    • CommentTimeAug 16th 2010 edited
     
    Thanks Richard!

    After long reviewing of Away3D internals, I've finally found the problem. The problem is related to aligning of MovieClipSprite which default value is "center" and Away3d tries to align it according to that option and also I've noticed some Z-ordering issues which were fixed with ownCanvas option. The whole fix looks pretty simple and located in A3DDisplayObjectClass.intialize:

    /**
    * @inheritDoc
    */
    override public function initialize( emitter:Emitter, particle:Particle ):void
    {
    particle.image = new MovieClipSprite( construct( _imageClass, _parameters ), { rescale:true, align : "none", ownCanvas : true } );
    }
    • CommentAuthorRichard
    • CommentTimeAug 17th 2010
     
    Great find. Thank you. I've added the fix to SVN.