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

Create OriginalPrimitive (Cylinder & Cone TypeBata) [Alternativa3D 7.6 TIPS]

オリジナルのプリミティブを作成してみます。

5.6には使い勝手の良い、Cylinder(シリンダー)プリミティブが用意されていましたが、
7.6では、残念ながら実装されていませんでした。

なので、Meshクラスを継承して、シリンダーやコーンが作成できるCylinderクラスを試作してみました。

なお、これもまだuvを設定していませんので、あくまで「試作」状態ですので、あしからず。
(twoside、reverseも未実装。TOPとBottomにフタも出来るようにしたいけど未実装)
まだまだ、色々研究中w

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/7jQO
 */

// forked from narutohyper's Alternativa3D 7.5 Template
package
{
    import alternativ7.engine3d.core.Object3DContainer;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.controllers.SimpleObjectController;
    import flash.display.Sprite;
    import flash.events.Event;



    /**
     * Alternativa3D 7.6
     *
     * オリジナルのプリミティブを作成
     *
     * @author narutohyper
     */
    [SWF(backgroundColor="#000000", frameRate="100", 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);
        
            //AlternativaTemplate作成
            var scene:AlternativaTemplate = new AlternativaTemplate(this);

            
            //まとめてcontrolするために、core.Object3DContainerを作成し、各Objectを入れ子にする
            var animeObject:Object3DContainer = new Object3DContainer;
            scene.container.addChild(animeObject);
            
            
            //外部読み込み画像によるmaterial

            var material:FillMaterial = new FillMaterial(0xCCCCFF,1,0,1);

            var cylinder1:Cylinder = new Cylinder(500,0,100,3,12);
            cylinder1.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder1);
            cylinder1.x=-500;
            cylinder1.y=-500;
            
            var cylinder2:Cylinder = new Cylinder(500,0,100,2,4);
            cylinder2.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder2);
            cylinder2.x=500;
            cylinder2.y=-500;

            var cylinder3:Cylinder = new Cylinder(500,100,0,6,8);
            cylinder3.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder3);
            cylinder3.x=-500;
            cylinder3.y=500;

            var cylinder4:Cylinder = new Cylinder(500,100,50,2,12);
            cylinder4.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder4);
            cylinder4.x=500;
            cylinder4.y=500;

            var cylinder5:Cylinder = new Cylinder(500,100,100,2,12);
            cylinder5.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder5);
            
            var cylinder6:Cylinder = new Cylinder(500,100,50,8,12);
            cylinder6.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder6);
            cylinder6.x=-500;
            
            var cylinder7:Cylinder = new Cylinder(500,50,100,1,12);
            cylinder7.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder7);
            cylinder7.x=500;

            var cylinder8:Cylinder = new Cylinder(100,100,100,2,12);
            cylinder8.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder8);
            cylinder8.y=-500;
            
            
            var cylinder9:Cylinder = new Cylinder(1000,100,100,10,12);
            cylinder9.setMaterialToAllFaces(material);
            animeObject.addChild(cylinder9);
            cylinder9.y=500;
            
            
            
            //カメラの調整
            //カメラはControllerに関連付けている為、x,y,zで直接位置を指定できないので
            //SimpleController.setObjectPosXYZを使用
            scene.cameraController.setObjectPosXYZ(0, -1500, 500);
            scene.cameraController.lookAtXYZ(0, 0, 0);
            //ObjectControllerの作成
            //MouseDragで、Objectを回転させる為のController
            var objectController:SimpleObjectController = new SimpleObjectController(stage,animeObject,100);
            objectController.unbindAll();
            
            scene.onPreRender = function():void {
                objectController.update();
            }
            
            //描画開始
            scene.startRendering();
            
            

        }
        


    }
    
}



import alternativ7.engine3d.core.Vertex;
import alternativ7.engine3d.objects.Mesh;
    
/**
 * @author narutohyper
 */
class Cylinder extends Mesh
{
    
