⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trigger.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "sceneGraph/sceneState.h"
#include "dgl/dgl.h"
#include "dgl/gTexManager.h"
#include "console/consoleTypes.h"
#include "collision/boxConvex.h"

#include "core/bitStream.h"
#include "math/mathIO.h"

#include "game/trigger.h"

//-----------------------------------------------------------------------------

ConsoleMethod( TriggerData, onEnterTrigger, void, 4, 4, "( Trigger t, SimObject intruder)")
{
   Trigger* trigger = NULL;
   if (Sim::findObject(argv[2], trigger) == false)
      return;

   // Do nothing with the trigger object id by default...
   SimGroup* pGroup = trigger->getGroup();
   for (SimGroup::iterator itr = pGroup->begin(); itr != pGroup->end(); itr++)
      Con::executef(*itr, 3, "onTrigger", Con::getIntArg(trigger->getId()), "1");
}

ConsoleMethod( TriggerData, onLeaveTrigger, void, 4, 4, "( Trigger t, SimObject intruder)")
{
   Trigger* trigger = NULL;
   if (Sim::findObject(argv[2], trigger) == false)
      return;

   if (trigger->getNumTriggeringObjects() == 0) {
      SimGroup* pGroup = trigger->getGroup();
      for (SimGroup::iterator itr = pGroup->begin(); itr != pGroup->end(); itr++)
         Con::executef(*itr, 3, "onTrigger", Con::getIntArg(trigger->getId()), "0");
   }
}

ConsoleMethod( TriggerData, onTickTrigger, void, 3, 3, "(Trigger t)")
{
   Trigger* trigger = NULL;
   if (Sim::findObject(argv[2], trigger) == false)
      return;

   // Do nothing with the trigger object id by default...
   SimGroup* pGroup = trigger->getGroup();
   for (SimGroup::iterator itr = pGroup->begin(); itr != pGroup->end(); itr++)
      Con::executef(*itr, 2, "onTriggerTick", Con::getIntArg(trigger->getId()));
}

ConsoleMethod( Trigger, getNumObjects, S32, 2, 2, "")
{
   return object->getNumTriggeringObjects();
}

ConsoleMethod( Trigger, getObject, S32, 3, 3, "(int idx)")
{
   S32 index = dAtoi(argv[2]);

   if (index >= object->getNumTriggeringObjects() || index < 0)
      return -1;
   else
      return object->getObject(U32(index))->getId();
}

//----------------------------------------------------------------------------

IMPLEMENT_CO_DATABLOCK_V1(TriggerData);

TriggerData::TriggerData()
{
   tickPeriodMS = 100;
}

bool TriggerData::onAdd()
{
   if (!Parent::onAdd())
      return false;

   return true;
}

void TriggerData::initPersistFields()
{
   Parent::initPersistFields();

   addField("tickPeriodMS", TypeS32,  Offset(tickPeriodMS, TriggerData));
}


//--------------------------------------------------------------------------
void TriggerData::packData(BitStream* stream)
{
   Parent::packData(stream);
   stream->write(tickPeriodMS);
}

void TriggerData::unpackData(BitStream* stream)
{
   Parent::unpackData(stream);
   stream->read(&tickPeriodMS);
}


//--------------------------------------------------------------------------

IMPLEMENT_CO_NETOBJECT_V1(Trigger);

Trigger::Trigger()
{
   // Don't ghost by default.
   mNetFlags.clear(Ghostable);

   mTypeMask |= TriggerObjectType;

   mObjScale.set(1, 1, 1);
   mObjToWorld.identity();
   mWorldToObj.identity();

   mDataBlock = NULL;

   mLastThink = 0;
   mCurrTick  = 0;

   mConvexList = new Convex;
}

Trigger::~Trigger()
{
   delete mConvexList;
   mConvexList = NULL;
}

