| Sintesis |
18.04.2011 22:04 |
Я когда-то движок писал что-б 3D отображать во FlashPlayer. Теперь он не нужен, я его забросил ибо Молхил вышел.
Вот пробуй, всего 4 класса, но можно отобразить любой 3D обьект:
Код AS3:
package{
public class Point3D{
public var fl:Number = -250;
private var vpX:Number = 0;
private var vpY:Number = 0;
private var cX:Number = 0;
private var cY:Number = 0;
private var cZ:Number = 0;
public var x:Number = 0;
public var y:Number = 0;
public var z:Number = 0;
public function Point3D(x:Number=0, y:Number=0, z:Number=0){
this.x = x;
this.y = y;
this.z = z;
}
public function setVanishingPoint(vpX:Number, vpY:Number):void{
this.vpX = vpX;
this.vpY = vpY;
}
public function setCenter(cX:Number, cY:Number, cZ:Number = 0):void {
this.cX = cX;
this.cY = cY;
this.cZ = cZ;
}
public function get screenX():Number{
var scale:Number = fl / (fl + z + cZ);
return vpX + (cX + x) * scale;
}
public function get screenY():Number{
var scale:Number = fl / (fl + z + cZ);
return vpY + (cY + y) * scale;
}
public function rotateX(angleX:Number):void{
var cosX:Number = Math.cos(angleX);
var sinX:Number = Math.sin(angleX);
var y1:Number = y * cosX - z * sinX;
var z1:Number = z * cosX + y * sinX;
y = y1;
z = z1;
}
public function rotateY(angleY:Number):void{
var cosY:Number = Math.cos(angleY);
var sinY:Number = Math.sin(angleY);
var x1:Number = x * cosY - z * sinY;
var z1:Number = z * cosY + x * sinY;
x = x1;
z = z1;
}
public function rotateZ(angleZ:Number):void{
var cosZ:Number = Math.cos(angleZ);
var sinZ:Number = Math.sin(angleZ);
var x1:Number = x * cosZ - y * sinZ;
var y1:Number = y * cosZ + x * sinZ;
x = x1;
y = y1;
}
}
}
Добавлено через 1 минуту
Код AS3:
package{
import flash.display.Graphics;
public class TriangleBfs{
private var pointA:Point3D;
private var pointB:Point3D;
private var pointC:Point3D;
private var color:uint;
public function TriangleBfs(a:Point3D, b:Point3D, c:Point3D, color:uint){
pointA = a;
pointB = b;
pointC = c;
this.color = color;
}
public function draw(g:Graphics):void{
if(isBackFace()){
return;
}
g.beginFill(color);
g.moveTo(pointA.screenX, pointA.screenY);
g.lineTo(pointB.screenX, pointB.screenY);
g.lineTo(pointC.screenX, pointC.screenY);
g.lineTo(pointA.screenX, pointA.screenY);
g.endFill();
}
private function isBackFace():Boolean{
var cax:Number = pointC.screenX - pointA.screenX;
var cay:Number = pointC.screenY - pointA.screenY;
var bcx:Number = pointB.screenX - pointC.screenX;
var bcy:Number = pointB.screenY - pointC.screenY;
return cax * bcy > cay * bcx;
}
public function get depth():Number{
var zpos:Number = Math.min(pointA.z, pointB.z);
zpos = Math.min(zpos, pointC.z);
return zpos;
}
}
}
Добавлено через 2 минуты
Код AS3:
package {
import flash.display.*;
import flash.events.Event;
public class MeshMine extends Sprite{
public var points:Array;
private var coord:Array;
public var triangles:Array;
private var sxm:Number;
private var ptx:Array;
private var numPoints:uint;
private var vpX:Number = 600 / 2;
private var vpY:Number = 600 / 2;
public function MeshMine(){
points = new Array();
coord = new Array();
ptx = new Array();
triangles = new Array();
sxm = new Number();
nVert(coord);
nTriangles(ptx);
render();
}
public function nVert(coord:Array):void{
points = [];
var length:int = coord.length;
for (var j:int = 0; j < length; j += 3){
points.push(new Point3D(coord[j], coord[j + 1], coord[j + 2]));
}
}
public function set xm(newXm:Number):void {
var xm:Number = newXm;
for(var i:uint = 0; i < numPoints; i++){
points[i].setCenter(xm, 0, 0);
}
}
public function nTriangles(ptx:Array):void{
triangles = [];
var lengthTry:int = ptx.length;
for (var z:int = 0; z < lengthTry; z += 3 ) {
triangles.push(new TriangleBfs(points[ptx[z]], points[ptx[z + 1]], points[ptx[z + 2]], 0x8d8a81));
}
numPoints = new uint();
numPoints = points.length;
for(var i:uint = 0; i < numPoints; i++){
points[i].setVanishingPoint(vpX, vpY);
//points[i].setCenter(sxm, 0, 0);
}
}
public function render():void {
triangles.sortOn("depth", Array.DESCENDING | Array.NUMERIC);
graphics.clear();
graphics.lineStyle(0);
for(var i:uint = 0; i < triangles.length; i++){
triangles[i].draw(graphics);
}
}
public function rot3DX(ang:Number):void {
for(var i:uint = 0; i < numPoints; i++){
var mesh:Point3D = points[i];
mesh.rotateX(ang);
}
}
public function rot3DY(ang:Number):void {
for(var i:uint = 0; i < numPoints; i++){
var mesh:Point3D = points[i];
mesh.rotateY(ang);
}
}
public function rot3DZ(ang:Number):void {
for(var i:uint = 0; i < numPoints; i++){
var mesh:Point3D = points[i];
mesh.rotateZ(ang);
}
}
}
}
Добавлено через 9 минут
Код AS3:
package {
import flash.display.Sprite;
import flash.events.Event;
public class Model extends Sprite {
private var sph:MeshMine;
public function Model():void {
init();
}
private function init():void {
sph = new MeshMine();
sph.nVert([9.13609, -17.7834, -9.13609, 0, -17.7834, -12.9204, -9.13609, -17.7834, -9.13609, -12.9204, -17.7834,
0, -9.13609, -17.7834, 9.13609, 0, -17.7834, 12.9204, 9.13609, -17.7834, 9.13609, 12.9204, -17.7834, 0, 14.7825,
-6.79265, -14.7825, 0, -6.79265, -20.9056, -14.7825, -6.79265, -14.7825, -20.9056, -6.79265, 0, -14.7825, -6.79265, 14.7825, 0,
-6.79265, 20.9056, 14.7825, -6.79265, 14.7825, 20.9056, -6.79265, 0, 14.7825, 6.79265, -14.7825, 0, 6.79265, -20.9056,
-14.7825, 6.79265, -14.7825, -20.9056, 6.79265, 0, -14.7825, 6.79265, 14.7825, 0, 6.79265, 20.9056, 14.7825, 6.79265,
14.7825, 20.9056, 6.79265, 0, 9.13609, 17.7834, -9.13609, 0, 17.7834, -12.9204, -9.13609, 17.7834, -9.13609, -12.9204,
17.7834, 0, -9.13609, 17.7834, 9.13609, 0, 17.7834, 12.9204, 9.13609, 17.7834, 9.13609, 12.9204, 17.7834, 0, 0, -21.9815, 0, 0, 21.9815, 0]);
sph.nTriangles([0, 1, 8 , 8 , 1 , 9 , 1 , 2 , 9 , 9 , 2 , 10 , 2 , 3 ,
10 , 10 , 3 , 11 , 3 , 4 , 11 , 11 , 4 , 12 , 4 , 5 , 12 ,
12 , 5 , 13 , 5 , 6 , 13 , 13 , 6 , 14 , 6 , 7 , 14 , 14 ,
7 , 15 , 7 , 0 , 15 , 15 , 0 , 8 , 8 , 9 , 16 , 16 , 9 , 17,
9 , 10 , 17 , 17 , 10 , 18 , 10 , 11 , 18 , 18 , 11 , 19 ,
11 , 12 , 19 , 19 , 12 , 20 , 12 , 13 , 20 , 20 , 13 , 21,
13 , 14 , 21 , 21 , 14 , 22 , 14 , 15 , 22 , 22 , 15 , 23 ,
15 , 8 , 23 , 23 , 8 , 16 , 16 , 17 , 24 , 24 , 17 , 25,
17, 18 , 25 , 25 , 18 , 26 , 18 , 19 , 26 , 26 , 19 , 27 , 19 , 20 , 27 , 27 , 20 , 28 , 20 , 21 , 28 ,
28 , 21 , 29 , 21 , 22 , 29 , 29 , 22 , 30 , 22 , 23 , 30 , 30 , 23 , 31 ,
23, 16, 31, 31 , 16 , 24 , 1 , 0 , 32 , 2 , 1 , 32 , 3 ,
2 , 32 , 4 , 3 , 32 , 5 , 4 , 32 , 6 , 5 , 32 , 7 , 6 , 32 , 0 , 7 , 32 , 24 , 25 , 33 , 25 , 26 , 33 ,
26 , 27 , 33 , 27 , 28 , 33 , 28 , 29 , 33 , 29 , 30 , 33 , 30 , 31 , 33 , 31 , 24 , 33
]);
addChild(sph);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void {
sph.render();
sph.rot3DY(0.1);
sph.xm += 1;
}
}
}
Добавлено через 32 минуты
там правда нет сеттеров для движения по Y и Z, но их легко сделать, есть сеттер который задаёт X положение в классе MeshMine это - public function set xm
Взять скопировать эту функцию пару раз и поменять где нужно "x" на "y" и "z".
Нет здесь сцены, то-есть объекты не сортируются между собой, сортируются только полигоны.
Нет парсера.
Нет текстурированья.
Это всё планировалось в будущем, но...
Как пользоваться видно в классе Model: вызываем экземпляр класса MeshMine, задаём координаты точек через .nVert и создаём треугольники через .nTriangles
например кубик будет так:
Код AS3:
вашMeshMine.nVert([ 10, 10, 10, -10, 10, 10, -10, -10, 10, 10, -10, 10,
10, 10, -10, -10, 10, -10, -10, -10, -10, 10, -10, -10]);
вашMeshMine.nTriangles([0, 1, 2, 0, 2, 3, 0, 5, 1, 0, 4, 5, 4, 6, 5, 4, 7, 6, 3, 2, 6,
3, 6, 7, 1, 5, 6, 1, 6, 2, 4, 0, 3, 4, 3, 7]);
двигаем в 3D пространстве по оси X: вашMeshMine.xm += 1;
вращаем в 3D пространстве: вашMeshMine.rot3DY(0.1); или вашMeshMine.rot3DX(0.1);
двигаем как спрайт вашMeshMine.x += 1;
вращаем как спрайт вашMeshMine.rotationX += 1;
|