Форум: "Игры";
Текущий архив: 2005.03.13;
Скачать: [xml.tar.bz2];
ВнизКлик! Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.036 c