Перевод 2D координат в 3D пространство?


Автор Сообщение

бывалый
Группа: Участники
Сообщений: 39
Добавлено: 03-04-2009 08:25
Помогите пожалуйста! Сложно найти геймера который не был бы знаком с современными компьюторными стратегиями, в связи с этим возникант такой вот вопрос. Методика работы мышки в 3D пространсте, для того чтобы выбрать персонажа (верно для любой стратегической игры) необходимо навести мышку и кликнуть по его фигурке, т. е. 2d переводится в 3d, помогите как реализовать это в x3d. Мои слабые попытки не к чему не привили, я писал так:

X = ViewerScreenToWorld(global.View0,MouseGetX(),MouseGetY(),0);
//Y = ViewerScreenToWorld // Эта коорд. не нужна
// (global.View0,MouseGetX(),MouseGetY(),1);
Z = ViewerScreenToWorld(global.View0,MouseGetX(),MouseGetY(),2);

ObjectSetPosition(ind1,X,0,Z); // Позиция независимого объекта
// который должен расположиться в том месте куда смотрит
// указатель мышки.

Данная конструкция работаент неверно!

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 03-04-2009 15:18
Ну ее, эту ViewerScreenToWorld. Ее очень тяжело заставить работать корректно. Если необходимо только выделение объекта мышью, гораздо легче сделать так:

Конвертировать координаты объекта в экранные:

pos_x=ViewerWorldToScreen(view1,ObjectGetAbsolutePosition(obj,0),ObjectGetAbsolutePosition(obj,1),ObjectGetAbsolutePosition(obj,2),0);
pos_y=480-ViewerWorldToScreen(view1,
ObjectGetAbsolutePosition(obj,0),
ObjectGetAbsolutePosition(obj,1),
ObjectGetAbsolutePosition(obj,2),1);

Проверить, не кликнул ли пользователь в квадрате 32х32 вокруг данной точки на экране (если кликнул, значит объект выбран):

if keyboard_check_direct(mb_left)
{
if window_mouse_get_x()>pos_x-16
&& window_mouse_get_x()<pos_x+16
&& window_mouse_get_y()>pos_y-16
&& window_mouse_get_y()<pos_y+16
{
show_message('You clicked the object');
}
}

Вот залил пример, в нем все наглядно показано:
x3d_click_object.zip

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

бывалый
Группа: Участники
Сообщений: 39
Добавлено: 04-04-2009 05:44
Большое спасибо 2 дня мучился, составлял гиганские коды, а всё было намного проще!

бывалый
Группа: Участники
Сообщений: 49
Добавлено: 15-11-2009 19:17
Я делаю 3d редактор карт в Xtreme3D. Сделал сетку и летающую камеру. Я хочу сделать, чтобы объект появлялся в той ячейке сетки, на которую я нажму. Как определить её 3D координаты? Функция ViewerScreenToWorld() почему-то показывает позицию камеры.

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 15-11-2009 20:45
Посмотри вот этот пример.
Если надо по сетке, попробуй заменить

place_x=xx-yy*mx/my;
place_z=zz-yy*mz/my;

на

place_x=floor(xx-yy*mx/my);
place_z=floor(zz-yy*mz/my);


бывалый
Группа: Участники
Сообщений: 49
Добавлено: 16-11-2009 14:56
Спасибо, сейчас посмотрю.


Группа: Участники
Сообщений: 1
Добавлено: 21-07-2011 12:51
Посмотри вот этот пример.

Можно ли в этом примере избавиться от искажений, которые происходят, если куб далеко или близко от камеры?

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 23-07-2011 08:29
Пример на самом деле не идеален. Я недавно усовершенствовал алгоритм, по которому он работает - это опубликовано в "FPS" №14 (статья "Язык D. Практикум"). Работает практически безупречно. Там, правда, не GML и не Xtreme3D, но переписать будет несложно.

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 23-07-2011 08:33
Вот, переписал код из Normal Step. Меняется, в основном, вычисление вектора (vx, vy, vz):

aspectRatio = window_get_width() / window_get_height();
tFOV = tan(45 * pi / 360);

xx = ObjectGetAbsolutePosition(camera, 0);
yy = ObjectGetAbsolutePosition(camera, 1);
zz = ObjectGetAbsolutePosition(camera, 2);

dx = ObjectGetDirection(camera, 0);
dy = ObjectGetDirection(camera, 1);
dz = ObjectGetDirection(camera, 2);

ux = ObjectGetUpVector(camera, 0) * tFOV;
uy = ObjectGetUpVector(camera, 1) * tFOV;
uz = ObjectGetUpVector(camera, 2) * tFOV;

// v = cross(u, d) * aspectRatio
vx = ((uy * dz) - (uz * dy)) * aspectRatio;
vy = ((uz * dx) - (ux * dz)) * aspectRatio;
vz = ((ux * dy) - (uy * dx)) * aspectRatio;

width = 2 * mouse_x / window_get_width() - 1;
height = 1 - 2 * mouse_y / window_get_height();

mx = dx + ux * height + vx * width;
my = dy + uy * height + vy * width;
mz = dz + uz * height + vz * width;

place_x = xx - mx * yy / my;
place_z = xx - mx * yy / my;

 

Offtop.ru © 2003