Проверка столкновений


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

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 07-03-2009 09:47
Скажите, а как сделать расчет столкновения между двумя объектами? например когда один объект касается второго, как расчитать координаты места их соприкосновения?

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 07-03-2009 16:54
В Экстриме есть много способов для этого. Самые простые - это стандартные функции ObjectCheck... (ObjectCheckCubeVsCube, ObjectCheckSphereVsFace и др.), они определяют факт столкновения между двумя объектами (а точнее, их ограничивающими кубами или сферами). Но их использовать не всегда удобно. К тому же, я не уверен, что таким образом можно получить координаты столкновения.
Поэтому существуют другие, узкоспециализированные функции.

Например, трассировка лучей (raycasting). Заданный объект испускает луч, и другие объекты проверяются на пересечение с этим лучом. При этом очень легко получить координаты точки и нормаль полигона пересечения. Лови пример.

Для работы с простейшей физикой (например, когда надо, чтобы персонаж перемещался по карте) можно использовать DCE (Dynamic Collision Engine). Смотри эту тему.

Есть также множество других способов: FPS Manager, ODE, ObjectGetGroundHeight и др. Если надо, расскажу и про них.
Все зависит от того, какую именно игру делаешь и какого характера столкновения надо реализовать.

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 08-03-2009 09:40
Ясно! =) спасибо за примеры! кстати, а где столкновения считываются быстрее в FPS manager или CDE ? и что означает эта функция FpsGetCollisionPosition ? мне просто нужно сделать пулю которая при попадание в стены уничтожалась.... и еще вопрос, boundingbox создается только в режиме DCE?

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 08-03-2009 21:20
В DCE быстрее.
FpsGetCollisionPosition(obj,index,ind) возвращает координату точки столкновения объекта obj с объектом-картой (ind соответствует нужной координате, т.е., если ind=0, то возвращается x; если ind=1; то y, если ind=2, то z). Хотя я не уверен - FPS Manager еще толком не тестил, руки не доходят) Экспериментируй! В этом весь Экстрим.
Для пули лучше всего брать raycasting.
Насчет bounding box: вручную его можно задать только в DCE, FPS Manager (там bounding sphere) и ODE. Все остальные функции столкновений работают с bb и bsphere, автоматически вычисленными движком, исходя из размеров объекта (например, если это куб 2x2x2, то его bb будет тоже 2x2x2).

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 09-03-2009 06:43
Понятно! а в DCE можно работать с FreeForm? и есть еще способы вычисления столкновения для пуль? просто если сделать вместо пули ракету как сделать чобы она взрывалась о препятствия? и можно немного поподробнее о FpsGetCollisionPosition =) а то я по всякому пробовал ее использовать но ничего не получается =( что за collisionindex который часто встречается во множественных функциях столкновений?

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 09-03-2009 08:03
DCE с freeform работает чуть ли не лучше всех остальных))
Про пулю я уже сказал, лучше raycasting'ом... Хотя если ракета - то это тот случай, где можно использовать ObjectCheckCubeVsFace(obj1,obj2). obj1 - это ракета, obj2 - препятствие (подозреваю, что это именно тот самый фриформ карты). Функция возвращает 1, если объекты соприкоснулись. Если возвратила, останавливаешь движение ракеты и берешь ее координаты:

rocket_x=ObjectGetAbsolutePosition(rocket,0);
rocket_y=ObjectGetAbsolutePosition(rocket,1);
rocket_z=ObjectGetAbsolutePosition(rocket,2);

