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

FlatShading [Alternativa3D 7.6]

7.5では実装されていなかった、フラットシェーディングですが、7.6に実装される事を期待しつつ、とりあえず無理矢理実装してみました。

が、思った以上に重いです・・・

ちなみに、これは無理矢理MeshをFlatShadingしています。

Materialを継承してFlatShadingする場合は以下を参照ください。

http://marubayashi.net/alternativa3d7/labo/flatshadingmaterial/flatshadingmaterial.html


2011/01/12 7.5から7.6仕様に変更
Get Adobe Flash player
by narutohyper 23 Oct 2012
/**
 * Copyright narutohyper ( http://wonderfl.net/user/narutohyper )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/485b
 */

// forked from narutohyper's Alternativa3D 7.5 Template
package
{

    import alternativ7.engine3d.controllers.SimpleObjectController;
    import alternativ7.engine3d.core.Object3DContainer;
    import alternativ7.engine3d.loaders.MaterialLoader;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.materials.TextureMaterial;
    import alternativ7.engine3d.primitives.Box;
    import alternativ7.engine3d.primitives.GeoSphere;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.system.LoaderContext;    
    /**
     *
     * Alternativa3D 7.6
     *
     * フラットシェーディングを無理矢理実装してみる
     *
     * ...
     * @author narutohyper
     */
    [SWF(backgroundColor="#000000", frameRate="24", width="800", height="600")]
    public class Main extends Sprite
    {
        
        public function Main():void    {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event=null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
        
            //テスト表示
            var bm:Bitmap=new Bitmap();
            //Materialの作成
            addChild(bm);
            
            //AlternativaTemplate作成
            var scene:AlternativaTemplate = new AlternativaTemplate(this);
            addChild(scene.camera.diagram);


            

            
            //回転させる為のContainer
            var objectContainer:Object3DContainer = new Object3DContainer();
            scene.container.addChild(objectContainer);

            
            //色つき球
            var material:FillMaterial = new FillMaterial(0x0000FF);
            var sphere1:FlatShadingMesh = new FlatShadingMesh(new GeoSphere(200));
            sphere1.setMaterialToAllFaces(material);
            objectContainer.addChild(sphere1);
            sphere1.x = -300;
            sphere1.y = -200;

            
            //虎柄球
            var tigerMaterial:TextureMaterial = new TextureMaterial(null, false, true);
            tigerMaterial.diffuseMapURL = 'http://assets.wonderfl.net/images/related_images/2/23/239d/239d90e633f3ab0f3e95d18c0fab3200d4a2820cm';
            
            var textures:Vector.<TextureMaterial> = new Vector.<TextureMaterial>();
            textures[0] = tigerMaterial;
            var context:LoaderContext = new LoaderContext(true);
            var materialLoader:MaterialLoader = new MaterialLoader()
            materialLoader.load(textures,context);

            
            var sphere2:FlatShadingMesh = new FlatShadingMesh(new GeoSphere(200));
            sphere2.setMaterialToAllFaces(tigerMaterial);
            objectContainer.addChild(sphere2);
            sphere2.x = 300;
            sphere2.y = -200;
            
            
            //6面ぬり分けた箱
            var leftM:FillMaterial = new FillMaterial(0x0000FF);
            var rightM:FillMaterial = new FillMaterial(0xFF0000);
            var frontM:FillMaterial = new FillMaterial(0x00FF00);
            var backM:FillMaterial = new FillMaterial(0xFF00FF);
            var bottomM:FillMaterial = new FillMaterial(0xFFFF00);
            var topM:FillMaterial = new FillMaterial(0x666666);
            var test:Box = new Box(400, 400, 400, 1, 1, 1, false, false, leftM, rightM, backM, frontM, bottomM, topM);
            
            var box:FlatShadingBox = new FlatShadingBox(new Box(300,300,300,1,1,1,false,false,leftM,rightM,backM,frontM,bottomM, tigerMaterial));
            //sphere2.setMaterialToAllFaces(tigerMaterial);
            objectContainer.addChild(box);
            box.x = 0;
            box.y = 200;
    
            
            var RADIAN:Number = Math.PI / 180;
            
            var lightContainer:Object3DContainer = new Object3DContainer();
            scene.container.addChild(lightContainer);
            var light:Light = new Light(0xFFFFFF,0.8);
            lightContainer.addChild(light);
            lightContainer.rotationY = 30 * RADIAN;
            light.x = 400;
            
            //カメラの調整
            //カメラはControllerに関連付けている為、x,y,zで直接位置を指定できないので
            //SimpleController.setObjectPosXYZを使用
            scene.cameraController.setObjectPosXYZ(0,-1400,0);
            scene.cameraController.lookAtXYZ(0, 0, 0);
            //ObjectControllerの作成
            //MouseDragで、Objectを回転させる為のController
            var objectController:SimpleObjectController = new SimpleObjectController(stage,objectContainer,100);
            objectController.unbindAll();
            
            //描画開始

            var angle:Number=0;
            scene.onPreRender = function():void {
                objectController.update();
                angle+=3;
                light.x = Math.cos(angle * RADIAN) * 700;
                light.y = Math.sin(angle * RADIAN) * 700;
                //引数の2番目には、回転するObject3D
                sphere1.calculateLight(light,[objectContainer]);
                sphere2.calculateLight(light,[objectContainer]);
                box.calculateLight(light,[objectContainer]);

                //bm.bitmapData = sphere2.bmd;
            }
            scene.startRendering();

            

        }
        
        
        

    }
    
}


