Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Поверхности, по порядку становись! (http://www.flasher.ru/forum/showthread.php?t=154482)

cn_snipes 18.04.2011 15:32

Поверхности, по порядку становись!
 
Привет.
Пишу модель 3Д кубика Рубика, только с множеством ячеек.
Модель представляет собой перевод 3D -> 2D , с 2-мя изменяемыми углами обзора.
Координаты точек считаются, осталось реализовать покрытие Кубика поверхностями. Вот вопросы:
- как реализовать отображение плоскостей, т.е. порядок их появления для каждого ракурса:
а) для каждого кубика-ячейки
б) совокупности ячеек
в) ... и что бы это было как можно менее ресурсозатратным (с т.з. железа клиента) :)

Буду благодарен умным мыслям, алгоритмам ну и ОЧЕНЬ опен-сорсным исходникам :)

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;


Часовой пояс GMT +4, время: 07:34.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.