forked from: forked from: forked from: s3d
...
@author lizhi http://game-develop.net/
/**
* Copyright lizhi ( http://wonderfl.net/user/lizhi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1B7T
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.IGraphicsData;
import flash.display.Sprite;
import flash.display.StageQuality;
import flash.events.Event;
import flash.geom.Vector3D;
import flash.geom.Point;
import net.hires.debug.Stats;
/**
* ...
* @author lizhi http://game-develop.net/
*/
public class Test3D5 extends Sprite
{
private var obj3d:Obj3D;
private var w:int = 400;
private var h:int = 400;
private var bmd:BitmapData = new BitmapData(w, h, false, 0);
private var vs:Vector.<uint> = bmd.getVector(bmd.rect);
private var gd:Vector.<IGraphicsData> = new Vector.<IGraphicsData>;
public function Test3D5()
{
var image:Bitmap = new Bitmap(bmd);
addChild(image);
//image.x = 400;
obj3d = createSphere(120,30 , 40);
obj3d.position.z = 150;
stage.quality = StageQuality.LOW;
addEventListener(Event.ENTER_FRAME, enterFrame);
addChild(new Stats);
}
private function enterFrame(e:Event):void
{
graphics.clear();
obj3d.rotation.x += .01;
obj3d.rotation.y += .02;
obj3d.rotation.z += .03;
graphics.lineStyle(0);
for (var i:int = obj3d.vs.length - 1; i >= 0; i-- ) {
var v:Vector3D = obj3d.vs[i];
var v2:Vector3D = obj3d.vs2[i];
var uv:Vector3D = obj3d.uvs[i];
var y:Number = v.y * Math.cos(obj3d.rotation.x) - v.z * Math.sin(obj3d.rotation.x);
var z:Number = v.z * Math.cos(obj3d.rotation.x) + v.y * Math.sin(obj3d.rotation.x);
var x:Number = v.x * Math.cos(obj3d.rotation.y) - z * Math.sin(obj3d.rotation.y);
z = z * Math.cos(obj3d.rotation.y) + v.x * Math.sin(obj3d.rotation.y);
var x_:Number = x * Math.cos(obj3d.rotation.z) - y * Math.sin(obj3d.rotation.z);
y = y * Math.cos(obj3d.rotation.z) + x * Math.sin(obj3d.rotation.z);
z += obj3d.position.z;
var fz:Number = 100 / z;
v2.x = x_ * fz+200;
v2.y = y * fz + 200;
v2.z = z;
}
/*for each(var line:Point in obj3d.lines) {
graphics.moveTo(obj3d.vs2[line.x].x,obj3d.vs2[line.x].y);
graphics.lineTo(obj3d.vs2[line.y].x,obj3d.vs2[line.y].y);
}*/
vs.length = 0;
vs.length = w * h;
obj3d.sort();
for each(var ts:Vector3D in obj3d.ts) {
fill(Vector.<Point>([
new Point(obj3d.vs2[ts.x].x, obj3d.vs2[ts.x].y),
new Point(obj3d.vs2[ts.y].x, obj3d.vs2[ts.y].y),
new Point(obj3d.vs2[ts.z].x, obj3d.vs2[ts.z].y)])
,ts.w);
}
bmd.setVector(bmd.rect, vs);
}
public function createSphere(r:Number, nv:int = 20, nh:int = 30):Obj3D {
var obj3d:Obj3D = new Obj3D;
obj3d.vs.push(new Vector3D(0, -r));
obj3d.uvs.push(new Vector3D(.5,0));
obj3d.vs2.push(new Vector3D);
for (var i:int = 1; i <= nv;i++ ) {
var az:Number = (i / (nv + 1) - .5) * Math.PI;
var uvv:Number = i / (nv + 1);
for (var j:int = 0; j < nh; j++ ) {
obj3d.uvs.push(new Vector3D(j/nh,uvv));
var v:Vector3D = new Vector3D(r);
var x:Number = v.x * Math.cos(az);
v.y = v.x * Math.sin(az);
var ay:Number = j / nh * 2 * Math.PI;
v.x = x * Math.cos(ay);
v.z = x * Math.sin(ay);
obj3d.vs.push(v);
obj3d.vs2.push(new Vector3D);
var a:int = (i - 1) * nh + j+1;
var b:int = j == (nh-1)?a - nh + 1:a + 1;
var c:int = i == nv?nv * nh + 1:a + nh;
var d:int = j == (nh - 1)?c - nh + 1:c + 1;
var color:uint = 0xffffff * Math.random();
obj3d.ts.push(new Vector3D(a, b, c,color), new Vector3D(b, c, d,color));
if (i == nv) obj3d.ts.pop();
obj3d.lines.push(new Point(a, b),new Point(a,c));
}
}
obj3d.vs.push(new Vector3D(0, r));
obj3d.vs2.push(new Vector3D);
obj3d.uvs.push(new Vector3D(.5,1));
for (j = 0; j < nh; j++ ) {
obj3d.lines.push(new Point(0, j + 1));
obj3d.ts.push(new Vector3D(0, j+1, j==(nh-1)?1:j+2,0xffffff*Math.random()));
}
return obj3d;
}
private function fill(v:Vector.<Point>, color:uint):void {
/*graphics.beginFill(color);
graphics.moveTo(v[0].x, v[0].y);
graphics.lineTo(v[1].x, v[1].y);
graphics.lineTo(v[2].x, v[2].y);
graphics.lineTo(v[0].x, v[0].y);
graphics.endFill();
return;*/
v.sort(sort);
var dx0:Number = (v[1].x - v[0].x) / (int(v[1].y) - int(v[0].y));
var dx1:Number = (v[2].x - v[0].x) / (int(v[2].y) - int(v[0].y));
if (dx0 > dx1) {
var temp:Number = dx0;
dx0 = dx1;
dx1 = temp;
}
var i:int = int(v[0].y) * w;
var x0:Number = v[0].x;
var x1:Number = v[0].x;
for (var y:int = v[0].y, y1:int = v[1].y; y < y1; y++ ) {
for (var x:int = x0+i,len:int=x1+i; x < len; x++ ) {
vs[x] = color;
}
x0 += dx0;
x1 += dx1;
i += w;
}
if (int(v[0].y)==int(v[1].y)) {
dx0 = (v[2].x - v[0].x) / (int(v[2].y) - int(v[0].y));
dx1 = (v[2].x - v[1].x) / (int(v[2].y) - int(v[1].y));
if (dx0 < dx1) {
temp = dx0;
dx0 = dx1;
dx1 = temp;
x1 = v[0].x;
x0 = v[1].x;
}else {
x0 = v[0].x;
x1 = v[1].x;
}
}else {
dx0 = (v[2].x - v[0].x) / (int(v[2].y) - int(v[0].y));
dx1 = (v[2].x - v[1].x) / (int(v[2].y) - int(v[1].y));
if (dx0 < dx1) {
temp = dx0;
dx0 = dx1;
dx1 = temp;
}
}
for (y1 = v[2].y; y < y1; y++ ) {
for (x = x0+i,len=x1+i; x < len; x++ ) {
vs[x] = color;
}
x0 += dx0;
x1 += dx1;
i += w;
}
}
private function sort(p1:Point, p2:Point):Number { return p1.y - p2.y }
}
}
import flash.geom.*;
class Obj3D {
public var rotation:Vector3D = new Vector3D;//角度
public var position:Vector3D = new Vector3D;//位置
public var vs:Vector.<Vector3D> = new Vector.<Vector3D>;//顶点
public var uvs:Vector.<Vector3D> = new Vector.<Vector3D>;//uv
public var vs2:Vector.<Vector3D> = new Vector.<Vector3D>;//屏幕坐标顶点
public var lines:Vector.<Point> = new Vector.<Point>;//直线
public var clines:Vector.<Vector3D> = new Vector.<Vector3D>;//曲线
public var ts:Vector.<Vector3D> = new Vector.<Vector3D>;//三角形
public function sort():void {
ts.sort(sortts);
}
private function sortts(p1:Vector3D,p0:Vector3D):Number
{
return vs2[p0.x].z + vs2[p0.y].z + vs2[p0.z].z - vs2[p1.x].z - vs2[p1.y].z - vs2[p1.z].z;
}
}