• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
  • Друзья, доброго времени суток! Спешите принять участие в оценке работ на конкурсе "Таинственные миры" 2024!
    Ждем именно вас!

    Ссылка на конкурсную тему - тык
    Ссылка на тему с работами участников- тык

Gothic ½ Коллизии с подвижными телами | zSoftskinCollisions [плагин для Union]

Gratt


Модостроитель
Регистрация
14 Ноя 2014
Сообщения
3.281
Благодарности
4.581
Баллы
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).

1657357928427.png


1657358982100.png
 

KirTheSeeker

Участник форума
Регистрация
18 Авг 2017
Сообщения
1.900
Благодарности
536
Баллы
275
Задачи:
- Получение точек пересечения с моделью NPC
- Получение кости в точке пересечения
Я мало что полял, но очень рад, что ты не перестаёшь развивать Готику.
Удачи и терпения.
 
Сверху Снизу