и на этих координатах создаешь взрыв, или что там тебе нужно. А ракету либо уничтожаешь, либо (что более разумно) просто прячешь.
Тебе для этого FpsGetCollisionPosition не обязателен.
Кстати, насколько я понял, делаешь шутер? Если так, то, как ни парадоксально, лучше не использовать FPS Manager, а брать тот же DCE. Лучше его я не видел - самая толковая система столкновений.
В Экстриме ведь что интересно: можно комбинировать технологии, они друг с другом не конфликтуют. То есть, при включенном ODE или DCE использовать raycasting и ObjectCheck...().
Кстати, если вместо фриформов использовать для карты простые кубики, то производительность возрастет в разы (правда, это подойдет скорее в платформере чем в шутере). Это я так, к слову.

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 09-03-2009 08:09
Насчет collisionindex - хрен его знает... Я просто пишу к Экстриму док, так вот, до FPS Менеджера еще не дошел. Как дойду, буду тестить - тогда и выяснится.

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 10-03-2009 12:35
Ок! =)
и еще вопрос немного не теме... я никак ене могу HUD нормально сделать... он почему-то за объекты прячется =(

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 10-03-2009 12:43
А ты ему в parent объект global.front поставил?

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 10-03-2009 13:09
а! все! =) понял! нужно сооблюдать очередность parent так как тот объект у кого pfrent был создан позже будет перекрывать тот у кого parent был создан раньше =)

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 10-03-2009 16:01
Ну да, это называется сортировка.

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 13-03-2009 09:29
как правильно использовать Dcemanager? просто я создаю его,но команда DceApplyAcceleration не работает =( объект не движется... и посоветуйте как удобнее сделать, чтобы два движущихся объекта при столкновении останавливались и скользили друг об друга...

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 13-03-2009 19:10
Ну давай разбираться.
Запускаем DCE:

dce=DceManagerCreate();
DceManagerSetManualStep(dce,1);

Создаем динамический объект:

dynamic=SphereCreate(5,8,8,global.scene);
DceSetManager(dynamic,dce);
DceSetUseGravity(dynamic,0);
DceSetActive(dynamic,true);
DceSetSize(dynamic,5,5,5);
DceSetSolid(dynamic,1);
DceSetSlideOrBounce(dynamic,0);
ObjectSetPosition(dynamic,0,5,0);
DceSetFriction(dynamic,1.5);

Применяем ускорение:

DceApplyAcceleration(dynamic,15,0,0);

И обновляем состояние DCE:

DceManagerStep(dce,0.1);

Должно работать!

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 14-03-2009 07:29
Спасибо! =) теперь заработало просто я пропустил функцию DceSetUseGravity...
а как в DCE с фриформой работать? чтобы объект по карте двигался и об ее препятствия сталкивался?

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 14-03-2009 14:56
Создаешь статический объект:

map=FreeformCreate("map.3ds",global.scene);
DceStaticSetManager(map,dce);
DceStaticSetActive(map,true);
DceStaticSetShape(map,2);
DceStaticSetSolid(map,1);

Функция DceStaticSetShape(map,2) указывает, как обрабатывать
столкновения с объектом. Если указать 0 - то по BSphere,
если 1 - по BB, если 2 - по геометрии (что и нужно для фриформы).

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 14-03-2009 15:46
Большое Спасибо за помощь! =)

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 16-03-2009 09:38
Скажите а что такое Delta в DceMove(object,x,y,z,delta)?

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 16-03-2009 19:02
Толком не знаю... Если поставить в delta ноль, движения не произойдет, если, например, 3, движение будет слишком быстрым. При этом это точно не скорость, так как за линейную скорость движения отвечает вектор x,y,z. Я обычно использую DceMove для гравитации (автоматическая гравитация DCE у меня не работает) и в delta ставлю 0.5

частый гость
Группа: Участники
Сообщений: 23
Добавлено: 18-03-2009 09:12
Понятно! =)
я думаю, что в качестве дельты здесь удобно использовать дельту времени для оптимизации скорости перемещения в зависимости от количества ФПСов... то есть в качестве Дельты в этой функции удобно использовать формулу: (Норма ФПС)/fps, то есть если норма ФПС к примеру 30 то, при уменьшении кол-ва фпс в игре объект не потеряет скорости перемещения за счет автоматического ускорения во столько раз, сколько составит величина (Норма ФПС)/fps...

Big Boss
Группа: Администраторы
Сообщений: 719
Добавлено: 18-03-2009 19:44
Да, скорее всего дельта введена именно для этого.

 

Offtop.ru © 2003