![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Клик!
Bryke © (2004-12-05 16:30:00)Как в играх типа "Warcraft" определяется координата на 3D-ландшафте, куда кликнул геймер?
Мож кто знает...
Sapersky (2004-12-10 13:43:00) [1]Не обязательно же весь экран лочить, можно одну конкретную точку ;)
Э-э... ну да :)
Совсем меня запугали мелкософт и прочие авторитетные товарищи со своим "руками не трогать" (не блокировать видеопамять) и "против течения не плыть" (не читать из видеопамяти). Так что рефлекс срабатывает - "Lock = ПЛОХО", независимо от обстоятельств :)
На самом деле, должны быть ещё некие накладные расходы на саму блокировку. Вряд ли большие, впрочем - в DX7, насколько помню, время обработки было практически пропорционально объёму обработанных данных (при этом даже указываемый LockRect особой роли не играл). В DX8-9 надо бы протестировать...
Но всё равно не нравится мне этот метод :) Или два раза рисовать, или шейдеры нужны. Опять же, геометрические методы универсальнее - raycast-функциями можно проверять на попадание не только мышь, но и другие объекты, которые можно представить лучом.
MsShtaer (2004-12-09 22:32:00) [2]>Не обязательно же весь экран лочить, можно одну конкретную точку ;)
Согласен.
И вот что вам скажу. Рендер таргет приводит к замедлению процента на 3. Насчёт подробнее. У фирмы ATI есть бесплатная софтина RenderMonkey(У NVIDIA - Cg) эта софтина создаёт .fx файлы их можно подключать к делфи с помощью ID3DEffect9 (у GL незнаю, но как-то можно). Ещё подробнее не могу, т.к. только описание Обезьянки занимает 290 страниц.
cyborg (2004-12-09 18:22:00) [3]
> Но в любом случае рендер таргет придётся лочить, чтобы проверить
> значение пикселя. Со всеми вытекающими.
Не обязательно же весь экран лочить, можно одну конкретную точку ;)
Bryke (2004-12-09 15:27:00) [4]Sapersky,
Все отлично работает, координаты находятся.
Блин, я не ожидал такого эффекта.
В общем спасибо.
Sapersky (2004-12-09 13:52:00) [5]Насколько я понял, это то же самое, что и старый "добрый" метод, который ещё у Краснова был. Только там всё рендерилось безо всяких MRT - в два прохода, сначала для проверки (разными цветами), потом собственно вывод.
Да, возможно, с MRT будет несколько быстрее, поскольку рисуется всё 1 раз, хотя и не верится, что вывод на вторую таргет - совсем уж "бесплатно" (особенно для владельцев карт без шейдеров - цена будет в $$$ :)). А при 2-проходном выводе можно на первом проходе рисовать упрощённую геометрию.
Но в любом случае рендер таргет придётся лочить, чтобы проверить значение пикселя. Со всеми вытекающими.
cyborg (2004-12-09 09:52:00) [6]
> [12] MsShtaer (07.12.04 21:38)
Интересно, разжуй пожалуйста ;)
Bryke (2004-12-08 22:48:00) [7]Sapersky,
спасибо буду разбираться.
Bryke (2004-12-08 22:29:00) [8]
> Быстро и просто.
А еще ресурсоемко.:)
MsShtaer (2004-12-07 21:38:00) [9]Ребята в шейдерах есть команда MRT (Multi Render Target). Когда воспроизводите сцену, воспроизводите коды полигонов на вторую таргет. А потом просто проверьте цвет пикселей. Быстро и просто.
Sapersky (2004-12-07 18:09:00) [10]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
Bryke (2004-12-07 15:13:00) [11]
> Если "чистый D3D" подразумевает использование D3DX, то
Я не использую d3dx, использую dxgutils.
Существуют ли еще способы?
Sapersky (2004-12-07 11:15:00) [12]Если "чистый D3D" подразумевает использование D3DX, то сначала D3DXUnproject, потом raycast-функции - D3DXBoxBoundProbe (D3DXSphereBoundProbe), D3DXIntersect (D3DXIntersectSubset) или D3DXIntersectTri. Если нужны исходники подобных ф-ий - они есть, например, в GLScene (VectorGeometry.pas).
если сетка регулярная (например карта высот), [...] можно сделать всё проще и быстрее
Вот, например - спроецировать луч на плоскость карты, определить ячейки сетки, в которые он попадает (нарисовать "растровую линию" на карте высот, алгоритмом Брезенхема или ещё как) и проверять последовательно (от начала луча) эту "линию".
wiz (2004-12-07 06:52:00) [13]2 Bryke: "Яndex - найдётся всё"... проверил - первые 5-10 ссылок на запрос "frustum" - твои :)
а вообще - я тут подумал и пришло в голову, что наверное лучше будет не искать попадение полигона в пирамиду мыши, а искать попадение точки мыши (которая на проекционной плоскости) в фигуру образованную вершинами полигона и eye-position.
PS: ну это всё конечно я говорю для _нерегулярной_ сетки, такой, как в warcraft 3 и подобных... если сетка регулярная (например карта высот), то использование описанных выше способов (конечно) будет, в некотором роде, идиотизмом - можно сделать всё проще и быстрее. Как? Впитайте в свои вены "Аналитическую геометрию" - и ответ придёт сам собой :)
П7 (2004-12-06 15:41:00) [14]На http://GameDev.ruесть пара статей на эту тему. Далее принцыпы можно подчерпнуть из исходников к конкурсу по DrkBASIC'у. Был там у них такой конкурс, мол определить координаты в 3D'пространстве, искать через рамблер. В книге "OpenGL в проектах Delphi" расказывается пара способов этого фокуса. Ну и... РАМБЛЕР твой друг! (:
Bryke (2004-12-06 12:46:00) [15]wiz,
Подробнее можно?
Или скинь на мыло.
Bryke (2004-12-06 12:40:00) [16]
> Вообще это зависит, от того, на чем ты пишешь... D3D или
> OGL...
Пишу на D3D (чистом)
wiz (2004-12-06 07:32:00) [17]задача абсолютно аналогична проверке "попадает ли выбранный полигон (или тайл) в Frustum камеры"... только в данном случае нужно frustum строить не по всему экрану, а только вокруг курсора.
Это не самый оптимальный вариант, зато наверняка сработает :)
---
бритва Оккама: 'Не создавайте сущности сверх необходимого'
dimodim-modern (2004-12-05 22:35:00) [18]Screentoworld акак начет screentovector = объясни
DeadMeat (2004-12-05 18:29:00) [19]Вообще это зависит, от того, на чем ты пишешь... D3D или OGL... у обоих есть свои функции для этого...
Вот например в GLScene это ScreenToVector и т.п... их там несколько на все случаи жизни..
---
...Death Is Only The Begining...
TButton (2004-12-05 17:30:00) [20]элементарно.
ибо курсор есть объект, который мняет свое положение на карте игры в соответсвии с перемещением мыши.
даже если это не так, это как-то можно сделать, ибо, натыкался на исходники програмули, которая рисовала пирамидку, реагируя на наведение мыши на опр. полигон.