Astro15.as (メイン)
package {
import __AS3__.vec.Vector;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.TriangleCulling;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Vector3D;
import flash.geom.PerspectiveProjection;
import primitives.Sphere;
[SWF(width="550",height="400",backgroundColor="0x0",frameRate="24")]
public class Astro15 extends Sprite{
[Embed(source="assets/panoramic.jpg")]
private var MoonImage:Class;
private var _img:Bitmap;
private var _container:Sprite;
private var _projection:PerspectiveProjection;
private var _scene:Sprite;
private var _primitive:Sphere;
private var _vertices:Vector.<Number>;
private var _uvtData:Vector.<Number>;
public function Astro15(){
_container = new Sprite();
_container.buttonMode = true;
_container.x = stage.stageWidth/2;
_container.y = stage.stageHeight/2;
addChild(_container);
_projection = new PerspectiveProjection();
_projection.fieldOfView = 60;
_scene = new Sprite();
_scene.transform.matrix3D = new Matrix3D();
_primitive = new Sphere(50);
_img = Bitmap(new MoonImage());
addEventListener(Event.ENTER_FRAME,renderScene);
}
private function renderScene(e:Event):void{
rotate(_scene);
var world:Matrix3D = _scene.transform.matrix3D.clone();
world.append(_projection.toMatrix3D());
var projectedVector3D:Vector.<Vector3D> = project3D(_primitive.vertices,world);
zsort(projectedVector3D,_primitive.uvtData);
_container.graphics.clear();
_container.graphics.beginBitmapFill(_img.bitmapData);
_container.graphics.drawTriangles(_vertices,null,_uvtData,TriangleCulling.POSITIVE);
_container.graphics.endFill();
}
private function project3D(vertices:Vector.<Vector3D>,world:Matrix3D):Vector.<Vector3D>{
var results:Vector.<Vector3D> = new Vector.<Vector3D>();
for (var i:int=0; i<vertices.length; i++){
var vertex:Vector3D = vertices[i];
var v:Vector3D = world.transformVector(vertex);
results.push(v);
}
return results;
}
private function zsort(vertices:Vector.<Vector3D>,uvtData:Vector.<Number>):void{
var objects:Array = new Array();
for (var i:int=0; i<vertices.length; i+=3){
var v0:Vector3D = vertices[i];
var v1:Vector3D = vertices[i+1];
var v2:Vector3D = vertices[i+2];
var avg:Number = (v0.z + v1.z + v2.z)/3;
var j:int = i*2;
var uvt0:Point = new Point(uvtData[j],uvtData[j+1]);
var uvt1:Point = new Point(uvtData[j+2],uvtData[j+3]);
var uvt2:Point = new Point(uvtData[j+4],uvtData[j+5]);
objects.push({v0:v0,v1:v1,v2:v2,p0:uvt0,p1:uvt1,p2:uvt2,zPos:avg});
}
objects.sortOn("zPos",Array.DESCENDING | Array.NUMERIC);
_vertices = new Vector.<Number>();
_uvtData = new Vector.<Number>();
for each (var obj:Object in objects){
_vertices.push(obj.v0.x,obj.v0.y, obj.v1.x,obj.v1.y, obj.v2.x,obj.v2.y);
_uvtData.push(obj.p0.x,obj.p0.y, obj.p1.x,obj.p1.y, obj.p2.x,obj.p2.y);
}
}
private function rotate(target:Sprite):void{
var dx:Number = (mouseX - stage.stageWidth/2);
var dy:Number = (mouseY - stage.stageHeight/2);
target.rotationX = 0.5*dy;
target.rotationY = -0.8*dx;
}
}
}
Sphere.as (プリミティブ)
package primitives{
import __AS3__.vec.Vector;
import flash.geom.Vector3D;
public class Sphere{
private var _vertices:Vector.<Vector3D>;
private var _uvtData:Vector.<Number>;
private const DIF:Number = 10;
private var tMin:Number = 5;
private var tMax:Number = 180 - tMin;
private var pMin:Number = 0;
private var pMax:Number = 360;
private var pi:Number = Math.PI;
public function Sphere(r:Number){
_vertices = new Vector.<Vector3D>();
_uvtData = new Vector.<Number>();
for (var t:int=tMin; t<tMax; t+=DIF){
for (var p:int=pMin; p<pMax; p+=DIF){
var x1:Number = r*Math.sin(t*pi/180)*Math.cos(p*pi/180);
var y1:Number = -r*Math.cos(t*pi/180);
var z1:Number = r*Math.sin(t*pi/180)*Math.sin(p*pi/180);
var xPos1:Number = (p-pMin)/(pMax-pMin);
var yPos1:Number = (t-tMin)/(tMax-tMin);
var x2:Number = r*Math.sin((t+DIF)*pi/180)*Math.cos(p*pi/180);
var y2:Number = -r*Math.cos((t+DIF)*pi/180);
var z2:Number = r*Math.sin((t+DIF)*pi/180)*Math.sin(p*pi/180);
var xPos2:Number = (p-pMin)/(pMax-pMin);
var yPos2:Number = ((t+DIF)-tMin)/(tMax-tMin);
var x3:Number = r*Math.sin(t*pi/180)*Math.cos((p+DIF)*pi/180);
var y3:Number = -r*Math.cos(t*pi/180);
var z3:Number = r*Math.sin(t*pi/180)*Math.sin((p+DIF)*pi/180);
var xPos3:Number = ((p+DIF)-pMin)/(pMax-pMin);
var yPos3:Number = (t-tMin)/(tMax-tMin);
var x4:Number = r*Math.sin((t+DIF)*pi/180)*Math.cos((p+DIF)*pi/180);
var y4:Number = -r*Math.cos((t+DIF)*pi/180);
var z4:Number = r*Math.sin((t+DIF)*pi/180)*Math.sin((p+DIF)*pi/180);
var xPos4:Number = ((p+DIF)-pMin)/(pMax-pMin);
var yPos4:Number = ((t+DIF)-tMin)/(tMax-tMin);
var v1:Vector3D = new Vector3D(x1,y1,z1);
var v2:Vector3D = new Vector3D(x2,y2,z2);
var v3:Vector3D = new Vector3D(x3,y3,z3);
var v4:Vector3D = new Vector3D(x4,y4,z4);
_vertices.push(v1,v2,v3, v3,v2,v4);
_uvtData.push(xPos1,yPos1,xPos2,yPos2,xPos3,yPos3,xPos3,yPos3,xPos2,yPos2,xPos4,yPos4);
}
}
}
public function get vertices():Vector.<Vector3D>{
return _vertices;
}
public function get uvtData():Vector.<Number>{
return _uvtData;
}
}
}
Powered by blog Boreal Kiss 2008.