import alternativ7.engine3d.core.Face;
import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.materials.Material;
import alternativ7.engine3d.materials.TextureMaterial;
import alternativ7.engine3d.objects.Mesh;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.GraphicsEndFill;
import flash.display.GraphicsPath;
import flash.display.GraphicsSolidFill;
import flash.display.GraphicsStroke;
import flash.display.IGraphicsData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
/**
 *
 * MeshオブジェクトをFlatShadingする、Meshに変更するクラス
 * 全て同じMaterialをUVで用いる場合のみ有効
 * BoxやOriginalCylinderでは使えません。
 *
 * また、Bone付き、スキンも使えません
 *
 * @param    mesh
 */
class FlatShadingMesh extends Mesh
{
    //テスト表示できるように、とりあえずpublic
    private var _bmd:BitmapData;

    private var _texture:BitmapData;
    private var _materialType:String;
    private var _textureMaterial:TextureMaterial;
    private var _tempMaterial:TextureMaterial;
    private var _rect:Rectangle;
    private var _sp:Point;
    private var _loaded:Boolean = false;
    private var _count:int;
    private var _paths:Vector.<GraphicsPath>;
    private var _canvas:Sprite = new Sprite();
    private var _fills:Shape = new Shape();
    private var _lines:Shape = new Shape();
    private var _endFill:GraphicsEndFill = new GraphicsEndFill();
    private var _normals:Vector.<Number>;
    
    public function FlatShadingMesh(mesh:Mesh) {
        //引数のMeshのgeometryをコピー
        clonePropertiesFrom(mesh);
        _count = faces.length;
        _canvas.addChild(_lines);
        _canvas.addChild(_fills);
        _normals = new Vector.<Number>;
        var face:Face;
        var textured:Boolean = false;
        for (var i:int = 0; i < _count; i++)
        {
            face = faces[i];
            //面の法線を得る
            if (face.material && !textured) {
                setTexture(face.material);
                textured = true;
            }
            _normals[i*3] = face.normal.x;
            _normals[i*3+1] = face.normal.y;
            _normals[i*3+2] = face.normal.z;
        }
    }
    
