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

みかん

視錐台の挙動確認
@author Masayuki Komatsu
http://sekiryou.com/
http://twitter.com/sekiryou_com
/**
 * Copyright sekiryou ( http://wonderfl.net/user/sekiryou )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/AfcR
 */

/**
* みかん
* 視錐台の挙動確認
* @author Masayuki Komatsu
* http://sekiryou.com/
* http://twitter.com/sekiryou_com
*/
package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.GradientType;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.SpreadMethod;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.geom.PerspectiveProjection;
    import flash.geom.Rectangle;
    import flash.geom.Utils3D;
    import flash.geom.Vector3D;
    import com.bit101.components.CheckBox;
    
    [SWF(width = 465, height = 465, backgroundColor = 0x000000, frameRate = 30)]
    
    public class ViewFrustumTest extends Sprite {
        private const TOTAL_OBJECT:int = 1;
        private var projection:PerspectiveProjection;
        private var projectionMatrix3D:Matrix3D;
        private var mtx3D:Matrix3D = new Matrix3D();
        private var mtx3DIdentity:Vector.<Number> = mtx3D.rawData;
        private var projectedVerts:Vector.<Number> = new Vector.<Number>();
        private var indexList:Vector.<int> = new Vector.<int>();
        private var uvtList:Vector.<Number> = new Vector.<Number>();
        private var mtrx:Matrix = new Matrix();
        private var screen:Sprite = new Sprite();
        private var texture:BitmapData;
        private var vf:ViewFrustum;
        private var frame:Sprite = new Sprite();
        
        private var objectList:Vector.<Mikan> = new Vector.<Mikan>();
        private var vfinList:Vector.<Mikan> = new Vector.<Mikan>();
        
        public function ViewFrustumTest() {
            graphics.beginFill(0x000000);
            graphics.drawRect(0, 0, 465, 465);
            graphics.endFill();
            addEventListener(Event.ADDED_TO_STAGE, init);
        }
        private function init(e:Event = null):void {
            projection = new PerspectiveProjection();
            //projection.fieldOfView = 40;
            projection.focalLength = 640;
            projectionMatrix3D = projection.toMatrix3D();
            screen = new Sprite();
            addChild(screen);
            screen.x = 232.5;
            screen.y = 232.5;
            
            //ViewFrustum
            const near:Number = -800;
            const far:Number = 800;
            vf = new ViewFrustum(projection.focalLength, near, far, 300 * 0.5, 300 * 0.5);
            
            texturePrepare();
            
            //ObjectGenerate
            for (var i:int = 0; i < TOTAL_OBJECT; i++ ) {
                var tmp:Mikan = new Mikan();
                screen.addChild(tmp);
                tmp.buttonMode = false;
                tmp.mouseChildren = false;
                objectList.push(tmp);
                
                tmp.px = 0;
                tmp.py = 0;
                tmp.pz = 0;
            }
            
            var maskSizeX:Number = 2400;
            var maskSizeY:Number = 1200;
            var frameSize:Number = 300;
            frame.graphics.beginFill(0x003333);
            frame.graphics.drawRect(maskSizeX * -0.5 + frameSize * 0.5, maskSizeY * -0.5 + frameSize * 0.5, maskSizeX, maskSizeY);
            frame.graphics.drawRect(465 * 0.5 - frameSize * 0.5, 465 * 0.5 - frameSize * 0.5, frameSize, frameSize);
            frame.graphics.endFill();
            addChild(frame);
            frame.visible = false;
            graphics.lineStyle(0, 0x880000);
            graphics.drawRect(465 * 0.5 - frameSize * 0.5, 465 * 0.5 - frameSize * 0.5, frameSize, frameSize);
            
            var checkBox:CheckBox = new CheckBox(this, 20, 20, "Mask", function(e:Event):void {
                frame.visible = e.currentTarget.selected
            });
            
            addEventListener(Event.ENTER_FRAME, update);
        }
        private function texturePrepare():void {
            var tmpShape:Shape = new Shape();
            var g:Graphics = tmpShape.graphics;
            for (var i:int = 0; i <= 200; i++) {
                for (var j:int = 0; j <= 200; j++) {
                    g.beginFill(0xAA4400);
                    g.drawEllipse(i * 2.1 + Math.random() * 4 - 8, j * 2.1 + Math.random() * 4 - 8, Math.random() * 0.3 + 1.0, Math.random() * 0.6 + 2.0);
                    g.endFill();
                }
            }
            
            var textureSize:Number = 400;
            texture = new BitmapData(textureSize, textureSize, false, 0xBB5500);
            var mtrx:Matrix = new Matrix();
            mtrx.createGradientBox(200, 200, -3.1415926 / 2, 0, 0);
            var spreadMethod:String = SpreadMethod.PAD;
            tmpShape.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0x000000], [0.3, 0.0], [0x00, 0xFF], mtrx);
            tmpShape.graphics.drawRect(0, 0, textureSize, textureSize);
            texture.draw(tmpShape);
            tmpShape = null;
            
            var leaf:BitmapData = new BitmapData(textureSize * 0.2, textureSize * 0.2, false, 0x003300);
            texture.draw(leaf, new Matrix(1, 0, 0, 1, textureSize - textureSize * 0.2, textureSize - textureSize * 0.2));
        }
        private var tmpIndices:Vector.<int> = new Vector.<int>();
        private var wfIndices:Vector.<int> = new Vector.<int>();
        private var tmpUvts:Vector.<Number> = new Vector.<Number>();
        private var offsetX:Number = 0;
        private var offsetY:Number = 0;
        private var offsetZ:Number = -640;
        private var rotX:Number = 0;
        private var rotY:Number = 0;
        private var rotZ:Number = 0;
        private var count:Number = -640;
        private function update(e:Event = null):void {
            var i:int
            var j:int
            var len:int;
            
            count += 4;
            if (count > 480) {
                count -= 960;
                rotX = Math.random() * 180 - 360;
                rotY = Math.random() * 180 - 360;
                rotZ = Math.random() * 180 - 360;
            }
            
            //
            vfinList.length = 0;
            len = objectList.length;
            for (i = 0; i < len; i++) {
                objectList[i].cVertices.length = 0;
                objectList[i].graphics.clear();
                
                objectList[i].rx += objectList[i].tx;
                objectList[i].ry += objectList[i].ty;
                objectList[i].rz += objectList[i].tz;
                
                //World
                mtx3D.rawData = mtx3DIdentity;
                mtx3D.appendRotation(objectList[i].rx, Vector3D.X_AXIS);
                mtx3D.appendRotation(objectList[i].ry, Vector3D.Y_AXIS);
                mtx3D.appendRotation(objectList[i].rz, Vector3D.Z_AXIS);
                mtx3D.appendTranslation(count, 0, 0);
                //Camera
                //mtx3D.appendTranslation(-offsetX, -offsetY, -offsetZ);
                //mtx3D.appendRotation(-rotX, Vector3D.X_AXIS);
                //mtx3D.appendRotation(-rotY, Vector3D.Y_AXIS);
                //mtx3D.appendRotation(-rotZ, Vector3D.Z_AXIS);
                //mtx3D.transformVectors(objectList[i].vertices, objectList[i].cVertices);
                
                mtx3D.appendRotation(-rotX, Vector3D.X_AXIS);
                mtx3D.appendRotation(-rotY, Vector3D.Y_AXIS);
                mtx3D.appendRotation(-rotZ, Vector3D.Z_AXIS);
                mtx3D.appendTranslation(-offsetX, -offsetY, -offsetZ);
                mtx3D.transformVectors(objectList[i].vertices, objectList[i].cVertices);
                
                if (mtx3D.rawData[0] > 0) {
                    var minX:Number = objectList[i].cVertices[0] + mtx3D.rawData[0] * objectList[i].minX;
                    var maxX:Number = objectList[i].cVertices[0] + mtx3D.rawData[0] * objectList[i].maxX;
                } else {
                    minX = objectList[i].cVertices[0] + mtx3D.rawData[0] * objectList[i].maxX;
                    maxX = objectList[i].cVertices[0] + mtx3D.rawData[0] * objectList[i].minX;
                }
                if (mtx3D.rawData[1] > 0) {
                    var minY:Number = objectList[i].cVertices[1] + mtx3D.rawData[1] * objectList[i].minX;
                    var maxY:Number = objectList[i].cVertices[1] + mtx3D.rawData[1] * objectList[i].maxX;
                } else {
                    minY = objectList[i].cVertices[1] + mtx3D.rawData[1] * objectList[i].maxX;
                    maxY = objectList[i].cVertices[1] + mtx3D.rawData[1] * objectList[i].minX;
                }
                if (mtx3D.rawData[2] > 0) {
                    var minZ:Number = objectList[i].cVertices[2] + mtx3D.rawData[2] * objectList[i].minX;
                    var maxZ:Number = objectList[i].cVertices[2] + mtx3D.rawData[2] * objectList[i].maxX;
                } else {
                    minZ = objectList[i].cVertices[2] + mtx3D.rawData[2] * objectList[i].maxX;
                    maxZ = objectList[i].cVertices[2] + mtx3D.rawData[2] * objectList[i].minX;
                }
                
                if (mtx3D.rawData[4] > 0) {
                    minX += mtx3D.rawData[4] * objectList[i].minY;                maxX += mtx3D.rawData[4] * objectList[i].maxY;
                } else {
                    minX += mtx3D.rawData[4] * objectList[i].maxY;            maxX += mtx3D.rawData[4] * objectList[i].minY;
                }
                if (mtx3D.rawData[5] > 0) {
                    minY += mtx3D.rawData[5] * objectList[i].minY;                maxY += mtx3D.rawData[5] * objectList[i].maxY;
                } else {
                    minY += mtx3D.rawData[5] * objectList[i].maxY;            maxY += mtx3D.rawData[5] * objectList[i].minY;
                }
                if (mtx3D.rawData[6] > 0) {
                    minZ += mtx3D.rawData[6] * objectList[i].minY;                maxZ += mtx3D.rawData[6] * objectList[i].maxY;
                } else {
                    minZ += mtx3D.rawData[6] * objectList[i].maxY;            maxZ += mtx3D.rawData[6] * objectList[i].minY;
                }
                
                if (mtx3D.rawData[8] > 0) {
                    minX += mtx3D.rawData[8] * objectList[i].minZ;                maxX += mtx3D.rawData[8] * objectList[i].maxZ;
                } else {
                    minX += mtx3D.rawData[8] * objectList[i].maxZ;            maxX += mtx3D.rawData[8] * objectList[i].minZ;
                }
                if (mtx3D.rawData[9] > 0) {
                    minY += mtx3D.rawData[9] * objectList[i].minZ;                maxY += mtx3D.rawData[9] * objectList[i].maxZ;
                } else {
                    minY += mtx3D.rawData[9] * objectList[i].maxZ;            maxY += mtx3D.rawData[9] * objectList[i].minZ;
                }
                if (mtx3D.rawData[10] > 0) {
                    minZ += mtx3D.rawData[10] * objectList[i].minZ;            maxZ += mtx3D.rawData[10] * objectList[i].maxZ;
                } else {
                    minZ += mtx3D.rawData[10] * objectList[i].maxZ;            maxZ += mtx3D.rawData[10] * objectList[i].minZ;
                }
                
                //BoundingBoxCheck
                //if (
                    //vf.nearA * maxX + vf.nearB * maxZ + vf.nearC <= 0 &&
                    //vf.farA * maxX + vf.farB * minZ + vf.farC <= 0 &&
                    //vf.leftA * maxX + vf.leftB * maxZ + vf.leftC >= 0 &&
                    //vf.rightA * minX + vf.rightB * maxZ + vf.rightC <= 0 &&
                    //vf.topA * maxY + vf.topB * maxZ + vf.topC >= 0 &&
                    //vf.bottomA * minY + vf.bottomB * maxZ + vf.bottomC <= 0
                //) {
                    vfinList.push(objectList[i]);
                    //
                    //if (
                        //vf.nearA * minX + vf.nearB * minZ + vf.nearC <= 0 &&
                        //vf.farA * maxX + vf.farB * maxZ + vf.farC <= 0 &&
                        //vf.leftA * minX + vf.leftB * maxZ + vf.leftC >= 0 &&
                        //vf.rightA * maxX + vf.rightB * maxZ + vf.rightC <= 0 &&
                        //vf.topA * minY + vf.topB * maxZ + vf.topC >= 0 &&
                        //vf.bottomA * maxY + vf.bottomB * maxZ + vf.bottomC <= 0
                    //) {
                        //objectList[i].isAllIn = true;
                    //} else {
                        //objectList[i].isAllIn = false;
                    //}
                //}
            }
            
            vfinList.sort(
                function(p1:Object, p2:Object):Number {
                    return p2.cVertices[2] - p1.cVertices[2];
                }
            );
            
            var g:Graphics = screen.graphics;
            g.clear();
            
            len = vfinList.length;
            for (i = 0; i < len; i++) {
                tmpIndices.length = 0;
                wfIndices.length = 0;
                tmpUvts = vfinList[i].uvts;
                projectedVerts.length = 0;
                
                var len2:int = vfinList[i].mesh.length;
                for (j = 0; j < len2; j++) {
                    vfinList[i].mesh[j].c = vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 2 >> 0];
                    if (vfinList[i].mesh[j].c < vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0]) {
                        vfinList[i].mesh[j].c = vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0];
                    }
                    if (vfinList[i].mesh[j].c < vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0]) {
                        vfinList[i].mesh[j].c = vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0];
                    }
                }
                
                vfinList[i].mesh.sort(
                    function(p1:Polygon, p2:Polygon):Number {
                        return p2.c - p1.c;
                    }
                );
                
                len2 = vfinList[i].mesh.length;
                for (j = 0; j < len2; j++) {
                    if (
                        (
                            vfinList[i].isAllIn
                        ) ||
                        (
                        vf.nearA * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 0 >> 0] + vf.nearB * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 2 >> 0] + vf.nearC <= 0 &&
                        vf.farA * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 0 >> 0] + vf.farB * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 2 >> 0] + vf.farC <= 0 &&
                        vf.leftA * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 0 >> 0] + vf.leftB * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 2 >> 0] + vf.leftC >= 0 &&
                        vf.rightA * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 0 >> 0] + vf.rightB * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 2 >> 0] + vf.rightC <= 0 &&
                        vf.topA * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 1 >> 0] + vf.topB * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 2 >> 0] + vf.topC >= 0 &&
                        vf.bottomA * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 1 >> 0] + vf.bottomB * vfinList[i].cVertices[vfinList[i].mesh[j].i0 * 3 + 2 >> 0] + vf.bottomC <= 0
                        ) ||
                        (
                        vf.nearA * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 0 >> 0] + vf.nearB * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0] + vf.nearC <= 0 &&
                        vf.farA * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 0 >> 0] + vf.farB * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0] + vf.farC <= 0 &&
                        vf.leftA * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 0 >> 0] + vf.leftB * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0] + vf.leftC >= 0 &&
                        vf.rightA * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 0 >> 0] + vf.rightB * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0] + vf.rightC <= 0 &&
                        vf.topA * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 1 >> 0] + vf.topB * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0] + vf.topC >= 0 &&
                        vf.bottomA * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 1 >> 0] + vf.bottomB * vfinList[i].cVertices[vfinList[i].mesh[j].i1 * 3 + 2 >> 0] + vf.bottomC <= 0
                        ) ||
                        (
                        vf.nearA * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 0 >> 0] + vf.nearB * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0] + vf.nearC <= 0 &&
                        vf.farA * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 0 >> 0] + vf.farB * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0] + vf.farC <= 0 &&
                        vf.leftA * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 0 >> 0] + vf.leftB * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0] + vf.leftC >= 0 &&
                        vf.rightA * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 0 >> 0] + vf.rightB * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0] + vf.rightC <= 0 &&
                        vf.topA * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 1 >> 0] + vf.topB * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0] + vf.topC >= 0 &&
                        vf.bottomA * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 1 >> 0] + vf.bottomB * vfinList[i].cVertices[vfinList[i].mesh[j].i2 * 3 + 2 >> 0] + vf.bottomC <= 0
                        )
                    ) {
                        tmpIndices.push(
                            vfinList[i].mesh[j].i0,
                            vfinList[i].mesh[j].i1,
                            vfinList[i].mesh[j].i2
                        );
                    } else {
                        wfIndices.push(
                            vfinList[i].mesh[j].i0,
                            vfinList[i].mesh[j].i1,
                            vfinList[i].mesh[j].i2
                        );
                    }
                }
                
                mtx3D.rawData = mtx3DIdentity;
                mtx3D.append(projectionMatrix3D);
                Utils3D.projectVectors(mtx3D, vfinList[i].cVertices, projectedVerts, tmpUvts);
                
                screen.setChildIndex(vfinList[i], i + 0);
                g = vfinList[i].graphics;
                
                if (wfIndices.length > 0) {
                    g.lineStyle(0, 0x009966);
                    g.drawTriangles(projectedVerts, wfIndices, tmpUvts, "none");
                    g.lineStyle();
                }
                
                if (tmpIndices.length > 0) {
                    g.beginBitmapFill(texture);
                    g.drawTriangles(projectedVerts, tmpIndices, tmpUvts, "negative");
                    g.endFill();
                    
                }
            }
        }
    }
}