bool Trigger::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
{
   // Collide against bounding box
   F32 st,et,fst = 0,fet = 1;
   F32 *bmin = &mObjBox.min.x;
   F32 *bmax = &mObjBox.max.x;
   F32 const *si = &start.x;
   F32 const *ei = &end.x;

   for (int i = 0; i < 3; i++) 
   {
      if (*si < *ei) 
      {
         if (*si > *bmax || *ei < *bmin)
            return false;
         F32 di = *ei - *si;
         st = (*si < *bmin)? (*bmin - *si) / di: 0;
         et = (*ei > *bmax)? (*bmax - *si) / di: 1;
      }
      else 
      {
         if (*ei > *bmax || *si < *bmin)
            return false;
         F32 di = *ei - *si;
         st = (*si > *bmax)? (*bmax - *si) / di: 0;
         et = (*ei < *bmin)? (*bmin - *si) / di: 1;
      }
      if (st > fst) fst = st;
      if (et < fet) fet = et;
      if (fet < fst)
         return false;
      bmin++; bmax++;
      si++; ei++;
   }

   info->normal = start - end;
   info->normal.normalizeSafe();
   getTransform().mulV( info->normal );

   info->t = fst;
   info->object = this;
   info->point.interpolate(start,end,fst);
   info->material = 0;
   return true;
}


//--------------------------------------------------------------------------
/* Console polyhedron data type exporter
   The polyhedron type is really a quadrilateral and consists of a corner
   point follow by three vectors representing the edges extending from the
   corner.
*/
ConsoleType( TriggerPolyhedron, TypeTriggerPolyhedron, sizeof(Polyhedron) )


ConsoleGetType( TypeTriggerPolyhedron )
{
   U32 i;
   Polyhedron* pPoly = reinterpret_cast<Polyhedron*>(dptr);

   // First point is corner, need to find the three vectors...`
   Point3F origin = pPoly->pointList[0];
   U32 currVec = 0;
   Point3F vecs[3];
   for (i = 0; i < pPoly->edgeList.size(); i++) {
      const U32 *vertex = pPoly->edgeList[i].vertex;
      if (vertex[0] == 0)
         vecs[currVec++] = pPoly->pointList[vertex[1]] - origin;
      else
         if (vertex[1] == 0)
            vecs[currVec++] = pPoly->pointList[vertex[0]] - origin;
   }
   AssertFatal(currVec == 3, "Internal error: Bad trigger polyhedron");

   // Build output string.
   char* retBuf = Con::getReturnBuffer(1024);
   dSprintf(retBuf, 1023, "%7.7f %7.7f %7.7f %7.7f %7.7f %7.7f %7.7f %7.7f %7.7f %7.7f %7.7f %7.7f",
            origin.x, origin.y, origin.z,
            vecs[0].x, vecs[0].y, vecs[0].z,
            vecs[2].x, vecs[2].y, vecs[2].z,
            vecs[1].x, vecs[1].y, vecs[1].z);

   return retBuf;
}