    override public function setMaterialToAllFaces(material:Material):void {
        setTexture(material);
    }
    
    
    private function setPath():void
    {
        var count2:int;

        //高速化の為、Mesh.facesからではなくGeometryのorderedFaces
        //(DictionaryではなくVectorでcloneが帰ってくる)

        _paths = new Vector.<GraphicsPath>();
        var path:GraphicsPath;
        var face:Face;
        for (var i:int = 0; i < _count; i++)
        {
            face = faces[i];
            var commands:Vector.<int> = new Vector.<int>();
            var coords:Vector.<Number> = new Vector.<Number>();
            commands[0] = 1;
            coords[0] = face.vertices[0].u * _bmd.width;
            coords[1] = face.vertices[0].v * _bmd.height;
            
            //faceのUVを得る
            //注意!Face.verticesは、Vector
            count2 = face.vertices.length;
            for (var j:int = 1; j < count2; j++ ) {
                commands[j] = 2;
                coords[j * 2] = face.vertices[j].u * _bmd.width;
                coords[j * 2 + 1] = face.vertices[j].v * _bmd.height;
            }
            commands[j] = 2;
            coords[j * 2] = coords[0];
            coords[j * 2 + 1] = coords[1];
            path = new GraphicsPath(commands, coords);
            _paths.push(path);
        }
    }
    
    
    private function setTexture(material:Material):void {
        _tempMaterial = material as TextureMaterial;
        if (_tempMaterial) {
            _materialType = 'Texture';
            if (_tempMaterial.texture) {
                _texture = _tempMaterial.texture;
                _bmd = new BitmapData(_texture.width, _texture.height, true, 0xFF666666);
                _loaded = true;
            } else {
                _texture = new BitmapData(400, 400, false, 0);
                _bmd = new BitmapData(400, 400, false, 0);
            }
            
        } else {
            _materialType='Fill';
            _texture = new BitmapData(400, 400, false, FillMaterial(material).color);
            _bmd = new BitmapData(400, 400, false, FillMaterial(material).color);
        }

        _textureMaterial = new TextureMaterial(_bmd);
        super.setMaterialToAllFaces(_textureMaterial);
        _rect = _bmd.rect;
        _sp = new Point(0, 0);

        setPath();
    }
    
    

    /**
     *各フェイスのnormalを取り、光源との内積で影の強さを判断する
     *
     */
    public function calculateLight(light:Light,rotaObject:Array = null):void {
        //Textureをloadしている場合、load完了までは、仮のTexture
        //読み込まれて、適用された段階で反映する
        if (_materialType == 'Texture' && !_loaded && _tempMaterial.texture) {
            _texture = _tempMaterial.texture;
            _bmd = new BitmapData(_texture.width, _texture.height, true, 0xFF666666);
            _textureMaterial = new TextureMaterial(_bmd);
            super.setMaterialToAllFaces(_textureMaterial);
            _loaded = true;
            setPath();
        }

        var count2:int;
        //光源の位置ベクトル
        var lv:Vector3D = new Vector3D(light.x, light.y, light.z);
        lv = light.localToGlobal(lv);
        
        //自身の位置ベクトル
        var target:Vector3D = new Vector3D(x, y, z);
        target = localToGlobal(target);
        
        //光源に対する方向(単位ベクトル)
        var axis:Vector3D = lv.subtract(target);
        var m:Number = axis.normalize();
        
        //光源への距離(とりあえず距離は無視するけど)
        //var length:Number = Vector3D.distance(target,lv)
        _lines.graphics.clear();
        _fills.graphics.clear();
        var fillDrawing:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
        var lineDrawing:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
        
        //1フェースごとにMatrix変換は、負荷大なので、まとめて変換
        var v3:Vector.<Vector3D>;
        var mtr3D:Matrix3D = new Matrix3D();
        var tempNormals:Vector.<Number> = new Vector.<Number>();
        
        var i:int;
        var j:int;

        tempNormals = _normals.concat() as Vector.<Number>;
        if (rotaObject)
        {
            count2 = rotaObject.length;
            for (i = 0; i < count2; i++)
            {
                //回転だけ取り出す
                v3 = rotaObject[i].matrix.decompose();
                v3[0] = new Vector3D(0, 0, 0);
                v3[2] = new Vector3D(1, 1, 1);
                mtr3D.recompose(v3);
                mtr3D.transformVectors(tempNormals, tempNormals);
            }
        } else {
            v3 = matrix.decompose();
            v3[0] = new Vector3D(0, 0, 0);
            v3[2] = new Vector3D(1, 1, 1);
            mtr3D.recompose(v3);
            mtr3D.transformVectors(tempNormals, tempNormals);
        }
        
        for (i = 0; i < _count; i++)
        {
            //面の法線を得る
            var normal:Vector3D = new Vector3D(tempNormals[i*3],tempNormals[i*3+1],tempNormals[i*3+2]);

            //光源との内積で強さを決定
            var strength:Number = normal.dotProduct(axis);
            
            var r:int = light.colorR / 2 * strength * light.strength + light.colorR / 2;
            var g:int = light.colorG / 2 * strength * light.strength + light.colorG / 2;
            var b:int = light.colorB / 2 * strength * light.strength + light.colorB / 2;
            var color:int = r << 16 | g << 8 | b;
            
            //隙間防止の為、一回り大きな三角形を描画。
            //簡略化の為、ラインで一回り大きな三角を描いた物を下に敷く
            var fill:GraphicsSolidFill = new GraphicsSolidFill(0);
            fill.color=color;
            fillDrawing.push(fill,_paths[i],_endFill);
            var stroke:GraphicsStroke = new GraphicsStroke(10);
            stroke.fill = fill;
            lineDrawing.push(stroke,_paths[i],_endFill);


        }
        _lines.graphics.drawGraphicsData(lineDrawing);
        _fills.graphics.drawGraphicsData(fillDrawing);

        _bmd.copyPixels(_texture, _rect, _sp);
        _bmd.draw(_canvas, null, null,BlendMode.HARDLIGHT);
        //_bmd.draw(_canvas);
    }
    
