PV3DのTriangleMesh3Dの練習07 Sphereクラスを修正して半球クラス作成実験

by siouxcitizen forked from PV3DのTriangleMesh3Dの練習06 ピラミッド型をクラス化 (diff: 155)
♥0 | Line 109 | Modified 2011-02-28 18:32:30 | MIT License
play

ActionScript3 source code

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

// forked from siouxcitizen's PV3DのTriangleMesh3Dの練習06 ピラミッド型をクラス化
//PV3DのTriangleMesh3Dの練習07 Sphereクラスを修正して半球クラス作成実験
//かなりムリヤリテキトーに半球下部を作成してます。。。
//
//以下のSphereクラスのソースを元にして半球(Hemispehre)クラス作成しました
//http://code.google.com/p/papervision3d-jp/source/browse/trunk/src/org/papervision3d/objects/primitives/Sphere.as?r=13
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import org.papervision3d.materials.*;
    import org.papervision3d.view.*;
    public class Main extends BasicView {
        
        private var hemisphere:Hemisphere;
        
        public function Main() {
            var material:WireframeMaterial = new WireframeMaterial(0x0000FF);
            //var material:ColorMaterial = new ColorMaterial(0x0000FF);
            material.doubleSided = true;

            hemisphere = new Hemisphere(material, 300, 10, 10);
            
            scene.addChild(hemisphere);
            
            startRendering();
            
            this.addEventListener(Event.ENTER_FRAME, loop);
        }
        
        private function loop(evt:Event):void {
            //hemisphere.rotationY += 1;
            //hemisphere.rotationZ += 1;
            hemisphere.rotationX=viewport.mouseX;
            hemisphere.rotationY=viewport.mouseY;
            //super.onRenderTick(event);
        }
        
    }
}

import org.papervision3d.Papervision3D;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.NumberUV;
import org.papervision3d.core.proto.*;  
class Hemisphere extends TriangleMesh3D {

    private var segmentsW :Number;
    private var segmentsH :Number;
    static public var DEFAULT_RADIUS :Number = 100;
    static public var DEFAULT_SCALE :Number = 1;
    static public var DEFAULT_SEGMENTSW :Number = 8;
    static public var DEFAULT_SEGMENTSH :Number = 6;
    static public var MIN_SEGMENTSW :Number = 3;
    static public var MIN_SEGMENTSH :Number = 2;

    public function Hemisphere( material:MaterialObject3D=null, radius:Number=100, segmentsW:int=8, segmentsH:int=6 ) {
        super( material, new Array(), new Array(), null );

        this.segmentsW = Math.max( MIN_SEGMENTSW, segmentsW || DEFAULT_SEGMENTSW); // Defaults to 8
        this.segmentsH = Math.max( MIN_SEGMENTSH, segmentsH || DEFAULT_SEGMENTSH); // Defaults to 6
        if (radius==0) radius = DEFAULT_RADIUS; // Defaults to 100

        var scale :Number = DEFAULT_SCALE;

        buildHemiphere( radius );
    }

