Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   API приложений и сред (http://www.flasher.ru/forum/forumdisplay.php?f=61)
-   -   Преобразование XY координат текстуры в XYZ и обратно (http://www.flasher.ru/forum/showthread.php?t=198675)

olexandr 02.05.2013 08:24

Преобразование XY координат текстуры в XYZ и обратно
 
Всем привет.

Прошу помощи опытных людей, поскольку с 3D-движками у меня очень маленький опыт работы.
Есть панорама, которую я показываю с помощью движка Alternativa3D 7.7 (использую примитив Sphere). Панораму я эту могу вращать.
Существует следующая проблема. Мне нужно на панораме отображать некие метки. Координаты этих метоку меня заданы в XY-формате, как для обычной плоской картинки. Мне нужно узнать эти координаты на готовой сфере, а потом перевести обратно в XY-формат.
То есть, допустим на панораме изображен какой-то дом, машина, человек... Мне нужно узнать координаты этого дома на сфере, чтобы показывать метку поверх него. Но поскольку метка должна быть не в 3D, а плоская, то потребуется обратный перевод.

Насколько я понимаю перевод обратно осуществляется с помощью методов projectGlobal и localToGlobal, а вот как быть с переводом в трехмерные координаты?
Важный момент - мышиных событий у меня не будет. Перевод нужно делать практически по EnterFrame.

p.s. если удобнее, можно ответить на форуме альтернативы

spirit2 03.05.2013 14:09

рейкастинг в помощь

olexandr 06.05.2013 19:34

рейкастинг помог, но не совсем.
координаты uv для текстуры мне нужно получать не из видимого 3d-пространства, а из развертки текстуры - насколько я понял, там можно обойтись обычными процентами.
вот, на тестовом примере вроде как получилось все реализовать для примитива plane, а для sphere пока никак :(

Код AS3:

package {
        import alternativa.engine3d.core.Camera3D;
        import alternativa.engine3d.core.Object3DContainer;
        import alternativa.engine3d.core.RayIntersectionData;
        import alternativa.engine3d.core.View;
        import alternativa.engine3d.materials.TextureMaterial;
        import alternativa.engine3d.primitives.Plane;
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.Shape;
        import flash.display.Sprite;
        import flash.display.StageAlign;
        import flash.display.StageScaleMode;
        import flash.events.Event;
        import flash.geom.Point;
        import flash.geom.Vector3D;
        import ua.olexandr.utils.GeomUtils;
 
        public class Main extends Sprite {
 
                public static const TEST_POINT:Point = new Point(663, 410);
 
                private var _holder:Object3DContainer;
                private var _camera:Camera3D;
                private var _texture:BitmapData;
                private var _plane:Plane;
//private var _sphere:Sphere;
                private var _shape:Shape;
 
                [Embed(source="texture.jpg")]
                private var _Texture:Class;
 
                public function Main():void {
                        if (stage)
                                init();
                        else
                                addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(e:Event = null):void {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
 
                        stage.align = StageAlign.TOP_LEFT;
                        stage.scaleMode = StageScaleMode.NO_SCALE;
 
                        _holder = new Object3DContainer();
 
                        _camera = new Camera3D();
                        _camera.view = new View(640, 480);
                        _camera.view.hideLogo();
                        _camera.view.contextMenu = null;
                        _camera.fov = GeomUtils.degreesToRadians(120);
                        _holder.addChild(_camera);
 
                        _texture = Bitmap(new _Texture()).bitmapData;
 
                        _plane = new Plane(100, 100, 100, 1, true);
                        _plane.setMaterialToAllFaces(new TextureMaterial(_texture));
                        _holder.addChild(_plane);
 
                        _camera.z = -80;
                        _camera.rotationX = GeomUtils.degreesToRadians(0);
                        _camera.rotationY = GeomUtils.degreesToRadians(-30);
                        _camera.rotationZ = GeomUtils.degreesToRadians(180);
 
                        _camera.view.x = stage.stageWidth - _camera.view.width >> 1;
                        _camera.view.y = stage.stageHeight - _camera.view.height >> 1;
                        addChild(_camera.view);
 
                        _shape = new Shape();
                        _shape.x = _camera.view.x;
                        _shape.y = _camera.view.y;
                        addChild(_shape);
 
                        addEventListener(Event.ENTER_FRAME, efHandler);
                }
 
                private function efHandler(e:Event):void {
                        var _degreesZ:Number = GeomUtils.radiansToDegrees(_camera.rotationZ) + 1;
                        _camera.rotationZ = GeomUtils.degreesToRadians(_degreesZ);
 
                        var _u:Number = (_texture.width - TEST_POINT.x) / _texture.width - .5;
                        var _v:Number = (_texture.height - TEST_POINT.y) / _texture.height - .5;
 
                        var _origin:Vector3D = new Vector3D(_camera.x, _camera.y, _camera.z);
                        var _direction:Vector3D = new Vector3D(_u, _v, 1);
                        var _data:RayIntersectionData = _holder.intersectRay(_origin, _direction);
 
                        if (_data) {
                                var _vec:Vector3D = _camera.projectGlobal(_data.point);
 
                                _shape.graphics.clear();
                                _shape.graphics.beginFill(0xFF0000, .5);
                                _shape.graphics.drawRect(_vec.x - 5, _vec.y - 5, 10, 10);
                        }
 
                        _camera.render();
                }
 
        }
 
}


Srednas 15.05.2013 15:18

Может статья поможет?

olexandr 18.05.2013 15:48

Вспомнил о не закрытой теме... Возможно, кому-то понадобится.

В итоге от Альтернативы использовалась всего 1 функция.

Код AS3:

var _x0:Number = p.x / _width;
var _y0:Number = p.y / _height;
 
var _a:Number = _x0 * 2 * Math.PI;
var _b:Number = (.5 - _y0) * Math.PI;
 
var _x:Number = Math.sin(_a) * Math.cos(_b);
var _y:Number = Math.cos(_a) * Math.cos(_b);
var _z:Number = Math.sin(_b);
 
var _vec:Vector3D = new Vector3D(_x, _y, _z);
_vec = _camera.projectGlobal(_vec);
 
if (_vec.z >= 0)
    return new Point(_vec.x, _vec.y);
 
return null;



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

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