    public function get bmd():BitmapData { return _bmd; }
    
}


import alternativ7.engine3d.core.Face;
import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.materials.Material;
import alternativ7.engine3d.materials.TextureMaterial;
import alternativ7.engine3d.objects.Mesh;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Shape;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Vector3D;
/**
 * BoxオブジェクトをFlatShadingする、Meshに変更するクラス
 *
 * サーフェースの概念がなくなったので、ちょっと面倒・・・
 *
 * @author narutohyper
 */
class FlatShadingBox extends Mesh
{
    private var _materialTypes:Vector.<String> = new Vector.<String>(6, true);;
    private var _materials:Vector.<TextureMaterial> = new Vector.<TextureMaterial>(6, true);
    private var _tempMaterials:Vector.<Material> = new Vector.<Material>(6, true);
    private var _textures:Vector.<BitmapData> = new Vector.<BitmapData>(6, true);
    private var _bmds:Vector.<BitmapData> = new Vector.<BitmapData>(6, true);
    private var _normals:Vector.<Number> = new Vector.<Number>();
    private var _bmd:BitmapData;
    private var _loadeds:Vector.<Boolean> = new Vector.<Boolean>(6, true);
    private var _fills:Shape = new Shape();
    private var _sp:Point;
    
    public function FlatShadingBox(mesh:Mesh)
    {
        var face:Face;
        var item:*;
        //引数のMeshのgeometryをコピー
        clonePropertiesFrom(mesh);

        //left左
        _normals.push(1, 0, 0);
        //right右
        _normals.push( -1, 0, 0);
        //back奥
        _normals.push(0, 1, 0);
        //front前
        _normals.push(0, -1, 0);
        //top上
        _normals.push(0, 0, 1);
        //bottom下
        _normals.push(0, 0, -1);

        //textureの取り込み

        var i:uint;
        var normal:Vector3D;
        for (item in faces) {
            face = faces[item];
            for (i = 0; i < 6; i++)
            {
                normal = new Vector3D(_normals[i * 3], _normals[i * 3 + 1], _normals[i * 3 + 2]);
                if (face.normal.x == normal.x && face.normal.y == normal.y && face.normal.z == normal.z) {
                    //この時点でTextureが設定されていたら、差し替え
                    if (!_textures[i] && face.material) {
                        setTexture(i, face.material);
                    }
                }
            }
        }

        var RADIAN:Number = Math.PI / 180;
    
        _sp = new Point(0, 0);
    }
    
    
    private function setTexture(id:uint,material:Material):void {
        var _tempMaterial:TextureMaterial = material as TextureMaterial;
        trace(_tempMaterial);
        if (_tempMaterial) {
            _materialTypes[id] = 'Texture';
            if (_tempMaterial.texture) {
                _textures[id] = _tempMaterial.texture;
                _bmds[id] = new BitmapData(_textures[id].width, _textures[id].height, true, 0xFF666666);
                _loadeds[id] = true;
                _materials[id] = new TextureMaterial(_bmds[id]);
                setFaceTexture(id);
            } else {
                //Textureが読み込まれていなかったら、差し替えしない
                _materials[id] = _tempMaterial;
            }
        } else {
            _materialTypes[id]='Fill';
            _textures[id] = new BitmapData(400, 400, false, FillMaterial(material).color);
            _bmds[id] = new BitmapData(400, 400, false, FillMaterial(material).color);
            _materials[id] = new TextureMaterial(_bmds[id]);
            setFaceTexture(id);
        }
    }
    

