Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.13;
Скачать: CL | DM;

Вниз

Клик!   Найти похожие ветки 

 
Bryke   (2004-12-05 16:30) [0]

Как в играх типа "Warcraft" определяется координата на 3D-ландшафте, куда кликнул геймер?
Мож кто знает...


 
TButton ©   (2004-12-05 17:30) [1]

элементарно.
ибо курсор есть объект, который мняет свое положение на карте игры в соответсвии с перемещением мыши.

даже если это не так, это как-то можно сделать, ибо, натыкался на исходники програмули, которая рисовала пирамидку, реагируя на наведение мыши на опр. полигон.


 
DeadMeat ©   (2004-12-05 18:29) [2]

Вообще это зависит, от того, на чем ты пишешь... D3D или OGL... у обоих есть свои функции для этого...
Вот например в GLScene это ScreenToVector и т.п... их там несколько на все случаи жизни..

---
...Death Is Only The Begining...


 
dimodim-modern   (2004-12-05 22:35) [3]

Screentoworld акак начет screentovector = объясни


 
wiz ©   (2004-12-06 07:32) [4]

задача абсолютно аналогична проверке "попадает ли выбранный полигон (или тайл) в Frustum камеры"... только в данном случае нужно frustum строить не по всему экрану, а только вокруг курсора.

Это не самый оптимальный вариант, зато наверняка сработает :)

---
бритва Оккама: "Не создавайте сущности сверх необходимого"


 
Bryke   (2004-12-06 12:40) [5]


> Вообще это зависит, от того, на чем ты пишешь... D3D или
> OGL...

Пишу на D3D (чистом)


 
Bryke   (2004-12-06 12:46) [6]

wiz,
Подробнее можно?
Или скинь на мыло.


 
П7   (2004-12-06 15:41) [7]

На http://GameDev.ru есть пара статей на эту тему. Далее принцыпы можно подчерпнуть из исходников к конкурсу по DrkBASIC"у. Был там у них такой конкурс, мол определить координаты в 3D"пространстве, искать через рамблер. В книге "OpenGL в проектах Delphi" расказывается пара способов этого фокуса. Ну и... РАМБЛЕР твой друг! (:


 
wiz ©   (2004-12-07 06:52) [8]

2 Bryke: "Яndex - найдётся всё"... проверил - первые 5-10 ссылок на запрос "frustum" - твои :)

а вообще - я тут подумал и пришло в голову, что наверное лучше будет не искать попадение полигона в пирамиду мыши, а искать попадение точки мыши (которая на проекционной плоскости) в фигуру образованную вершинами полигона и eye-position.

PS: ну это всё конечно я говорю для _нерегулярной_ сетки, такой, как в warcraft 3 и подобных... если сетка регулярная (например карта высот), то использование описанных выше способов (конечно) будет, в некотором роде, идиотизмом - можно сделать всё проще и быстрее. Как? Впитайте в свои вены "Аналитическую геометрию" - и ответ придёт сам собой :)


 
Sapersky   (2004-12-07 11:15) [9]

Если "чистый D3D" подразумевает использование D3DX, то сначала D3DXUnproject, потом raycast-функции - D3DXBoxBoundProbe (D3DXSphereBoundProbe), D3DXIntersect (D3DXIntersectSubset) или D3DXIntersectTri. Если нужны исходники подобных ф-ий - они есть, например, в GLScene (VectorGeometry.pas).

если сетка регулярная (например карта высот), [...] можно сделать всё проще и быстрее

Вот, например - спроецировать луч на плоскость карты, определить ячейки сетки, в которые он попадает (нарисовать "растровую линию" на карте высот, алгоритмом Брезенхема или ещё как) и проверять последовательно (от начала луча) эту "линию".


 
Bryke   (2004-12-07 15:13) [10]


> Если "чистый D3D" подразумевает использование D3DX, то

Я не использую d3dx, использую dxgutils.
Существуют ли еще способы?


 
Sapersky   (2004-12-07 18:09) [11]

UnProject можно и вручную расписать:

// InvViewMat - инвертированная видовая матрица - инвертирование в DXGUtils должно быть
// HalfViewSize - половина размера окна вывода
procedure VectorUnProject(Const Src : TVector; Const InvViewMat : TMatrix;
                                       Const ProjMat : TMatrix; Const HalfViewSize : TPoint;
                                       Var Dir, Offset : TVector);
Var v : TVector;
begin
v.x :=  ( ( Src.x / HalfViewSize.x ) - 1) / ProjMat._11;
v.y := -( ( Src.y / HalfViewSize.y ) - 1) / ProjMat._22;
v.z := 1.0;

With InvViewMat do begin
 Dir.x  := v.x * _11 + v.y * _21 + v.z * _31;
 Dir.y  := v.x * _12 + v.y * _22 + v.z * _32;
 Dir.z  := v.x * _13 + v.y * _23 + v.z * _33;
 Offset := Vector(_41, _42, _43);
end;
end;

Offset, Dir - начальная точка и направление луча, в кот. преобразуются коорд. мыши.
Спроецировать луч на плоскость (напр. XY) можно так:

StartAtPlane.x:=Offset.x; StartAtPlane.y:=Offset.y; StartAtPlane.z:=0; // ну это сугубо для ясности :)
EndAtPlane:=VectorAdd(Offset, VectorMulS(Dir, - Offset.z / Dir.z) );

Проверка пересечения луча с треугольником, сферой, произвольной плоскостью - см., повторяю, исходники GLScene (OGL, D3D - в данном случае неважно, это чистая геометрия) или вот:

http://www.geometryalgorithms.com/algorithm_archive.htm


 
MsShtaer   (2004-12-07 21:38) [12]

Ребята в шейдерах есть команда MRT (Multi Render Target). Когда воспроизводите сцену, воспроизводите коды полигонов на вторую таргет. А потом просто проверьте цвет пикселей. Быстро и просто.


 
Bryke   (2004-12-08 22:29) [13]


> Быстро и просто.

А еще ресурсоемко.:)


 
Bryke   (2004-12-08 22:48) [14]

Sapersky,
спасибо буду разбираться.


 
cyborg ©   (2004-12-09 09:52) [15]


> [12] MsShtaer   (07.12.04 21:38)

Интересно, разжуй пожалуйста ;)


 
Sapersky   (2004-12-09 13:52) [16]

Насколько я понял, это то же самое, что и старый "добрый" метод, который ещё у Краснова был. Только там всё рендерилось безо всяких MRT - в два прохода, сначала для проверки (разными цветами), потом собственно вывод.
Да, возможно, с MRT будет несколько быстрее, поскольку рисуется всё 1 раз, хотя и не верится, что вывод на вторую таргет - совсем уж "бесплатно" (особенно для владельцев карт без шейдеров - цена будет в $$$ :)). А при 2-проходном выводе можно на первом проходе рисовать упрощённую геометрию.
Но в любом случае рендер таргет придётся лочить, чтобы проверить значение пикселя. Со всеми вытекающими.


 
Bryke   (2004-12-09 15:27) [17]

Sapersky,
Все отлично работает, координаты находятся.
Блин, я не ожидал такого эффекта.
В общем спасибо.


 
cyborg ©   (2004-12-09 18:22) [18]


> Но в любом случае рендер таргет придётся лочить, чтобы проверить
> значение пикселя. Со всеми вытекающими.

Не обязательно же весь экран лочить, можно одну конкретную точку ;)


 
MsShtaer   (2004-12-09 22:32) [19]

>Не обязательно же весь экран лочить, можно одну конкретную точку ;)
Согласен.
И вот что вам скажу. Рендер таргет приводит к замедлению процента на 3. Насчёт подробнее. У фирмы ATI есть бесплатная софтина RenderMonkey(У NVIDIA - Cg) эта софтина создаёт .fx файлы их можно подключать к делфи с помощью ID3DEffect9 (у GL незнаю, но как-то можно). Ещё подробнее не могу, т.к. только описание Обезьянки занимает 290 страниц.


 
Sapersky   (2004-12-10 13:43) [20]

Не обязательно же весь экран лочить, можно одну конкретную точку ;)

Э-э... ну да :)
Совсем меня запугали мелкософт и прочие авторитетные товарищи со своим "руками не трогать" (не блокировать видеопамять) и "против течения не плыть" (не читать из видеопамяти). Так что рефлекс срабатывает - "Lock = ПЛОХО", независимо от обстоятельств :)
На самом деле, должны быть ещё некие накладные расходы на саму блокировку. Вряд ли большие, впрочем - в DX7, насколько помню, время обработки было практически пропорционально объёму обработанных данных (при этом даже указываемый LockRect особой роли не играл). В DX8-9 надо бы протестировать...
Но всё равно не нравится мне этот метод :) Или два раза рисовать, или шейдеры нужны. Опять же, геометрические методы универсальнее - raycast-функциями можно проверять на попадание не только мышь, но и другие объекты, которые можно представить лучом.



Страницы: 1 вся ветка

Текущий архив: 2005.03.13;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.031 c
14-1108479143
GRAND25
2005-02-15 17:52
2005.03.13
Новый футбольный сезон


14-1109046319
boriskb
2005-02-22 07:25
2005.03.13
Вы согласны с такой оценкой WinXP ?


1-1109687795
Phoenix9000
2005-03-01 17:36
2005.03.13
Поиск в подкаталоге


1-1109279193
akvilon
2005-02-25 00:06
2005.03.13
один TStrings


4-1107253055
grigory
2005-02-01 13:17
2005.03.13
Как по процессу узнать заголовок окна?