Gratt
Модостроитель
- Регистрация
- 14 Ноя 2014
- Сообщения
- 3.301
- Благодарности
- 4.636
- Баллы
- 625
zSoftskinCollisions
Исходный код: GitHub
Библиотека: GDrive
Задачи:
- Получение точек пересечения с моделью NPC
- Получение кости в точке пересечения
Подробно:
Техноплагин, задача которого расширить разработчикам возможности взаимодействия с игрой.
Известно, что игра не умеет просчитывать столкновения с динамическими объектами, а потому невозможно получить подробную точку пересечения луча и тела NPC. Для того, чтобы получить эту точку, необходимо поместить данный плагин в Autorun вашего проекта, а в любом другом плагине добавить дополнительный флаг для трассировки:
C++:
enum {
zTRACERAY_NPC_SOFTSKIN = 1 << 26
};
Далее следует просто передать этот флаг в качестве аргумента трассирующей функции. К примеру, нарисуем красный крест в точке пересечения взгляда камеры и персонажа.
C++:
void DrawCross3D( const zMAT4& trafo, const zVEC3& location, const zCOLOR& color, const float& size ) {
zVEC3 up = trafo.GetUpVector();
zVEC3 right = trafo.GetRightVector();
zlineCache->Line3D(
location + (-up + -right) * size,
location + ( up + right) * size,
color, 0 );
zlineCache->Line3D(
location + ( up + -right) * size,
location + (-up + right) * size,
color, 0 );
}
void Game_Loop() {
oCWorld* world = ogame->GetGameWorld();
zCVob* cameraVob = ogame->GetCameraVob();
zVEC3 rayStart = cameraVob->GetPositionWorld();
zVEC3 ray = cameraVob->GetAtVectorWorld() * 500.0f;
int ok = world->TraceRayNearestHit( rayStart, ray, player, zTRACERAY_NPC_SOFTSKIN );
if( ok ) {
zTTraceRayReport& report = world->traceRayReport;
DrawCross3D( cameraVob->trafoObjToWorld, report.foundIntersection, GFX_WHITE, 1.5f );
zCVob* foundVob = report.foundVob;
if( foundVob && foundVob->type == zVOB_TYPE_NSC ) {
oCNpc* npc = reinterpret_cast<oCNpc*>(foundVob);
DrawCross3D( cameraVob->trafoObjToWorld, report.foundIntersection, GFX_RED, 5.0f );
zCModel* model = npc->GetModel();
int nodeId = reinterpret_cast<int&>( report.foundVertex );
if( nodeId != Invalid && nodeId < model->nodeList.GetNum() ) {
zCModelNodeInst* nodeInst = model->nodeList[nodeId];
screen->PrintCX( 2500, nodeInst->protoNode->nodeName );
}
}
}
}
Мы увидим следующий результат. Обратите внимание, что также на экран выводится название кости, к которой привязан полигон в точке пересечения. Если foundVob можно привести к oCNpc и флаги трассировки содержат zTRACERAY_NPC_SOFTSKIN, то в report.foundVertex вместо вертекса будет лежать индекс кости в диапазоне от 0 до nodeList.size-1. Если кость невалидна, то индекс будет иметь значение Invalid (-1).