/* Console polyhedron data type loader
   The polyhedron type is really a quadrilateral and consists of an corner
   point follow by three vectors representing the edges extending from the
   corner.
*/
ConsoleSetType( TypeTriggerPolyhedron )
{
   if (argc != 1) {
      Con::printf("(TypeTriggerPolyhedron) multiple args not supported for polyhedra");
      return;
   }

   Point3F origin;
   Point3F vecs[3];

   U32 numArgs = dSscanf(argv[0], "%g %g %g %g %g %g %g %g %g %g %g %g",
                         &origin.x, &origin.y, &origin.z,
                         &vecs[0].x, &vecs[0].y, &vecs[0].z,
                         &vecs[1].x, &vecs[1].y, &vecs[1].z,
                         &vecs[2].x, &vecs[2].y, &vecs[2].z);
   if (numArgs != 12) {
      Con::printf("Bad polyhedron!");
      return;
   }

   Polyhedron* pPoly = reinterpret_cast<Polyhedron*>(dptr);

   pPoly->pointList.setSize(8);
   pPoly->pointList[0] = origin;
   pPoly->pointList[1] = origin + vecs[0];
   pPoly->pointList[2] = origin + vecs[1];
   pPoly->pointList[3] = origin + vecs[2];
   pPoly->pointList[4] = origin + vecs[0] + vecs[1];
   pPoly->pointList[5] = origin + vecs[0] + vecs[2];
   pPoly->pointList[6] = origin + vecs[1] + vecs[2];
   pPoly->pointList[7] = origin + vecs[0] + vecs[1] + vecs[2];

   Point3F normal;
   pPoly->planeList.setSize(6);

   mCross(vecs[2], vecs[0], &normal);
   pPoly->planeList[0].set(origin, normal);
   mCross(vecs[0], vecs[1], &normal);
   pPoly->planeList[1].set(origin, normal);
   mCross(vecs[1], vecs[2], &normal);
   pPoly->planeList[2].set(origin, normal);
   mCross(vecs[1], vecs[0], &normal);
   pPoly->planeList[3].set(pPoly->pointList[7], normal);
   mCross(vecs[2], vecs[1], &normal);
   pPoly->planeList[4].set(pPoly->pointList[7], normal);
   mCross(vecs[0], vecs[2], &normal);
   pPoly->planeList[5].set(pPoly->pointList[7], normal);

   pPoly->edgeList.setSize(12);
   pPoly->edgeList[0].vertex[0]  = 0; pPoly->edgeList[0].vertex[1]  = 1; pPoly->edgeList[0].face[0]  = 0; pPoly->edgeList[0].face[1]  = 1;
   pPoly->edgeList[1].vertex[0]  = 1; pPoly->edgeList[1].vertex[1]  = 5; pPoly->edgeList[1].face[0]  = 0; pPoly->edgeList[1].face[1]  = 4;
   pPoly->edgeList[2].vertex[0]  = 5; pPoly->edgeList[2].vertex[1]  = 3; pPoly->edgeList[2].face[0]  = 0; pPoly->edgeList[2].face[1]  = 3;
   pPoly->edgeList[3].vertex[0]  = 3; pPoly->edgeList[3].vertex[1]  = 0; pPoly->edgeList[3].face[0]  = 0; pPoly->edgeList[3].face[1]  = 2;
   pPoly->edgeList[4].vertex[0]  = 3; pPoly->edgeList[4].vertex[1]  = 6; pPoly->edgeList[4].face[0]  = 3; pPoly->edgeList[4].face[1]  = 2;
   pPoly->edgeList[5].vertex[0]  = 6; pPoly->edgeList[5].vertex[1]  = 2; pPoly->edgeList[5].face[0]  = 2; pPoly->edgeList[5].face[1]  = 5;
   pPoly->edgeList[6].vertex[0]  = 2; pPoly->edgeList[6].vertex[1]  = 0; pPoly->edgeList[6].face[0]  = 2; pPoly->edgeList[6].face[1]  = 1;
   pPoly->edgeList[7].vertex[0]  = 1; pPoly->edgeList[7].vertex[1]  = 4; pPoly->edgeList[7].face[0]  = 4; pPoly->edgeList[7].face[1]  = 1;
   pPoly->edgeList[8].vertex[0]  = 4; pPoly->edgeList[8].vertex[1]  = 2; pPoly->edgeList[8].face[0]  = 1; pPoly->edgeList[8].face[1]  = 5;
   pPoly->edgeList[9].vertex[0]  = 4; pPoly->edgeList[9].vertex[1]  = 7; pPoly->edgeList[9].face[0]  = 4; pPoly->edgeList[9].face[1]  = 5;
   pPoly->edgeList[10].vertex[0] = 5; pPoly->edgeList[10].vertex[1] = 7; pPoly->edgeList[10].face[0] = 3; pPoly->edgeList[10].face[1] = 4;
   pPoly->edgeList[11].vertex[0] = 7; pPoly->edgeList[11].vertex[1] = 6; pPoly->edgeList[11].face[0] = 3; pPoly->edgeList[11].face[1] = 5;
}


//-----------------------------------------------------------------------------

void Trigger::initPersistFields()
{
   Parent::initPersistFields();

   addField("polyhedron", TypeTriggerPolyhedron, Offset(mTriggerPolyhedron, Trigger));
}


//--------------------------------------------------------------------------

bool Trigger::onAdd()
{
   if(!Parent::onAdd())
      return false;

   Con::executef(this, 2, "onAdd", Con::getIntArg(getId()));

   Polyhedron temp = mTriggerPolyhedron;
   setTriggerPolyhedron(temp);

   addToScene();

   return true;
}

void Trigger::onRemove()
{
   Con::executef(this, 2, "onRemove", Con::getIntArg(getId()));

   mConvexList->nukeList();

   removeFromScene();
   Parent::onRemove();
}

bool Trigger::onNewDataBlock(GameBaseData* dptr)
{
   mDataBlock = dynamic_cast<TriggerData*>(dptr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -