123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- #include "navMeshTestTool.h"
- #include "navigation/guiNavEditorCtrl.h"
- #include "console/consoleTypes.h"
- #include "gfx/gfxDrawUtil.h"
- #include "scene/sceneManager.h"
- #include "math/mathUtils.h"
- #include "T3D/gameBase/gameConnection.h"
- #include "T3D/AI/AIController.h"
- IMPLEMENT_CONOBJECT(NavMeshTestTool);
- //// take control
- // GameConnection* conn = GameConnection::getConnectionToServer();
- // if (conn)
- // conn->setControlObject(static_cast<GameBase*>(obj));
- //}
- static void renderBoxOutline(const Box3F& box, const ColorI& col)
- {
- if (box != Box3F::Invalid)
- {
- GFXStateBlockDesc desc;
- desc.setCullMode(GFXCullNone);
- desc.setFillModeSolid();
- desc.setZReadWrite(true, false);
- desc.setBlend(true);
- GFX->getDrawUtil()->drawCube(desc, box, ColorI(col, 20));
- desc.setFillModeWireframe();
- desc.setBlend(false);
- GFX->getDrawUtil()->drawCube(desc, box, ColorI(col, 255));
- }
- }
- void NavMeshTestTool::spawnPlayer(const Point3F& position)
- {
- if (mSpawnClass.isEmpty() || mSpawnDatablock.isEmpty())
- {
- Con::warnf("NavMeshTestTool::spawnPlayer - spawn class/datablock not set!");
- return;
- }
- SimObject* spawned = Sim::spawnObject(mSpawnClass, mSpawnDatablock);
- SceneObject* obj = dynamic_cast<SceneObject*>(spawned);
- if (!obj)
- {
- Con::warnf("NavMeshTestTool::spawnPlayer - spawn failed or not a SceneObject");
- if (spawned)
- spawned->deleteObject();
- return;
- }
- obj->setPosition(position);
- SimObject* cleanup = Sim::findObject("MissionCleanup");
- if (cleanup)
- {
- SimGroup* missionCleanup = dynamic_cast<SimGroup*>(cleanup);
- missionCleanup->addObject(obj);
- }
- mPlayer = obj;
- Con::executef(this, "onPlayerSpawned", obj->getIdString());
- #ifdef TORQUE_NAVIGATION_ENABLED
- AIPlayer* asAIPlayer = dynamic_cast<AIPlayer*>(mPlayer.getPointer());
- if (asAIPlayer)
- {
- Con::executef(this, "onPlayerSelected");
- }
- else
- {
- ShapeBase* sbo = dynamic_cast<ShapeBase*>(mPlayer.getPointer());
- if (sbo && sbo->getAIController() && sbo->getAIController()->mControllerData)
- {
- Con::executef(this, "onPlayerSelected");
- }
- else
- {
- Con::executef(this, "onPlayerSelected");
- }
- }
- #else
- Con::executef(this, "onPlayerSelected");
- #endif
- }
- void NavMeshTestTool::drawAgent(duDebugDrawTorque& dd, const F32* pos, F32 r, F32 h, F32 c, const U32 col)
- {
- dd.depthMask(false);
- // Agent dimensions.
- duDebugDrawCylinderWire(&dd, pos[0] - r, pos[1] + 0.02f, pos[2] - r, pos[0] + r, pos[1] + h, pos[2] + r, col, 2.0f);
- duDebugDrawCircle(&dd, pos[0], pos[1] + c, pos[2], r, duRGBA(0, 0, 0, 64), 1.0f);
- U32 colb = duRGBA(0, 0, 0, 196);
- dd.begin(DU_DRAW_LINES);
- dd.vertex(pos[0], pos[1] - c, pos[2], colb);
- dd.vertex(pos[0], pos[1] + c, pos[2], colb);
- dd.vertex(pos[0] - r / 2, pos[1] + 0.02f, pos[2], colb);
- dd.vertex(pos[0] + r / 2, pos[1] + 0.02f, pos[2], colb);
- dd.vertex(pos[0], pos[1] + 0.02f, pos[2] - r / 2, colb);
- dd.vertex(pos[0], pos[1] + 0.02f, pos[2] + r / 2, colb);
- dd.end();
- dd.depthMask(true);
- }
- NavMeshTestTool::NavMeshTestTool()
- {
- mSpawnClass = String::EmptyString;
- mSpawnDatablock = String::EmptyString;
- mPlayer = NULL;
- mCurPlayer = NULL;
- mFollowObject = NULL;
- mCurFollowObject = NULL;
- mPathStart = Point3F::Max;
- mPathEnd = Point3F::Max;
- mTestPath = NULL;
- mLinkTypes = LinkData(AllFlags);
- mFilter.setIncludeFlags(mLinkTypes.getFlags());
- mFilter.setExcludeFlags(0);
- mSelectFollow = false;
- }
- void NavMeshTestTool::onActivated(const Gui3DMouseEvent& evt)
- {
- mSelectFollow = false;
- Con::executef(this, "onActivated");
- }
- void NavMeshTestTool::onDeactivated()
- {
- if (mTestPath != NULL) {
- mTestPath->deleteObject();
- mTestPath = NULL;
- }
- if (mPlayer != NULL)
- {
- mPlayer = NULL;
- Con::executef(this, "onPlayerDeselected");
- }
- mSelectFollow = false;
- Con::executef(this, "onDeactivated");
- }
- void NavMeshTestTool::on3DMouseDown(const Gui3DMouseEvent& evt)
- {
- if (mNavMesh.isNull())
- return;
- Point3F startPnt = evt.pos;
- Point3F endPnt = evt.pos + evt.vec * 1000.0f;
- RayInfo ri;
- bool shift = evt.modifier & SI_LSHIFT;
- bool ctrl = evt.modifier & SI_LCTRL;
- if (ctrl)
- {
- if (gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
- {
- spawnPlayer(ri.point);
- }
- return;
- }
- if (shift)
- {
- mPlayer = NULL;
- Con::executef(this, "onPlayerDeselected");
- return;
- }
- if (gServerContainer.castRay(startPnt, endPnt, PlayerObjectType | VehicleObjectType, &ri))
- {
- if (!ri.object)
- return;
- if (mSelectFollow)
- {
- mFollowObject = ri.object;
- Con::executef(this, "onFollowSelected");
- mSelectFollow = false;
- return;
- }
- else
- {
- mPlayer = ri.object;
- }
- #ifdef TORQUE_NAVIGATION_ENABLED
- AIPlayer* asAIPlayer = dynamic_cast<AIPlayer*>(mPlayer.getPointer());
- if (asAIPlayer)
- {
- Con::executef(this, "onPlayerSelected");
- }
- else
- {
- ShapeBase* sbo = dynamic_cast<ShapeBase*>(mPlayer.getPointer());
- if (sbo && sbo->getAIController() && sbo->getAIController()->mControllerData)
- {
- Con::executef(this, "onPlayerSelected");
- }
- else
- {
- Con::executef(this, "onPlayerSelected");
- }
- }
- #else
- Con::executef(this, "onPlayerSelected");
- #endif
- }
- else if (gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
- {
- if (mPlayer.isNull())
- {
- if (mPathStart != Point3F::Max && mPathEnd != Point3F::Max) // start a new path.
- {
- mPathStart = Point3F::Max;
- mPathEnd = Point3F::Max;
- }
- if (mPathStart != Point3F::Max)
- {
- mPathEnd = ri.point;
- mTestPath = new NavPath();
- mTestPath->mMesh = mNavMesh;
- mTestPath->mFrom = mPathStart;
- mTestPath->mTo = mPathEnd;
- mTestPath->mFromSet = mTestPath->mToSet = true;
- mTestPath->mAlwaysRender = true;
- mTestPath->mLinkTypes = mLinkTypes;
- mTestPath->mFilter = mFilter;
- mTestPath->mXray = true;
- // Paths plan automatically upon being registered.
- if (!mTestPath->registerObject())
- {
- delete mTestPath;
- return;
- }
- }
- else
- {
- mPathStart = ri.point;
- if (mTestPath != NULL) {
- mTestPath->deleteObject();
- mTestPath = NULL;
- }
- }
- }
- else
- {
- AIPlayer* asAIPlayer = dynamic_cast<AIPlayer*>(mPlayer.getPointer());
- if (asAIPlayer) //try direct
- {
- asAIPlayer->setPathDestination(ri.point);
- mPathStart = mPlayer->getPosition();
- mPathEnd = ri.point;
- }
- else
- {
- ShapeBase* sbo = dynamic_cast<ShapeBase*>(mPlayer.getPointer());
- if (sbo->getAIController())
- {
- if (sbo->getAIController()->mControllerData)
- {
- sbo->getAIController()->getNav()->setPathDestination(ri.point, true);
- mPathStart = mPlayer->getPosition();
- mPathEnd = ri.point;
- }
- }
- }
- }
- }
- }
- void NavMeshTestTool::on3DMouseMove(const Gui3DMouseEvent& evt)
- {
- if (mNavMesh.isNull())
- return;
- Point3F startPnt = evt.pos;
- Point3F endPnt = evt.pos + evt.vec * 1000.0f;
- RayInfo ri;
- if (gServerContainer.castRay(startPnt, endPnt, PlayerObjectType | VehicleObjectType, &ri))
- {
- if (mSelectFollow)
- mCurFollowObject = ri.object;
- else
- mCurPlayer = ri.object;
- }
- else
- {
- mCurFollowObject = NULL;
- mCurPlayer = NULL;
- }
- }
- void NavMeshTestTool::onRender3D()
- {
- if (mNavMesh.isNull())
- return;
- static const U32 startCol = duRGBA(128, 25, 0, 192);
- static const U32 endCol = duRGBA(51, 102, 0, 129);
- const F32 agentRadius = mNavMesh->mWalkableRadius;
- const F32 agentHeight = mNavMesh->mWalkableHeight;
- const F32 agentClimb = mNavMesh->mWalkableClimb;
- duDebugDrawTorque dd;
- dd.depthMask(false);
- if (mPathStart != Point3F::Max)
- {
- drawAgent(dd, DTStoRC(mPathStart), agentRadius, agentHeight, agentClimb, startCol);
- }
- if (mPathEnd != Point3F::Max)
- {
- drawAgent(dd, DTStoRC(mPathEnd), agentRadius, agentHeight, agentClimb, endCol);
- }
- dd.depthMask(true);
- mNavMesh->renderSearch(dd);
- dd.immediateRender();
- if (!mCurFollowObject.isNull())
- renderBoxOutline(mCurFollowObject->getWorldBox(), ColorI::LIGHT);
- if (!mCurPlayer.isNull())
- renderBoxOutline(mCurPlayer->getWorldBox(), ColorI::BLUE);
- if (!mPlayer.isNull())
- renderBoxOutline(mPlayer->getWorldBox(), ColorI::GREEN);
- if (!mFollowObject.isNull())
- renderBoxOutline(mFollowObject->getWorldBox(), ColorI::WHITE);
-
- }
- bool NavMeshTestTool::updateGuiInfo()
- {
- SimObject* statusbar;
- Sim::findObject("EditorGuiStatusBar", statusbar);
- GuiTextCtrl* selectionBar;
- Sim::findObject("EWorldEditorStatusBarSelection", selectionBar);
- String text;
- if (mPlayer)
- text = "LMB To Select move Destination. LSHIFT+LMB To Deselect Current Bot.";
- if (mCurPlayer != NULL && mCurPlayer != mPlayer)
- text = "LMB To select Bot.";
- if (mPlayer == NULL)
- {
- text = "LMB To place start/end for test path.";
- }
- if (mSpawnClass != String::EmptyString && mSpawnDatablock != String::EmptyString)
- text += " CTRL+LMB To spawn a new Bot.";
- if (mSelectFollow)
- text = "LMB To select Follow Target.";
- if (statusbar)
- Con::executef(statusbar, "setInfo", text.c_str());
- text = "";
- if (mPlayer)
- text = String::ToString("Bot Selected: %d", mPlayer->getId());
- if (selectionBar)
- selectionBar->setText(text);
- return true;
- }
- S32 NavMeshTestTool::getPlayerId()
- {
- return mPlayer.isNull() ? 0 : mPlayer->getId();
- }
- S32 NavMeshTestTool::getFollowObjectId()
- {
- return mFollowObject.isNull() ? 0 : mFollowObject->getId();
- }
- DefineEngineMethod(NavMeshTestTool, getPlayer, S32, (), ,
- "@brief Return the current player id.")
- {
- return object->getPlayerId();
- }
- DefineEngineMethod(NavMeshTestTool, getFollowObject, S32, (), ,
- "@brief Return the current follow object id.")
- {
- return object->getFollowObjectId();
- }
- DefineEngineMethod(NavMeshTestTool, setSpawnClass, void, (String className), , "")
- {
- object->setSpawnClass(className);
- }
- DefineEngineMethod(NavMeshTestTool, setSpawnDatablock, void, (String dbName), , "")
- {
- object->setSpawnDatablock(dbName);
- }
- DefineEngineMethod(NavMeshTestTool, followSelectMode, void, (), ,
- "@brief Set NavMeshTool to select a follow object.")
- {
- return object->followSelectMode();
- }
|