    private function setFaceTexture(id:uint):void {
        //該当IDのフェースを差し替える
        var face:Face;
        var normal:Vector3D;
        for (var item:* in faces) {
            face = faces[item];
            normal = new Vector3D(_normals[id * 3], _normals[id * 3 + 1], _normals[id * 3 + 2]);
            if (face.normal.x == normal.x && face.normal.y == normal.y && face.normal.z == normal.z) {
                face.material=_materials[id];
            }
        }
    }


    
    public function calculateLight(light:Light, rotaObject:Array = null):void {
        var i:int;
        var j:int;

        //Textureをloadしている場合、load完了までは、Textureなし
        //読み込まれて、適用された段階で反映する
        
        var normal:Vector3D;

        //光源の位置ベクトル
        var lv:Vector3D = new Vector3D(light.x, light.y, light.z);
        lv = light.localToGlobal(lv);
        
        //自身の位置ベクトル
        var target:Vector3D = new Vector3D(x, y, z);
        target = localToGlobal(target);
        
        //光源に対する方向(単位ベクトル)
        var axis:Vector3D = lv.subtract(target);
        var m:Number = axis.normalize();
        
        //1フェースごとにMatrix変換は、負荷大なので、まとめて変換
        var v3:Vector.<Vector3D>;
        var mtr3D:Matrix3D = new Matrix3D();
        var tempNormals:Vector.<Number> = new Vector.<Number>();
        
        var count2:int;
        tempNormals = _normals.concat() as Vector.<Number>;
        if (rotaObject)
        {
            count2 = rotaObject.length;
            for (i = 0; i < count2; i++)
            {
                //回転だけ取り出す
                v3 = rotaObject[i].matrix.decompose();
                v3[0] = new Vector3D(0, 0, 0);
                v3[2] = new Vector3D(1, 1, 1);
                mtr3D.recompose(v3);
                mtr3D.transformVectors(tempNormals, tempNormals);
            }
        } else {
            v3 = matrix.decompose();
            v3[0] = new Vector3D(0, 0, 0);
            v3[2] = new Vector3D(1, 1, 1);
            mtr3D.recompose(v3);
            mtr3D.transformVectors(tempNormals, tempNormals);
        }

        
        for (i = 0; i < 6; i++)
        {
            if (_materialTypes[i] == 'Texture') {
                if (!_loadeds[i] && _materials[i].texture) {
                    _textures[i] = _materials[i].texture;
                    _bmds[i] = new BitmapData(_textures[i].width, _textures[i].height, true, 0xFF666666);
                    _loadeds[i] = true;
                    _materials[i] = new TextureMaterial(_bmds[i]);
                    setFaceTexture(i);
                }
            }
            normal = new Vector3D(tempNormals[i * 3], tempNormals[i * 3 + 1], tempNormals[i * 3 + 2]);
            //光源との内積で強さを決定
            var strength:Number = normal.dotProduct(axis);
            
            //lightの色成分を分解
            
            
            var r:int = light.colorR / 2 * strength * light.strength + light.colorR / 2;
            var g:int = light.colorG / 2 * strength * light.strength + light.colorG / 2;
            var b:int = light.colorB / 2 * strength * light.strength + light.colorB / 2;
            var color:int = r << 16 | g << 8 | b;
            
            _fills.graphics.clear();
            if (_bmds[i]) {
                _fills.graphics.beginFill(color);
                _fills.graphics.drawRect(0, 0, _bmds[i].width, _bmds[i].height);
                _bmds[i].copyPixels(_textures[i], _textures[i].rect, _sp);
                _bmds[i].draw(_fills, null, null,BlendMode.HARDLIGHT);
            }

        }

        
    }
    