    private function buildHemiphere( fRadius:Number ):void {
        var i:Number, j:Number, k:Number;
        var iHor:Number = Math.max(3,this.segmentsW);
        var iVer:Number = Math.max(2,this.segmentsH);
        var aVertice:Array = this.geometry.vertices;
        var aFace:Array = this.geometry.faces;
        var aVtc:Array = new Array();
        //for (j=0;j<(iVer+1);j++) { // vertical
        //for (j=0;j<(iVer+1)/2;j++) { // vertical
        for (j=0;j<(iVer/2+1);j++) { // vertical
            var fRad1:Number = Number(j/iVer);
            var fZ:Number = -fRadius*Math.cos(fRad1*Math.PI);
            var fRds:Number = fRadius*Math.sin(fRad1*Math.PI);
            var aRow:Array = new Array();
            var oVtx:Vertex3D;
            for (i=0;i<iHor;i++) { // horizontal
                var fRad2:Number = Number(2*i/iHor);
                var fX:Number = fRds*Math.sin(fRad2*Math.PI);
                var fY:Number = fRds*Math.cos(fRad2*Math.PI);
                if (!((j==0||j==iVer)&&i>0)) { // top||bottom = 1 vertex
                    oVtx = new Vertex3D(fY,fZ,fX);
                    aVertice.push(oVtx);
                }
                aRow.push(oVtx);
            }
            aVtc.push(aRow);
        }
        var iVerNum:int = aVtc.length;
        for (j=0;j<iVerNum;j++) {
            var iHorNum:int = aVtc[j].length;
            if (j>0) { // &&i>=0
                for (i=0;i<iHorNum;i++) {
                    // select vertices
                    var bEnd:Boolean = i==(iHorNum-1);
                    var aP1:Vertex3D = aVtc[j][bEnd?0:i+1];
                    var aP2:Vertex3D = aVtc[j][(bEnd?iHorNum-1:i)];
                    var aP3:Vertex3D = aVtc[j-1][(bEnd?iHorNum-1:i)];
                    var aP4:Vertex3D = aVtc[j-1][bEnd?0:i+1];
                    // uv

                    var fJ0:Number = j              / (iVerNum-1);
                    var fJ1:Number = (j-1)  / (iVerNum-1);
                    var fI0:Number = (i+1)  / iHorNum;
                    var fI1:Number = i              / iHorNum;
                    var aP4uv:NumberUV = new NumberUV(fI0,fJ1);
                    var aP1uv:NumberUV = new NumberUV(fI0,fJ0);
                    var aP2uv:NumberUV = new NumberUV(fI1,fJ0);
                    var aP3uv:NumberUV = new NumberUV(fI1,fJ1);
                    // 2 faces
                    if (j<(aVtc.length-1))  aFace.push( new Triangle3D(this, new Array(aP1,aP2,aP3), material, new Array(aP1uv,aP2uv,aP3uv)) );
                    if (j>1) aFace.push( new Triangle3D(this, new Array(aP1,aP3,aP4), material, new Array(aP1uv,aP3uv,aP4uv)) );
                }
            }
        }
        //半球下部の欠けている部分を作成(コメントでいろいろ作業を記録してます)
        //for (i=0;i<iHorNum-1;i++) { //bEnd_2による調整を行わない場合(昔使用していたループの記録)
        for (i=0;i<iHorNum;i++) {
            var bEnd_2:Boolean = i==(iHorNum-1);
            //↓固定で1つ分作成
            //var aP1_2:Vertex3D = aVtc[5][1];
            //var aP2_2:Vertex3D = aVtc[5][0];
            //var aP3_2:Vertex3D = aVtc[4][0];
            //↓iVerNumを使用して
            //var aP1_2:Vertex3D = aVtc[iVerNum-1][1];
            //var aP2_2:Vertex3D = aVtc[iVerNum-1][0];
            //var aP3_2:Vertex3D = aVtc[iVerNum-2][0];
            //↓ループを使って複数作成
            //var aP1_2:Vertex3D = aVtc[iVerNum-1][i+1];
            //var aP2_2:Vertex3D = aVtc[iVerNum-1][i];
            //var aP3_2:Vertex3D = aVtc[iVerNum-2][i];
            //↓最後の1つ分作成の調整のため(判定のためbEnd_2を使用)
            var aP1_2:Vertex3D = aVtc[iVerNum-1][bEnd_2?0:i+1];
            var aP2_2:Vertex3D = aVtc[iVerNum-1][bEnd_2?iHorNum-1:i];
            var aP3_2:Vertex3D = aVtc[iVerNum-2][bEnd_2?iHorNum-1:i];

            //uvよくわからないのでとりあえず。。。
            var uvA : NumberUV = new NumberUV( 0, 0 );
            var uvC : NumberUV = new NumberUV( 1, 0 );
            var uvB : NumberUV = new NumberUV( 0, 1 );

            aFace.push( new Triangle3D(this, new Array(aP1_2,aP2_2,aP3_2), material, new Array(uvA,uvC,uvB)) );
        }
        for each(var t:Triangle3D in aFace) {
            t.renderCommand.create = createRenderTriangle;
        }
        
        this.geometry.ready = true;
        
        if (Papervision3D.useRIGHTHANDED) this.geometry.flipFaces();
    }
}

Forked