Gratt

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

 
		 
 
		