|
|
|||||
Регистрация: Oct 2006
Сообщений: 10
|
Поверхности, по порядку становись!
Привет.
Пишу модель 3Д кубика Рубика, только с множеством ячеек. Модель представляет собой перевод 3D -> 2D , с 2-мя изменяемыми углами обзора. Координаты точек считаются, осталось реализовать покрытие Кубика поверхностями. Вот вопросы: - как реализовать отображение плоскостей, т.е. порядок их появления для каждого ракурса: а) для каждого кубика-ячейки б) совокупности ячеек в) ... и что бы это было как можно менее ресурсозатратным (с т.з. железа клиента) Буду благодарен умным мыслям, алгоритмам ну и ОЧЕНЬ опен-сорсным исходникам
__________________
Ёж в противогазе |
|
|||||
Регистрация: Jul 2008
Сообщений: 912
|
Я когда-то движок писал что-б 3D отображать во FlashPlayer. Теперь он не нужен, я его забросил ибо Молхил вышел.
Вот пробуй, всего 4 класса, но можно отобразить любой 3D обьект: 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; } } } 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; } } } 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); } } } } 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; } } } там правда нет сеттеров для движения по Y и Z, но их легко сделать, есть сеттер который задаёт X положение в классе MeshMine это - public function set xm Взять скопировать эту функцию пару раз и поменять где нужно "x" на "y" и "z". Нет здесь сцены, то-есть объекты не сортируются между собой, сортируются только полигоны. Нет парсера. Нет текстурированья. Это всё планировалось в будущем, но... Как пользоваться видно в классе Model: вызываем экземпляр класса MeshMine, задаём координаты точек через .nVert и создаём треугольники через .nTriangles например кубик будет так: ваш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 пространстве: вашMeshMine.rot3DY(0.1); или вашMeshMine.rot3DX(0.1); двигаем как спрайт вашMeshMine.x += 1; вращаем как спрайт вашMeshMine.rotationX += 1; Последний раз редактировалось Sintesis; 18.04.2011 в 22:10. |
Часовой пояс GMT +4, время: 15:26. |
|
« Предыдущая тема | Следующая тема » |
|
|