Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > Blitz3D > 3D-программирование

3D-программирование Вопросы, касающиеся программирования 3D мира

Ответ
 
Опции темы
Старый 08.04.2020, 11:09   #1
leshiyru70
AnyKey`щик
 
Аватар для leshiyru70
 
Регистрация: 20.01.2019
Адрес: Томск
Сообщений: 6
Написано 2 полезных сообщений
(для 3 пользователей)
Как вычислить 2D координату курсора в 3D мире?

Доброго времени суток! Прошу подсобить советом в решении одной задачи. В созданной 3D сцене нужно узнать точную координату X,Y,Z на которую указывает курсор мыши. А именно есть координаты X,Y,Z камеры и X,Y 2D координата курсора, ну и Z1 расстояние до предполагаемой 3D точки. По возможности напишите пожалуйста формулу для реализации этой процедуры. Спасибо.
__________________
(Offline)
 
Ответить с цитированием
Старый 08.04.2020, 14:29   #2
Кирпи4
Социал-сычевист
 
Аватар для Кирпи4
 
Регистрация: 24.06.2011
Сообщений: 611
Написано 342 полезных сообщений
(для 1,359 пользователей)
Ответ: Как вычислить 2D координату курсора в 3D мире?

Если просто, то CameraPick
__________________


(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо Кирпи4 за это полезное сообщение:
ABTOMAT (08.04.2020), leshiyru70 (08.04.2020), St_AnGer (09.04.2020)
Старый 08.04.2020, 15:44   #3
leshiyru70
AnyKey`щик
 
Аватар для leshiyru70
 
Регистрация: 20.01.2019
Адрес: Томск
Сообщений: 6
Написано 2 полезных сообщений
(для 3 пользователей)
Ответ: Как вычислить 2D координату курсора в 3D мире?

К сожалению будь всё так элементарно и не спрашивал бы. CameraPick не совсем что нужно. В вашем варианте прийдёться создавать объект, а в дальнейшем передвигать его в нужную 3D точку по отношению к курсору. Вполне реалистично, но как-то заморочно. Математическими вычислениями было-бы как-то солидней. Перелопатил уже уйму материала. Пока совсем не въехал. Математик ещё тот...
__________________
(Offline)
 
Ответить с цитированием
Старый 08.04.2020, 16:05   #4
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Ответ: Как вычислить 2D координату курсора в 3D мире?

Сообщение от leshiyru70 Посмотреть сообщение
К сожалению будь всё так элементарно и не спрашивал бы. CameraPick не совсем что нужно. В вашем варианте прийдёться создавать объект, а в дальнейшем передвигать его в нужную 3D точку по отношению к курсору. Вполне реалистично, но как-то заморочно. Математическими вычислениями было-бы как-то солидней. Перелопатил уже уйму материала. Пока совсем не въехал. Математик ещё тот...
Надо взять координаты курсора в пространстве экрана (где центр экрана — это XY 0,0 правый верхний угол экрана — 1,1, левый нижний угол экрана — -1,-1, у а Z — это то расстояние от камеры, которое ты выбрал заранее сам).

То есть получится вектор XYZ в пространстве экрана.

Потом этот вектор надо умножить на инверсную матрицу камеры, и получится этот же вектор но уже в пространстве камеры.

Затем его умножить на инверсную матрицу трансформации камеры. И получатся координаты в пространстве мира, которые мы и хотели.

Это была теория. А вот практика уже грустнее.

Применительно к блицу, у него нет встроенных инструментов для работы с линейной алгеброй. Элементы матрицы трансформации можно достать с помощью GetMatElement.

Достать матрицу проекции камеры вроде нельзя. Но можно её самостоятельно сделать, зная её параметры (угол обзора и т.д.).

Так как у Блица нет встроенных инструментов для работы с линейной алгеброй, то инвертирование матриц и умножение вектора на них тебе придётся писать самому, что в целом не сложно, достаточно только вооружиться учебником по математике 1-го курса института.

Другой вопрос: в связи с особенностями Блица такой способ всё равно будет медленнее, чем если поставить полигон перед камерой и сделать на него CameraPick. Поэтому если стоит практическая задача, то лучше делать через CameraPick и не париться.

