TriangleMesh3Dの練習(ドーナッツ)

by hi.kurosawa
♥0 | Line 102 | Modified 2011-04-12 16:05:51 | MIT License
play

ActionScript3 source code

/**
 * Copyright hi.kurosawa ( http://wonderfl.net/user/hi.kurosawa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3kYi
 */

//--------------------------------------------
//TriangleMesh3Dの練習(ドーナッツ)
// URL:http://programmingatelier.net/
//--------------------------------------------
package 
{
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.materials.*;  
    import org.papervision3d.objects.primitives.*;  
    import org.papervision3d.objects.*;
    import org.papervision3d.lights.*;
    import org.papervision3d.materials.shadematerials.*;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.materials.special.CompositeMaterial;
    import org.papervision3d.view.*;
    import org.papervision3d.core.geom.TriangleMesh3D;
    import org.papervision3d.core.geom.renderables.Triangle3D;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import flash.events.Event;

    public class Main extends BasicView
    {
        //3D形状の配置領域
        private var rootNode:DisplayObject3D;
        //ライト
        private var light:PointLight3D;
        //カメラ位置を求める角度
        private     var kakudo0:Number;
        private     var kakudo1:Number;
        private     var kakudo2:Number;
        
        public function Main():void {
            //3D形状の配置領域作成
            rootNode = new DisplayObject3D();
            this.scene.addChild(rootNode);
            //光源
            light = new PointLight3D();
            light.x = -1000;
            light.y = 1000;
            light.z = 1000;

            //マテリアル定義
            var compoMat:CompositeMaterial = new CompositeMaterial();
            var matShade:FlatShadeMaterial = new FlatShadeMaterial(light, 0xCC9900, 0x885500);
            var matWire:WireframeMaterial = new WireframeMaterial( 0x000000, 0.2);
            compoMat.addMaterial(matShade);
            compoMat.addMaterial(matWire);
            //compoMat.doubleSided = true;  //裏表示
            
            var iBun1:int = 20;
            var iBun2:int = 16;
            var r1:Number = 200.0;
            var r2:Number = 60.0;
            var i:int;
            var j:int;
            
            
            var arrP2D:Array = new Array();
            for (i = 0; i < iBun2; i++) {
                arrP2D.push({ x:r1-r2*Math.cos(i*Math.PI*2.0/iBun2),y:r2*Math.sin(i*Math.PI*2.0/iBun2)});
            }
            //使用する座標を求める
            var arrVec3D:Array = new Array();
            var mesh:TriangleMesh3D = new TriangleMesh3D( compoMat, new Array(), new Array(), null );
            for (i = 0; i < iBun1; i++) {
                for (j = 0; j < iBun2; j++) {
                    var v3dP:Vertex3D = new Vertex3D(arrP2D[j].x*Math.cos(i*Math.PI*2.0/iBun1),arrP2D[j].y,
                                               arrP2D[j].x * Math.sin(i * Math.PI * 2.0 / iBun1));
                    arrVec3D.push(v3dP);
                    mesh.geometry.vertices.push( v3dP );
                }
            }

            //形状の作成
            for (i = 0; i < iBun1; i++) {
                var k:int = i + 1;
                if (k >= iBun1) { k = 0;}
                
                for (j = 0; j < iBun2; j++) {
                    var l:int = j + 1;
                    if (l >= iBun2) { l = 0;}
                    //三角2枚で四角を作成
                    mesh.geometry.faces.push( new Triangle3D( mesh, 
                            new Array(
                                arrVec3D[i*iBun2+j],
                                arrVec3D[i*iBun2+l],
                                arrVec3D[k*iBun2+j])
                            , null,null ));
                    mesh.geometry.faces.push( new Triangle3D( mesh, 
                            new Array(
                                arrVec3D[k*iBun2+j],
                                arrVec3D[i*iBun2+l],
                                arrVec3D[k*iBun2+l])
                            , null,null ));
                }
            }
            rootNode.addChild(mesh);
            //カメラ用角度クリア
            kakudo0 = 0;
            kakudo1 = 0;
            kakudo2 = 0;
            //繰り返し処理登録
            addEventListener(Event.ENTER_FRAME, onFrame);
        }
        
        private function onFrame(e:Event):void {
            //カメラを回転させるための角度を増加させる
            kakudo0 += 0.3;
            kakudo1++;
            if (kakudo1 >= 360) { kakudo1 = 0; }
            if (kakudo0 >= 360) { kakudo0 -= 360; }
            kakudo2 = Math.sin(kakudo0 * Math.PI / 180) * 80;
            //カメラの位置セット、形状表示
            onSlChmg();
        }
        
        //カメラの位置セット、形状表示
        private function onSlChmg():void {
            //カメラ位置
            var kyori:Number = 500;//原点・カメラの距離
            //高さ方向の角度(ラジアン)
            var ang1:Number =  kakudo2 * Math.PI / 180.0;    
            //方向(ラジアン)
            var ang2:Number = (kakudo1-180) * Math.PI / 180.0;    
            var x:Number=kyori*Math.cos(ang1)*Math.sin(ang2);
            var y:Number=kyori*Math.cos(ang1)*Math.cos(ang2);
            var z:Number = kyori*Math.sin(ang1);
            this.camera.x = x;
            this.camera.z = y;
            this.camera.y = z;

            //描画処理
            this.renderer.renderScene( this.scene , this.camera , this.viewport );
        }
    }

}