    public function Cylinder(
        height:Number = 100,
        topRadius:Number = 0,bottomRadius:Number = 100,
        heightSegments:uint = 1, radialSegments:uint = 12,
        twoside:Boolean = false , reverse:Boolean = false, triangulate:Boolean = false) {
                                                            
        if(bottomRadius <= 0 && topRadius <= 0) {
            throw new ArgumentError("bottomRadius and topRadius are given below 0");
        } else if (height <= 0) {
            throw new ArgumentError("height are given below 0");
        } else if (radialSegments<3) {
            throw new ArgumentError("radialSegments are given below 3");
        } else if (heightSegments<1) {
            throw new ArgumentError("heightSegments are given below 4");
        } else {
            
            var h:Number = height/heightSegments;
            var offsetRadius:Number;
            var iz:int;
            var ir:int;
            var nh:Number;
            var oh:Number;
            var nx:Number;
            var ny:Number;
            var nz:Number;
            var nr:Number;        //半径
            
            var sinR:Number = Math.sin((360 / radialSegments) * Math.PI / 180);
            var cosR:Number = Math.cos((360 / radialSegments) * Math.PI / 180);
            var step:Number = 360 / radialSegments;
            
            
            var vertex:Vector.<Vertex> = new Vector.<Vertex>;
            
            var id:uint = 0;
            var v0:Vertex;
            //Vertex(頂点)の登録

              var start:uint;
            var end:uint;
            if (topRadius > bottomRadius) {
                offsetRadius = topRadius - bottomRadius;
                if (bottomRadius == 0) {
                    end = 1;
                } else {
                    end = 0;
                }
                for (iz = 0; iz <= heightSegments-end; iz++)
                {
                    for (ir = 0; ir < radialSegments;ir++ )
                    {
                        nh = (h * iz);
                        oh = (nh) ? (height - nh) / height:1;
                        nr = (bottomRadius + (offsetRadius * oh));
                        nz = (height / 2) - nh;
                        
                        nx = Math.cos(step * ir * Math.PI / 180)*nr;
                        ny = Math.sin(step * ir * Math.PI / 180)*nr;
                        v0 = addVertex(nx, ny, nz, 0, 0, 'vertex' + id);
                        id++;
                    }
                }
                if (bottomRadius == 0) {
                    start = 1;
                    nz = (height / -2);
                    v0 = addVertex(0, 0, nz, 0, 0, 'vertex' + id);
                    id++;
                }
                
            } else {
                offsetRadius = bottomRadius - topRadius;

                if (topRadius == 0) {
                    nz = (height / 2);
                    v0 = addVertex(0, 0, nz, 0, 0, 'vertex' + id);
                    id++;
                    start = 1;
                } else {
                    start = 0;
                }
                for (iz = start; iz <= heightSegments; iz++)
                {
                    for (ir = 0; ir < radialSegments;ir++ )
                    {
                        nh = (h * iz);
                        oh = (nh) ? nh / height:0;
                        nr = (topRadius + (offsetRadius * oh));
                        nz = (height / 2) - nh;
                        
                        nx = Math.cos(step * ir * Math.PI / 180)*nr;
                        ny = Math.sin(step * ir * Math.PI / 180) * nr;
                        v0 = addVertex(nx, ny, nz, 0, 0, 'vertex' + id);
                        id++;
                        
                    }
                }
                
            }


            //Face(面・四角)の登録
            id = 0;
            var n1:uint;
            var n2:uint;
            var n3:uint;
            var v1:Vertex;
            var v2:Vertex;
            var v3:Vertex;
            var v4:Vertex;
            
            for (iz = 0; iz < heightSegments; iz++)
            {
                for (ir = 0; ir < radialSegments;ir++ )
                {
                    
                    n1 = ir;
                    n2 = (ir+1 == radialSegments) ? 0:ir+1;
                    if (topRadius == 0) {
                        n3 = (iz * radialSegments-radialSegments+1);
                    } else {
                        n3 = (iz * radialSegments);
                    }
                    
                    if (topRadius == 0 && iz == 0) {
                        n3 = 1;
                        v1 = getVertexById('vertex' + 0);
                        v2 = getVertexById('vertex' + (n3 + n2));
                        v3 = getVertexById('vertex' + (n3 + n1));
                        addTriFace(v1, v2, v3, null, 'faceFront' + id);
                        addTriFace(v1, v3, v2, null, 'faceBack' + id);
                    } else if (bottomRadius == 0 && iz == heightSegments - 1) {
                        v1 = getVertexById('vertex' + (n3 + n1));
                        v2 = getVertexById('vertex' + (n3 + n2));
                        v3 = getVertexById('vertex' + (n3 + radialSegments));
                        addTriFace(v1, v2, v3, null, 'faceFront' + id);
                        addTriFace(v1, v3, v2, null, 'faceBack' + id);

                    } else {
                        v1 = getVertexById('vertex' + (n3 + n1));
                        v2 = getVertexById('vertex' + (n3 + n2));
                        v3 = getVertexById('vertex' + (n3 + n2 + radialSegments));
                        v4 = getVertexById('vertex' + (n3 + n1 + radialSegments));
                        
                        addQuadFace(v1, v2, v3, v4, null, 'faceFront' + id);
                        addQuadFace(v1, v4, v3, v2, null, 'faceBack' + id);
                    }
                    id++;
                }
            }
            
            calculateNormals();
            
            
        }
        
    }

}











/**
 * 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.DisplayObject;

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();
    }
            
    
}