In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Flash Tip collection 12 : Basic use of drawTriangle and Matrix3D

Basic use of drawTriangle and Matrix3D.
(Sorry for indentation, i am copying the source code from flashdevelop)
Get Adobe Flash player
by YoupSolo 13 Oct 2015

    Talk

    spanvega at 12 Oct 2015 17:38
    line 187 must be write, otherwise the framerate drops quickly due to a memory lack
    YoupSolo at 13 Oct 2015 23:23
    thx :)
    Embed
/**
 * Copyright YoupSolo ( http://wonderfl.net/user/YoupSolo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wTOe
 */

package
{

    import flash.display.BitmapData;

    import flash.display.DisplayObjectContainer;

    import flash.display.Sprite;

    import flash.display.StageAlign;

    import flash.display.StageScaleMode;

    import flash.events.Event;

    import flash.display.TriangleCulling;

    import flash.events.Event;

    import flash.geom.Matrix3D;

    import flash.geom.Vector3D;    

    import flash.text.TextField;

    import flash.text.TextFieldAutoSize;

    import flash.text.TextFormat;

    

    /**

     * 

     * @author YopSolo

     */


     public class Main extends Sprite 

    {

        private const FRAMERATE:int = 30;        

        private var _stageW:int;

        private var _stageH:int;

        private var _halfStageW:int;

        private var _halfStageH:int;        

        

        private var _texture:BitmapData;

        private var _model:Mesh3D;

        private var _transform:Matrix3D;



        /**

        * Constructor. Centers sprite, creates model and texture

        */

        public function Main() 

        {

            

            if (stage)

                init();

            else

                addEventListener(Event.ADDED_TO_STAGE, init);                

        }

        

        private function init(e:Event = null):void 

        {

            removeEventListener(Event.ADDED_TO_STAGE, init);

            

            

            // config stage

            stage.align = StageAlign.TOP_LEFT;

            stage.scaleMode = StageScaleMode.NO_SCALE;

            //stage.quality = StageQuality.MEDIUM;

            stage.stageFocusRect = false;

            stage.tabChildren = false;

            

            stage.frameRate = FRAMERATE;

            

            _stageW = stage.stageWidth;

            _stageH = stage.stageHeight;

            _halfStageW = _stageW >> 1;

            _halfStageH = _stageH >> 1;

            

            // add custom menu

            new CustomMenu(this);

            

            // run app            

            run();            

        }

        

        // == APP ==

        private function run():void

        {

            buildTextField(this, 'TIP 12 : Basic use of drawTriangle and Matrix3D', (2-_halfStageW)>>0, (2-_halfStageH)>>0);

            

            x = _halfStageW;

            y = _halfStageH;

            

            _texture = new XORTexture(256, 256);

            _model = new PyramidMesh(this);

            // creates initial 3D transform

            _transform = new Matrix3D();

            

            addEventListener( Event.ENTER_FRAME, _oef);            

        }

        

        

        /**

         * Draws the 3D model to the screen using drawTriangles().

         */

        private function render():void {

            // applies current transform to the model

            _model.applyTransform(_transform);

            this.graphics.clear(); /*thx !*/
            this.graphics.beginFill(0x333333,1);
            this.graphics.drawRect(-_halfStageW ,-_halfStageH,_stageW, _stageH);
            this.graphics.endFill();

            this.graphics.beginBitmapFill(_texture);

            this.graphics.drawTriangles(

                _model.vertices,

                _model.sides,

                _model.uvtData,

                TriangleCulling.NEGATIVE

            );

            this.graphics.endFill();

        }

        /**

         * onEnterFrame

         * @param    event

         */

        private function _oef(event:Event):void {

            _transform.appendRotation(2, Vector3D.Y_AXIS);

            render();

        }

        

        

        // == COMMON ==        

        private function buildTextField(doc:DisplayObjectContainer, txt:String, x:int = 0, y:int = 0):TextField

        {

            var fmt:TextFormat = new TextFormat;

            fmt.color = 0xFFFFFF;

            fmt.font = 'Arial'; //(new FONT_HARMONY() as Font).fontName;

            fmt.size = 11; // 8;

            

            var tf:TextField = new TextField;

            tf.autoSize = TextFieldAutoSize.LEFT;

            tf.opaqueBackground = 0x333333; // opaque background allow a perfect font rendering even in StageQuality.LOW mode

            tf.selectable = false;

            //tf.embedFonts = true;

            tf.defaultTextFormat = fmt;

            tf.text = txt;

            tf.x = x;

            tf.y = y;

            

            doc.addChild(tf);

            

            return tf;

        }        

        

    }

    

}





import flash.display.DisplayObject;

import flash.geom.Matrix3D;

import flash.geom.Point;

import flash.geom.Vector3D;