import flash.geom.Vector3D;
class ViewFrustum {
    public var vertices:Vector.<Number> = new Vector.<Number>();
    public var leftA:Number, leftB:Number, leftC:Number;
    public var rightA:Number, rightB:Number, rightC:Number;
    public var topA:Number, topB:Number, topC:Number;
    public var bottomA:Number, bottomB:Number, bottomC:Number;
    public var nearA:Number, nearB:Number, nearC:Number;
    public var farA:Number, farB:Number, farC:Number;
    public function ViewFrustum(focalLength:Number, near:Number, far:Number, w:Number, h:Number) {
        if (near < -focalLength) near = -focalLength;
        var nearSizeW:Number = (near + focalLength) * Math.tan(w / focalLength);
        var nearSizeH:Number = (near + focalLength) * Math.tan(h / focalLength);
        var farSizeW:Number = (far + focalLength) * Math.tan(w / focalLength);
        var farSizeH:Number = (far + focalLength) * Math.tan(h / focalLength);
        
        vertices.push(0, 0, 0);
        vertices.push( -nearSizeW, -nearSizeH, near + focalLength);
        vertices.push( -nearSizeW, nearSizeH, near + focalLength);
        vertices.push(nearSizeW, -nearSizeH, near + focalLength);
        vertices.push(nearSizeW, nearSizeH, near + focalLength);
        vertices.push( -farSizeW, -farSizeH, far + focalLength);
        vertices.push( -farSizeW, farSizeH, far + focalLength);
        vertices.push(farSizeW, -farSizeH, far + focalLength);
        vertices.push(farSizeW, farSizeH, far + focalLength);
        
        leftA = (far + focalLength) - (near + focalLength);
        leftB = farSizeW - nearSizeW;
        leftC = -leftB * (near + focalLength) + leftA * nearSizeW;
        
        rightA = (far + focalLength) - (near + focalLength);
        rightB = -farSizeW + nearSizeW;
        rightC = -rightB * (near + focalLength) - rightA * nearSizeW;
        
        topA = (far + focalLength) - (near + focalLength);
        topB = farSizeH - nearSizeH;
        topC = -topB * (near + focalLength) + topA * nearSizeH;
        
        bottomA = (far + focalLength) - (near + focalLength);
        bottomB = -farSizeH + nearSizeH;
        bottomC = -bottomB * (near + focalLength) - bottomA * nearSizeH;
        
        nearA = (near + focalLength) - (near + focalLength);
        nearB = -nearSizeW - nearSizeW;
        nearC = -nearB * (near + focalLength) + nearA * nearSizeW;
        
        farA = (far + focalLength) - (far + focalLength);
        farB = farSizeW + farSizeW;
        farC = -farB * (far + focalLength) - farA * farSizeW;
    }
}

