Для того, чтобы получить координаты мыши в пространстве, необходимо посмотреть пересечение луча с контейнером или объектом, на котором мы хотим отлавливать событие мыши. Хочу сразу сказать, что тут вообще ничего сложного нету, но из-за того, что я не сразу понял, что нужно отключить mouseChildren у контейнера, из-за чего у меня получалась каша с координатами. Спасибо большое Дмитрию [focus] Юханову, с которым мы созвонились по скайпу и начали искать в чем проблема. Дим, спасибо за помощь! Так же, не забывайте, что в скачанном архиве альтернативы лежит не только документация, но и примеры использования движка.
Вначале посмотрим сам метод intersectRay, который доступен любому Object3D

Стандартный пример:
package intersectrayexample { import alternativa.engine3d.containers.ConflictContainer; import alternativa.engine3d.controllers.SimpleObjectController; import alternativa.engine3d.core.Camera3D; import alternativa.engine3d.core.MipMapping; import alternativa.engine3d.core.MouseEvent3D; import alternativa.engine3d.core.Object3D; import alternativa.engine3d.core.Object3DContainer; import alternativa.engine3d.core.RayIntersectionData; import alternativa.engine3d.core.Sorting; import alternativa.engine3d.core.View; import alternativa.engine3d.materials.FillMaterial; import alternativa.engine3d.materials.TextureMaterial; import alternativa.engine3d.primitives.Box; import alternativa.engine3d.primitives.Plane; 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; /** * Пример работы с поиском пересечения луча с геометрией в Alternativa3D. */ public class IntersectRayExample extends Sprite { //ембедим наш файл текстуры в EmbedTexture [Embed(source="texture.jpg")] static private const EmbedTexture:Class; private var rootContainer:Object3DContainer = new Object3DContainer(); private var camera:Camera3D; private var controller:SimpleObjectController; public function IntersectRayExample() { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; // Создание камеры и вьюпорта camera = new Camera3D(); camera.view = new View(stage.stageWidth, stage.stageHeight); addChild(camera.view); addChild(camera.diagram); // Установка начального положения камеры camera.rotationX = -110*Math.PI/180; camera.y = -1200; camera.z = 300; controller = new SimpleObjectController(stage, camera, 200); rootContainer.addChild(camera); // Создание объектов var plane:Plane = new Plane(1200, 1200); plane.setMaterialToAllFaces(new TextureMaterial(new BitmapData(800, 800, false, 0xAFC47D))); plane.z = -100; plane.rotationZ = -30*Math.PI/180; rootContainer.addChild(plane); var box:Box = new Box(100, 100, 100); box.sorting = Sorting.DYNAMIC_BSP; box.setMaterialToAllFaces(new TextureMaterial(new EmbedTexture().bitmapData, false, true, MipMapping.OBJECT_DISTANCE)); var container:ConflictContainer = new ConflictContainer(); container.rotationZ = -30*Math.PI/180; for (var i:int = 0; i < 5; i++) { for (var j:int = 0; j < 5; j++) { var object:Object3D = box.clone(); object.x = i*180 - 360; object.y = j*180 - 360; container.addChild(object); } } rootContainer.addChild(container); // Мышиные события в 3D camera.view.interactive = true; //ОТКЛЮЧАЕМ ОТ МЫШИ ДЕТЕЙ container.mouseChildren = false; container.addEventListener(MouseEvent3D.MOUSE_DOWN, addBox); plane.addEventListener(MouseEvent3D.MOUSE_DOWN, drawSpot); // Подписка на события stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(Event.RESIZE, onResize); } private function addBox(e:MouseEvent3D):void { var container:Object3DContainer = e.target as Object3DContainer; //получаем результат пересечения луча //с объектом на который добавили слушатель события var data:RayIntersectionData = container.intersectRay(e.localOrigin, e.localDirection); //если есть рузультат if (data != null) { //и вот он наш Vector3D var point:Vector3D = data.object.matrix.transformVector(data.point); var box:Box = new Box(15, 15, 15); box.setMaterialToAllFaces(new FillMaterial(0xFF0000)); box.x = point.x; box.y = point.y; box.z = point.z; container.addChild(box); } } private function drawSpot(e:MouseEvent3D):void { var object:Object3D = e.target as Object3D; //получаем результат пересечения луча //с объектом на который добавили слушатель события var data:RayIntersectionData = object.intersectRay(e.localOrigin, e.localDirection); //если есть рузультат if (data != null) { var texture:BitmapData = (data.face.material as TextureMaterial).texture; var uv:Point = data.face.getUV(data.point); var spot:Shape = new Shape(); spot.graphics.beginFill(0x0000FF, 0.5); spot.graphics.drawCircle(uv.x*texture.width, uv.y*texture.height, 20); texture.draw(spot); } } private function onEnterFrame(e:Event):void { controller.update(); camera.render(); } private function onResize(e:Event = null):void { // Установка ширины и высоты вьюпорта camera.view.width = stage.stageWidth; camera.view.height = stage.stageHeight; } } }
5 Responses to “Alternativa3D определение координат мыши в пространстве”



Всегда пожалуйста, Серёг, было здорово =)
Альтернатива за статьи и уроки теперь платит по 100 баксов, кстати )
Мы всё читаем, если что
Молодец, Сергей! Так держать.
Кстати, сегодня Вова продемонстрировал нормальные человеческие маус-евенты в 7.6, так что скоро будет проще.
Спасибо большое, я стараюсь!
С нетерпением жду 7.6)
На форуме помощи просят, посмотришь?
http://forum.alternativaplatform.com/posts/list/3207.page
Да, конечно