/**

* Abstract base class for 3D models. This holds the untransformed vertices, sides and UVT data,

* then can convert the 3D vertices into 2D coordinates to be rendered on the screen.

*/

 class Mesh3D {



    private var _vertices:Vector.<Number>;

    private var _container3D:DisplayObject;



    protected var _vectors:Vector.<Vector3D>;

    protected var _sides:Vector.<int>;

    protected var _uvtData:Vector.<Number>;



    /**

    * Constructor. This saves a reference to the parent container of the model for

    * use in transforming coordinates into the parent coordinate space, as well

    * as calls the createMesh() method to initialize all of the model properties.

    *

    * @param container The container display object in which the model will be rendered.

    */

    public function Mesh3D(container:DisplayObject) {

        _container3D = container;

        createMesh();

    }



    /**

    * Abstract method to be overridden by concrete child classes.

    * This should initialize all of the vertices, sides and UVT data.

    */

    protected function createMesh():void {}



    /**

    * Transforms a 3D vector into a 2D screen coordinate.

    *

    * @param vector The 3D vector to convert.

    *

    * @return The 2D coordinate in the parent container's coordinate space.

    */

    private function getPoint2D(vector:Vector3D):Point {

        var point:Point = _container3D.local3DToGlobal(vector);

        return _container3D.globalToLocal(point);

    }



    /**

    * Applies the specified matrix transform to the vertices in the model.

    * This is non-destructive, creating a separate list of transformed vertices.

    *

    * @param matrix The 3D matrix transform to apply to the model.

    */

    public function applyTransform(matrix:Matrix3D):void {

        _vertices = new Vector.<Number>();

        var vertex:Point;

        var transformedVector:Vector3D;

        // run through each vertex

        for each (var vector:Vector3D in _vectors) {

            // transforms the vector using the matrix transform

            transformedVector = matrix.deltaTransformVector(vector);

            // converts the transformed 3D point to a 2D screen coordinate

            vertex = getPoint2D(transformedVector);

            // separates point into separate x and y properties, as required by drawTriangles()

            _vertices.push(vertex.x, vertex.y);

        }

    }



    /**

    * Returns the 2D coordinates that can be used to draw the 3D model.

    * This returns the vertices in the form required by drawTriangles().

    *

    * @return The 2D coordinates that can be used to draw the 3D model.

    */

    public function get vertices():Vector.<Number> {

        return _vertices;

    }



    /**

    * Returns the sides data that can be used to draw the 3D model.

    * This returns the sides in the form required by drawTriangles().

    *

    * @return The sides that can be used to draw the 3D model.

    */

    public function get sides():Vector.<int> {

        return _sides;

    }



    /**

    * Returns the UVT data that can be used to texture the 3D model.

    * This returns the data in the form required by drawTriangles().

    *

    * @return The UVT data that can be used to texture the 3D model.

    */

    public function get uvtData():Vector.<Number> {

        return _uvtData;

    }



}





import flash.display.DisplayObject;

import flash.geom.Vector3D;



/**

* Class holding 3D values for pyramid model.

*/

class PyramidMesh extends Mesh3D {



    /**

    * Constructor. Calls super's contructor.

    *

    * @param container The object in which the model will be rendered.

    */

    public function PyramidMesh(container:DisplayObject) {

        super(container);

    }



    /**

    * Initializes all the values needed to render the model,

    * including vertices, sides and uvt data.

    */

    override protected function createMesh():void {

        _vectors = new Vector.<Vector3D>();

        _vectors.push(new Vector3D(0, -100, 0));

        _vectors.push(new Vector3D(130, 100, 130));

        _vectors.push(new Vector3D(130, 100, -130));

        _vectors.push(new Vector3D(-130, 100, -130));

        _vectors.push(new Vector3D(-130, 100, 130));



        _sides = new Vector.<int>();

        _sides.push(0, 1, 2);

        _sides.push(0, 2, 3);

        _sides.push(0, 3, 4);

        _sides.push(0, 4, 1);



        _uvtData = new Vector.<Number>();

        _uvtData.push(0.5, 0.5);

        _uvtData.push(0, 1);

        _uvtData.push(0, 0);

        _uvtData.push(1, 0);

        _uvtData.push(1, 1);

    }



}





// create the XOR texture

import flash.display.BitmapData;



class XORTexture extends BitmapData

{   

    public function XORTexture(width:int, height:int)

    {

        super(width, height, false, 0x0);

        var color:uint;

        var rbg_color:uint;

        

        for (var w:int = 0; w < width; w++)

        {

            for (var h:int = 0; h < height; h++)

            {

                color = w ^ h;

                rbg_color = color << 16 | color << 8 | color;

                this.setPixel(w, h, rbg_color);

            }

        }

    }

}





import flash.display.Sprite;

import flash.events.ContextMenuEvent;

import flash.net.navigateToURL;

import flash.net.URLRequest;

import flash.ui.ContextMenu;

import flash.ui.ContextMenuItem;



class CustomMenu

{

    

    private const NAME:String = "Flash Tips Collection : 'Basic use of drawTriangle and Matrix3D'";

    

    public function CustomMenu(ref:Sprite):void

    {

        var appContextMenu:ContextMenu = new ContextMenu;

        appContextMenu.hideBuiltInItems();

        

        var cmi:ContextMenuItem = new ContextMenuItem(NAME);

        var credits:ContextMenuItem = new ContextMenuItem("by YopSolo");

        appContextMenu.customItems.push(cmi);

        appContextMenu.customItems.push(credits);

        

        cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, _onClickCollection);

        credits.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, _onClickCredits);

        

        ref.contextMenu = appContextMenu;

    }

    

    private function _onClickCollection(e:ContextMenuEvent):void

    {

        navigateToURL(new URLRequest('http://www.yopsolo.fr/wp/2012/01/14/flash-tips-collection/'), '_blank');

    }

    

    private function _onClickCredits(e:ContextMenuEvent):void

    {

        navigateToURL(new URLRequest('http://www.yopsolo.fr'), '_blank');

    }

}