    public function get bmd():BitmapData { return _bmd; }
    
    
}


import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.primitives.GeoSphere;

/**
 *
 * Lightを表現するクラス
 *
 * @author narutohyper
 */
class Light extends GeoSphere
{
    private var _color:int;
    private var _colorR:int;
    private var _colorG:int;
    private var _colorB:int;
    private var _strength:Number;
    private var _material:FillMaterial;
    public function Light(color:Number,strength:Number=1)
    {
        _color = color;
        _strength = strength;
        _colorR = ( _color & 0xff0000 ) >> 16;
        _colorG = ( _color & 0xff00 ) >> 8;
        _colorB = ( _color & 0xff );
        _material = new FillMaterial(color);
        super(20, 2, false, _material);
    }
    
    public function get colorR():int { return _colorR; }
    
    public function get colorG():int { return _colorG; }
    
    public function get colorB():int { return _colorB; }
    
    public function get strength():Number { return _strength; }
    
    public function set strength(value:Number):void
    {
        _strength = value;
    }
    
    public function get color():int { return _color; }
    
    public function set color(value:int):void
    {
        _color = value;
    }
    
}


/**
 * BasicTemplate for Alternativa3D 7.5
 * Alternativa3D 7.5を扱いやすくするためのテンプレートです
 * @author narutohyper & clockmaker
 *
 */
import alternativ7.engine3d.containers.BSPContainer;
import alternativ7.engine3d.containers.ConflictContainer;
import alternativ7.engine3d.containers.DistanceSortContainer;
import alternativ7.engine3d.containers.KDContainer;
import alternativ7.engine3d.containers.LODContainer;
import alternativ7.engine3d.controllers.SimpleObjectController;
import alternativ7.engine3d.core.Camera3D;
import alternativ7.engine3d.core.Object3DContainer;
import alternativ7.engine3d.core.View;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;



class AlternativaTemplate extends Sprite
{
        /**
         * 子オブジェクトを最適な方法でソートするコンテナ
         * (ConflictContainer)
         */
        public static const CONFLICT:String = 'conflict';
        /**
         * 子オブジェクトをBSP(バイナリ空間分割法)によってソートするコンテナ
         * (BSPContainer)
         */
        public static const BSP:String = 'bsp';
        
        /**
         * 子オブジェクトをカメラからのZ値でソートするコンテナ
         * (DistanceSortContainer)
         */
        public static const ZSORT:String = 'zsort';
        /**
         * KDツリー(http://ja.wikipedia.org/wiki/Kd%E6%9C%A8)によってソートするコンテナ
         * (KDContainer)
         */
        public static const KD:String = 'kd';
        /**
         * detalizationと子オブジェクトの距離でソートするコンテナ(詳細は調査中)
         * (LODContainer)
         */
        public static const LOD:String = 'lod';
        
        /**
         * 3dオブジェクト格納するコンテナインスタンス。
         */
        public var container:Object3DContainer;

        /**
         * ビューインスタンスです。
         */
        public var view:View;
        
        /**
         * カメラインスタンスです。
         */
        public var camera:Camera3D;
        
        /**
         * カメラコントローラーです。
         */
        public var cameraController:SimpleObjectController;
        
        private var _mc:DisplayObjectContainer;
        private var _viewWidth:int;
        private var _viewHeight:int;
        private var _scaleToStage:Boolean;
        private var _containerType:String;
        
