PV3DのTriangleMesh3Dの練習07 Sphereクラスを修正して半球クラス作成実験
forked from PV3DのTriangleMesh3Dの練習06 ピラミッド型をクラス化 (diff: 155)
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();
}
}