import flash.display.Sprite;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
class Mikan  extends Sprite {
    public var isAllIn:Boolean;
    public var c:Number = 0;
    public var px:Number;
    public var py:Number;
    public var pz:Number;
    public var vx:Number;
    public var vy:Number;
    public var vz:Number;
    public var rx:Number = Math.random() * 360;
    public var ry:Number = Math.random() * 360;
    public var rz:Number = Math.random() * 360;
    public var tx:Number = Math.random() * 2 - 1;
    public var ty:Number = Math.random() * 2 - 1;
    public var tz:Number = Math.random() * 2 - 1;
    public var vertices:Vector.<Number> = new Vector.<Number>();
    public var wVertices:Vector.<Number> = new Vector.<Number>();
    public var cVertices:Vector.<Number> = new Vector.<Number>();
    public var indices:Vector.<int> = new Vector.<int>();
    public var uvts:Vector.<Number> = new Vector.<Number>();
    public var mesh:Vector.<Polygon> = new Vector.<Polygon>();
    
    public var minX:Number = Number.MAX_VALUE;
    public var maxX:Number = Number.MIN_VALUE;
    public var minY:Number = Number.MAX_VALUE;
    public var maxY:Number = Number.MIN_VALUE;
    public var minZ:Number = Number.MAX_VALUE;
    public var maxZ:Number = Number.MIN_VALUE;
    
