Notes for learning Flex 4. The goal is to use Away3D as the container for Flex 4 components, so that the 3D elements can affect Flex 4 components (e.g., rotating a cube with Flex 4 version of VideoPlayer on each side).


Phase 4


Getting it moving
Movement in Away3D is not exactly straightforward using MD2. And, as of this writing, the Away3D MD2 class is being changed.

Still, here are the details on how I got it working. From reading the source code for the MD2 class, I (finally) figured out that within every MD2 class, Away3D sets up a “default” animation. If the MD2 does not have a list of animations, the “default” animation is loaded with all of the frames found in the MD2. However, the defaultAnimation object is private; how can I play the animation? Fabrice Closier, one of the creators of Away3D, in this post lays out the new way of doing things (this will probably be in the documentation soon.) Essentially, it’s this code:

private function setAnimation(animationName:String):void
{
    var animd:AnimationData = testHorse.animationLibrary.getAnimation(animationName);
    if(animd)
    {
        trace("Playing animation: " + animationName);
        var myAnim:VertexAnimator = animd.animator as VertexAnimator;
        myAnim.delay = 0;
        myAnim.loop = true;
        myAnim.fps = 5;
        myAnim.interpolate = true;
        myAnim.play();
    }
    else
    {
        trace("Animation name not found: " + animationName);
    }
}

I think it is pretty clear what is going on, but let me know if it needs any clarification. Note that myAnim.play() will NOT actually show the animation. It still relies on the view.render() command to change the appearance of the world. So the horse is actually running, but it’s appearance will only gets updated on every frame. This could create some choppy animations, unless the math between frames and myAnim.fps works out.

Code:
The new MD2Import.as file. Note that I also embedded the image file in this version.

package
{
    import away3d.animators.VertexAnimator;
    import away3d.containers.View3D;
    import away3d.core.base.Mesh;
    import away3d.core.math.Number3D;
    import away3d.lights.AmbientLight3D;
    import away3d.loaders.Md2;
    import away3d.loaders.data.AnimationData;
    import away3d.materials.BitmapMaterial;
    
    import flash.display.Bitmap;
    import flash.events.Event;
    
    import mx.core.UIComponent;
    
    public class MD2Import extends UIComponent
    {
        private var view:View3D;
        private var sceneLight:AmbientLight3D;
        
        private var testHorse:Mesh;
        
        [Embed (source="horse.md2", mimeType="application/octet-stream")]
        public static const Model:Class;
        
        [Embed (source="horse.jpg")]
        public static const ModelTextureImage:Class;
        
        public function MD2Import()
        {
            super();
            this.addEventListener(Event.ENTER_FRAME, onFrameEnter);
        }
        
        override protected function createChildren():void
        {
            super.createChildren();
            
            if(!this.view)
            {
                this.view = new View3D();
                
                this.view.camera.moveTo(0, 0, -1500);
                this.view.camera.lookAt(new Number3D(0, 0, 0));
                
            }
            try
            {
                this.getChildIndex(this.view);
            }
            catch (e:Error)
            {
                this.addChild(this.view);
            }
            
            if(!this.testHorse)
            {
                this.testHorse = Md2.parse(new Model());
                this.testHorse.name = "horseModel";
                testHorse.material = new BitmapMaterial(Bitmap(new ModelTextureImage()).bitmapData); //BitmapFileMaterial("horse.jpg");
                
                testHorse.scaleX = 0.01;
                testHorse.scaleY = 0.01;
                testHorse.scaleZ = 0.01;
                testHorse.rotationX = 45;
                
                setAnimation("default");
            }
            try
            {
                if(this.view.scene.getChildByName(this.testHorse.name) == null)
                    this.view.scene.addChild(this.testHorse);
            }
            catch (e:Error)
            {
                this.view.scene.addChild(this.testHorse);
            }
            
            this.view.render();
        }
        
        private function setAnimation(animationName:String):void
        {
            var animd:AnimationData = testHorse.animationLibrary.getAnimation(animationName);
            if(animd)
            {
                trace("Playing animation: " + animationName);
                var myAnim:VertexAnimator = animd.animator as VertexAnimator;
                myAnim.delay = 0;
                myAnim.loop = true;
                myAnim.fps = 5;
                myAnim.interpolate = true;
                myAnim.play();
            }
            else
            {
                trace("Animation name not found: " + animationName);
            }
        }
        
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            
            if(this.width / 2 != this.view.x)
                this.view.x = this.width / 2;
            if(this.height / 2 != this.view.y)
                this.view.y = this.height / 2;
        }
        
        private function onFrameEnter(event:Event):void
        {
            if(this.view && this.view.stage)
            {
                this.view.render();
            }
        } 
    }
}

Please continue to Away3D in Flex 4 – Phase 5.

– 30 –

Advertisements