        /**
         * 新しい Alternativa3DTemplate インスタンスを作成します。
         * @param        mc
         * @param        containerType
         * @param        viewWidth
         * @param        viewHeight
         * @param        scaleToStage
         */
        public function AlternativaTemplate(mc:DisplayObjectContainer,containerType:String=CONFLICT,viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true)
        {
                _mc = mc;
                _mc.addChild(this);

                _containerType = containerType;
                _viewWidth = viewWidth;
                _viewHeight = viewHeight;
                _scaleToStage = scaleToStage;
                
                if (stage) init();
                else addEventListener(Event.ADDED_TO_STAGE, init);
        }


        /**
         * 初期化されたときに実行されるイベントです。
         * 初期化時に実行したい処理をオーバーライドして記述します。
         */
        protected function atInit():void {}


        /**
         * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
         * レンダリング前に実行したい処理をオーバーライドして記述します。
         */
        protected function atPreRender():void {}
        
        /**
         * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
         * レンダリング前に実行したい処理をオーバーライドして記述します。
         */
        private var _onPreRender:Function = function():void{};
        public function get onPreRender():Function { return _onPreRender; }
        public function set onPreRender(value:Function):void
        {
                _onPreRender = value;
        }
        
        /**
         * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
         * レンダリング後に実行したい処理をオーバーライドして記述します。
         */
        protected function atPostRender():void {}
        
        /**
         * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
         * レンダリング後に実行したい処理を記述します。
         */
        private var _onPostRender:Function = function():void{};
        public function get onPostRender():Function { return _onPostRender; }
        public function set onPostRender(value:Function):void
        {
                _onPostRender = value;
        }
        
        
        /**
         * レンダリングを開始します。
         */
        public function startRendering():void
        {
                addEventListener(Event.ENTER_FRAME, onRenderTick);
        }

        /**
        * レンダリングを停止します。
        */
        public function stopRendering():void
        {
                removeEventListener(Event.ENTER_FRAME, onRenderTick);
        }

        /**
         * シングルレンダリング(レンダリングを一回だけ)を実行します。
         */
        public function singleRender():void
        {
                onRenderTick();
        }

        /**
         * @private
         */
        private function init(e:Event = null):void
        {
                removeEventListener(Event.ADDED_TO_STAGE, init);
                // entry point
                stage.scaleMode = StageScaleMode.NO_SCALE;
                stage.align = StageAlign.TOP_LEFT;
                stage.quality = StageQuality.HIGH;
                
                //Root objectの作成
                if (_containerType == CONFLICT) {
                        container = new ConflictContainer();
                } else if (_containerType == BSP) {
                        container = new BSPContainer();
                } else if (_containerType == ZSORT) {
                        container = new DistanceSortContainer();
                } else if (_containerType == KD) {
                        container = new KDContainer();
                } else if (_containerType == LOD) {
                        container = new LODContainer();
                }
                //Viewの作成
                view = new View(stage.stageWidth, stage.stageHeight);
                _mc.addChild(view);

                //cameraの作成
                camera = new Camera3D();
                camera.view = view;
                camera.x = 0;
                camera.y = -500;
                camera.z = 0;
                container.addChild(camera);
                
                // Camera controller
                cameraController = new SimpleObjectController(stage, camera, 10);
                cameraController.mouseSensitivity = 0;
                cameraController.unbindAll();
                cameraController.lookAtXYZ(0, 0, 0);
                
                onResize();
                stage.addEventListener(Event.RESIZE, onResize);
                
                atInit();
        }
        
        /**
         * @private
         */
        private function onResize(e:Event = null):void
        {
                if (_scaleToStage)
                {
                    view.width = stage.stageWidth;
                    view.height = stage.stageHeight;
                }
                else
                {
                    view.width = _viewWidth;
                    view.height = _viewHeight;
                }
        }
        
        /**
         * @private
         */
        private function onRenderTick(e:Event = null):void
        {
                atPreRender();
                _onPreRender();
                cameraController.update();
                camera.render();
                atPostRender();
                _onPostRender();
        }


}