    public function Mikan() {
        init();
    }
    
    private function init():void {
        //Center
        vertices.push(0, 0, 0);
        uvts.push(null, null, null);
        //BoundingBox
        vertices.push(null, null, null);
        vertices.push(null, null, null);
        vertices.push(null, null, null);
        vertices.push(null, null, null);
        vertices.push(null, null, null);
        vertices.push(null, null, null);
        vertices.push(null, null, null);
        vertices.push(null, null, null);
        uvts.push(null, null, null);
        uvts.push(null, null, null);
        uvts.push(null, null, null);
        uvts.push(null, null, null);
        uvts.push(null, null, null);
        uvts.push(null, null, null);
        uvts.push(null, null, null);
        uvts.push(null, null, null);
        const hDiv:int = 24;
        const vDiv:int = 12;
        const hr:Number = 80;
        const vr:Number = 60;
        var sid:int = 9;
        var mtx3D:Matrix3D = new Matrix3D();
        var vv:Vector.<Number> = new Vector.<Number>();
        for (var i:uint = 0; i <= hDiv; i++) {
            vv.length = 0;
            for (var j:uint = 0; j <= vDiv; j++) {
                vv.push(
                    Math.sin(j / vDiv * Math.PI) * hr,
                    Math.cos(j / vDiv * Math.PI) * vr,
                    0
                );
                
                uvts.push(i / hDiv * 0.6 + 0.1, j / vDiv * 0.6 + 0.1, 1);
                if (j < vDiv && i < hDiv) {
                    var a:uint =  i * (vDiv + 1) + j;
                    var b:uint = (i + 1) * (vDiv + 1) + j;
                    
                    indices.push(
                        b + sid, a + 1 + sid, a + sid,
                        a + 1 + sid, b + sid, b + 1 + sid
                    );
                }
            }
            mtx3D.identity();
            mtx3D.appendRotation(i * (360 /hDiv), Vector3D.Y_AXIS);
            mtx3D.transformVectors(vv, vv);
            vertices = vertices.concat(vv);
        }
        
        const w:Number = 5;
        const h:Number = 3;
        const h2:Number = vr + 0.8;
        const lw:Number = 16;
        const h3:Number = -0.4;
        sid = vertices.length / 3;
        vertices.push( -w, h + h2, -w);
        vertices.push( -w, 0 + h2, -w);
        vertices.push(w, h + h2, -w);
        vertices.push(w, 0 + h2, -w);
        vertices.push(w, h + h2, w);
        vertices.push(w, 0 + h2, w);
        vertices.push(-w, h + h2, w);
        vertices.push( -w, 0 + h2, w);
        vertices.push( -w, h + h2, -w);
        vertices.push( -w, 0 + h2, -w);
        vertices.push(-w, h + h2, w);
        vertices.push(w, h + h2, w);
        vertices.push(0, h2 + h3, -lw);
        vertices.push(lw, h2 + h3, 0);
        vertices.push(0, h2 + h3, lw);
        vertices.push(-lw, h2 + h3, 0);
        const u0:Number = 0.9;
        const v0:Number = 0.9;
        const u1:Number = 0.99;
        const v1:Number = 0.99;
        const u2:Number = 0.95;
        const v2:Number = 0.81;
        uvts.push(u0, v0, null);
        uvts.push(u0, v1, null);
        uvts.push(u1, v0, null);
        uvts.push(u1, v1, null);
        uvts.push(u0, v0, null);
        uvts.push(u0, v1, null);
        uvts.push(u1, v0, null);
        uvts.push(u1, v1, null);
        uvts.push(u0, v0, null);
        uvts.push(u0, v1, null);
        uvts.push(u0, v2, null);
        uvts.push(u1, v2, null);
        uvts.push(u2, v1, null);
        uvts.push(u2, v1, null);
        uvts.push(u2, v1, null);
        uvts.push(u2, v1, null);
        indices.push(sid + 0, sid + 1, sid + 3);
        indices.push(sid + 0, sid + 3, sid + 2);
        indices.push(sid + 2, sid + 3, sid + 5);
        indices.push(sid + 2, sid + 5, sid + 4);
        indices.push(sid + 4, sid + 5, sid + 7);
        indices.push(sid + 4, sid + 7, sid + 6);
        indices.push(sid + 6, sid + 7, sid + 9);
        indices.push(sid + 6, sid + 9, sid + 8);
        indices.push(sid + 0, sid + 11, sid + 10);
        indices.push(sid + 0, sid + 2, sid + 11);
        indices.push(sid + 3, sid + 1, sid + 12);
        indices.push(sid + 5, sid + 3, sid + 13);
        indices.push(sid + 7, sid + 5, sid + 14);
        indices.push(sid + 9, sid + 7, sid + 15);
        //BoundingBox
        var len:int = vertices.length;
        for (i = 27; i < len; i += 3) {
            if (minX > vertices[i + 0 >> 0]) {
                minX = vertices[i + 0 >> 0];
            } else if (maxX < vertices[i + 0 >> 0]) {
                maxX = vertices[i + 0 >> 0];
            }
            if (minY > vertices[i + 1 >> 0]) {
                minY = vertices[i + 1 >> 0];
            } else if (maxY < vertices[i + 1 >> 0]) {
                maxY = vertices[i + 1 >> 0];
            }
            if (minZ > vertices[i + 2 >> 0]) {
                minZ = vertices[i + 2 >> 0];
            } else if (maxZ < vertices[i + 2 >> 0]) {
                maxZ = vertices[i + 2 >> 0];
            }
        }
        vertices[3] = minX;            vertices[4] = minY;            vertices[5] = minZ;
        vertices[6] = minX;            vertices[7] = maxY;            vertices[8] = minZ;
        vertices[9] = maxX;            vertices[10] = minY;            vertices[11] = minZ;
        vertices[12] = maxX;        vertices[13] = maxY;            vertices[14] = minZ;
        vertices[15] = minX;            vertices[16] = minY;            vertices[17] = maxZ;
        vertices[18] = minX;            vertices[19] = maxY;            vertices[20] = maxZ;
        vertices[21] = maxX;        vertices[22] = minY;            vertices[23] = maxZ;
        vertices[24] = maxX;        vertices[25] = maxY;            vertices[26] = maxZ;
        
        len = indices.length;
        for (i = 0; i < len; i++) {
            if (i % 3 == 0) {
                var tmp:Polygon = new Polygon(
                    indices[i],
                    indices[i + 1 >> 0],
                    indices[i + 2 >> 0]
                );
                mesh.push(tmp);
            }
        }
    }
}

import flash.geom.Vector3D;
class Polygon {
    public var c:Number = 0;
    public var x:Number = 0;
    public var y:Number = 0;
    public var z:Number = 0;
    public var i0:int = 0;
    public var i1:int = 0;
    public var i2:int = 0;
    public function Polygon(i0:int, i1:int, i2:int) {
        this.i0 = i0;
        this.i1 = i1;
        this.i2 = i2;
    }
}