На других движках, наверное, операциями с математикой было бы и лучше, но не в случае Блица.
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена

(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо ABTOMAT за это полезное сообщение:
Arton (10.04.2020), leshiyru70 (08.04.2020), St_AnGer (09.04.2020)
Старый 15.04.2020, 02:28   #5
leshiyru70
AnyKey`щик
 
Аватар для leshiyru70
 
Регистрация: 20.01.2019
Адрес: Томск
Сообщений: 6
Написано 2 полезных сообщений
(для 3 пользователей)
Ответ: Как вычислить 2D координату курсора в 3D мире?

Вот моя попытка соорудить что-то вроде определителя 3D координаты под курсором мыши. Пока есть недостатки. Для нормального вычисления нельзя вращать камеру по XY осям, так-как сбиваются координаты. Есть ощущение что решение этого недостатка где-то рядом, не пока не могу сообразить где. Если вас не затруднит взгляните на код. Может будут какие-либо советы, предложения. Буду весьма благодарен. Спасибо.

P.S. Управление камерой на стрелочках и правые шифт и контрол. Вращение по Z оси=7 и 9 на NUM PAD, то бишь ЦИФРОКЛАВА. ))



; перечень работоспособных разрешений всегда должны быть 4/3
; 640,480 \ 800,600 \ 1024,768
camW=800: camH=600

Graphics3D camW,camH,32,2
SetBuffer BackBuffer ()

; стартовое позиционирование камеры XYZ
camX#=0: camY#=0: camZ#=-40
cam = CreateCamera()
PositionEntity cam,camX,camY,camZ

; стартовое вращение камеры по осям XYZ
anglX#=0: anglY#=0: anglZ#=0
RotateEntity cam,anglX#,anglY#,anglZ#,True

; стартовая дистанция до 3Д точки
distance#=-40

; для наглядности сфера будет прикреплена к курсору
sph=CreateSphere (4)
ScaleEntity sph,2,2,2

arial20=LoadFont ("arial",20)
SetFont arial20

; основной цикл ====================================
While Not KeyDown(1)
mx=MouseX(): my=MouseY()



; изменения позиции камеры
If KeyDown (203) Then camX=camX-1; (Left)
If KeyDown (205) Then camX=camX+1; (Right)
If KeyDown (200) Then camZ=camZ-1; (Up)
If KeyDown (20 Then camZ=camZ+1; (Down)
If KeyDown (54) Then camY=camY+1; (r Shift)
If KeyDown (157) Then camY=camY-1; (r Cntrl)
PositionEntity cam,camX,camY,camZ

; вращение камеры по XYZ оси
; кроме оси Z пока вращать нельзя (СБОЙ НАВЕДЕНИЯ)
; If KeyDown (72) Then anglX=anglX-1; (
; If KeyDown (80) Then anglX=anglX+1; (2)
; If KeyDown (75) Then anglY=anglY-1; (4)
; If KeyDown (77) Then anglY=anglY+1; (6)
If KeyDown (71) Then anglZ=anglZ-1; (7) работает нормально
If KeyDown (73) Then anglZ=anglZ+1; (9) работает нормально
RotateEntity cam,anglX,anglY,anglZ


; что-бы не делать вычислений в пустую
If oldmxy<>mx+my+camX+camY+camZ+anglX+anglY+anglZ Then
oldmxy=mx+my+camX+camY+camZ+anglX+anglY+anglZ

XYZ$=FF_2Dto3D(cam,camW,camH,distance); XYZ$=полученные результаты

; передача результата от функции происходит в тексте "\"=разделитель между параметрами
oldi=1: kol=0
For i=1 To Len(XYZ$)
If Mid$(XYZ$,i,1)="\" Then
If kol=0 Then pxx#=Mid$(XYZ$,oldi,i-1) ; получина X координата
If kol=1 Then pyy#=Mid$(XYZ$,oldi,i-1) ; получина Y координата
If kol=2 Then pzz#=Mid$(XYZ$,oldi,i-1) ; получина Z координата
oldi=i+1: kol=kol+1
EndIf
Next
EndIf

PositionEntity sph,pxx,pyy,pzz,True

RenderWorld

Color 250,250,0: Rect mx-8,my-8,16,16,0

Color 250,250,250
Text 400,0,"X\Y\Z координаты сферы="+XYZ$,True

CXYZ$=camX+"\"+camY+"\"+camZ
Text 400,20,"X\Y\Z координаты камеры="+CXYZ$,True

CAXYZ$=anglX+"\"+anglY+"\"+anglZ
Text 400,40,"X\Y\Z вращение камеры="+CAXYZ$,True
Flip
Wend
End
; ================================================



; ----------------------------------------------------------------------------------
; ПЕРЕВОД ПОЗИЦИИ 2Д КУРСОРА В 3Д КООРДИНАТУ
; cam=личный номер камеры, camW,camH=разрешение экрана,
; distance#=предполагаемая дистанция до 3Д точки
Function FF_2Dto3D$(cam,camW,camH,distance#)
mx=MouseX(): my=MouseY()

; определяю местоположения камеры
camX#=EntityX#(cam)
camY#=EntityY#(cam)
camZ#=EntityZ#(cam)
; поворот камеры по осям XYZ
anglX#=EntityPitch#(cam)
anglY#=EntityYaw#(cam)
anglZ#=EntityRoll#(cam)

; вычисляю шаг движения 3Д точки с учётом дистанции до камеры
; разрешение всегда должно иметь соотношение сторон 4/3 для правильной работы.
ccz#=(camW/4)/((distance/2)+(camZ/2))

; смещаю нулевую координату курсора в центр экрана
cx#=(camW/2)-mx
cy#=(camH/2)-my

; вычисляю новую 3Д координату по отношению к позиции камеры
ccx#=camX+cx/ccz
ccy#=camY-cy/ccz

; узнаю дистанцию и угол между камерой и 3Д точкой
alldist#=FF_getdist#(camX,camY,ccx,ccy,1)
allug#=FF_getdist#(camX,camY,ccx,ccy,2)+anglZ

; вычисляю координаты новой точки зная угол и дистанцию
pxx#=camX+Sin(allug)*alldist
pyy#=camY-Cos(allug)*alldist
pzz#=-distance

; передаю XYZ координаты для использования
XYZ$=pxx+"\"+pyy+"\"+pzz+"\"
Return XYZ$

End Function
; ----------------------------------------------------------------------------------



; _____________________________________________
; ЗАМЕР ДИСТАНЦИИ И УГЛА между точками
; px,py,pxx,pyy=первая и вторая точки измерения
; direc=1 возврат дистанции direc=2 возврат угла 0=верх 90=право и т д по Ч стрелке
Function FF_getdist#(px#,py#,pxx#,pyy#,direc)

dx#=pxx#-px#
dy#=pyy#-py#

; вычисляю дистанцию между координатами
If direc=1 Then dist#=Sqr((dx#*dx#)+(dy#*dy#))

; определяю угол между точками от px,py и к pxx,pyy
If direc=2
dist#=180+ATan2(dx#,dy#): dist#=360-dist#
EndIf

Return dist#
End Function
; ---------------------------------------------------------------------------------UOTE][/quote][/quote]
__________________
(Offline)
 
Ответить с цитированием
Старый 15.04.2020, 03:46   #6
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 26.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,741
Написано 5,461 полезных сообщений
(для 15,675 пользователей)
Ответ: Как вычислить 2D координату курсора в 3D мире?

Сообщение от leshiyru70 Посмотреть сообщение
Вот моя попытка соорудить что-то вроде определителя 3D координаты под курсором мыши. Пока есть недостатки. Для нормального вычисления нельзя вращать камеру по XY осям, так-как сбиваются координаты. Есть ощущение что решение этого недостатка где-то рядом, не пока не могу сообразить где. Если вас не затруднит взгляните на код. Может будут какие-либо советы, предложения. Буду весьма благодарен. Спасибо.

P.S. Управление камерой на стрелочках и правые шифт и контрол. Вращение по Z оси=7 и 9 на NUM PAD, то бишь ЦИФРОКЛАВА. ))
Увы, сразу скажу: у меня Блица нет и не будет, поэтому запустить я не могу.
А просто читать код сложнее хелловорлда без возможности его оттестировать даже при наличии времени и желания ничего не даст.

Если у тебя вычисляется 3D-координата при нулевом положении камеры, значит, ты на верном пути.

Теперь надо полученный вектор выводить из пространства камеры в пространство мира, похоже, проблема кроется в этой части. Как ты решаешь конкретно эту часть задачи?
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена

(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
leshiyru70 (16.04.2020)
Старый 15.04.2020, 07:40   #7
leshiyru70
AnyKey`щик
 
Аватар для leshiyru70
 
Регистрация: 20.01.2019
Адрес: Томск
Сообщений: 6
Написано 2 полезных сообщений
(для 3 пользователей)
Ответ: Как вычислить 2D координату курсора в 3D мире?

От своей ранее изложенной идеи не отказываюсь, но всё-же слишком надолго застревать на одном месте наверное не стоит. Пока-же реализую функцию по определению 3Д координаты по отношению к 2Д курсору другим способом, который мне предложили АВТОМАТ и КИРПИ4. За что им очень благодарен!
Суть функции такова.
Создаётся Mesh в позиции камеры и направляется в ту-же сторону, далее Mesh отодвигаю от камеры на необходимое расстояние.
MoveEntity msh,0,0,-distance#
Далее в цикле при помощи.
CameraProject (cam,EntityX(msh),EntityY(msh),EntityZ(msh))
iccx=ProjectedX #()
iccy=ProjectedY #()
Узнаю 2Д координату Mesh и передвигаю его в сторону курсора.
Когда 2Д координаты относительно сошлись вывожу 3Д позицию Mesh в тексте "X\Y\Z\"... Ну как-то так.

Вот та самая функция, может кому нужно будет.
; -------------------------------------------------------------------------------
; ПОЗИЦИЯ 2Д КУРСОРА В 3Д КООРДИНАТУ
; cam=личный номер камеры, camW,camH=разрешение экрана,
; distance#=предполагаемая дистанция до 3Д точки
Function FF_2Dto3D$(cam,distance#)
mx=MouseX(): my=MouseY()

; определяю местоположения камеры
camX#=EntityX#(cam)
camY#=EntityY#(cam)
camZ#=EntityZ#(cam)
; поворот камеры по осям XYZ
anglX#=EntityPitch#(cam)
anglY#=EntityYaw#(cam)
anglZ#=EntityRoll#(cam)

; создаю Mesh, ориентирую его в направлении камеры
; и отодвигаю на нужную дистанцию
msh=CreateMesh ()
PositionEntity msh,camX#,camY#,camZ#
RotateEntity msh,anglX#,anglY#,anglZ#
MoveEntity msh,0,0,-distance#

; цикл выравнивания
Repeat
; узнаю координату Mesh в 2Д области экрана
CameraProject (cam,EntityX(msh),EntityY(msh),EntityZ(msh))
iccx=ProjectedX #()
iccy=ProjectedY #()

; передвижение Mesh в сторону курсора
noko=0: xxx#=0: yyy#=0
If iccx<mx-1 Then xxx#=.1: noko=1
If iccx>mx+1 Then xxx#=-.1: noko=1
If iccy<my-1 Then yyy#=-.1: noko=1
If iccy>my+1 Then yyy#=.1: noko=1
MoveEntity msh,xxx#,yyy#,0
Until noko=0
; узнаю координату Mesh в 3Д области
xxx#=EntityX(msh): yyy#=EntityY(msh): zzz#=EntityZ(msh)
; удаляю msh за ненадобностью
FreeEntity msh

; передаю XYZ координаты для использования
XYZ$=xxx#+"\"+yyy#+"\"+zzz#+"\"
Return XYZ$

End Function
; -------------------------------------------------------------------------------
__________________
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
ABTOMAT (16.04.2020)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


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


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com