Torque3D Documentation / _generateds / guiNavEditorCtrl.cpp

guiNavEditorCtrl.cpp

Engine/source/navigation/guiNavEditorCtrl.cpp

More...

Public Functions

ConsoleDocClass(GuiNavEditorCtrl , "@brief GUI tool that makes up the Navigation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editor\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
DefineEngineMethod(GuiNavEditorCtrl , buildTile , void , () , "@brief Build the currently selected tile." )
DefineEngineMethod(GuiNavEditorCtrl , deleteLink , void , () , "@brief Delete the currently selected link." )
DefineEngineMethod(GuiNavEditorCtrl , deselect , void , () , "@brief Deselect whatever is currently selected in the editor." )
DefineEngineMethod(GuiNavEditorCtrl , getMesh , S32 , () , "@brief Select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classnavmesh/">NavMesh</a> object." )
DefineEngineMethod(GuiNavEditorCtrl , getMode , const char * , () , "" )
DefineEngineMethod(GuiNavEditorCtrl , getPlayer , S32 , () , "@brief Select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classnavmesh/">NavMesh</a> object." )
DefineEngineMethod(GuiNavEditorCtrl , selectMesh , void , (S32 id) , "@brief Select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classnavmesh/">NavMesh</a> object." )
DefineEngineMethod(GuiNavEditorCtrl , setLinkFlags , void , (U32 flags) , "@Brief Set jump and drop properties of the selected link." )
DefineEngineMethod(GuiNavEditorCtrl , setMode , void , (String mode) , "setMode(<a href="/coding/class/classstring/">String</a> <a href="/coding/file/zipobject_8cpp/#zipobject_8cpp_1ac6c3dfb4c3a68f849f32cbfb21da4e77">mode</a>)" )
DefineEngineMethod(GuiNavEditorCtrl , spawnPlayer , void , () , "@brief Spawn an <a href="/coding/class/classaiplayer/">AIPlayer</a> at the centre of the screen." )

Detailed Description

Public Functions

ConsoleDocClass(GuiNavEditorCtrl , "@brief GUI tool that makes up the Navigation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editor\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )

DefineEngineMethod(GuiNavEditorCtrl , buildTile , void , () , "@brief Build the currently selected tile." )

DefineEngineMethod(GuiNavEditorCtrl , deleteLink , void , () , "@brief Delete the currently selected link." )

DefineEngineMethod(GuiNavEditorCtrl , deselect , void , () , "@brief Deselect whatever is currently selected in the editor." )

DefineEngineMethod(GuiNavEditorCtrl , getMesh , S32 , () , "@brief Select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classnavmesh/">NavMesh</a> object." )

DefineEngineMethod(GuiNavEditorCtrl , getMode , const char * , () , "" )

DefineEngineMethod(GuiNavEditorCtrl , getPlayer , S32 , () , "@brief Select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classnavmesh/">NavMesh</a> object." )

DefineEngineMethod(GuiNavEditorCtrl , selectMesh , void , (S32 id) , "@brief Select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/class/classnavmesh/">NavMesh</a> object." )

DefineEngineMethod(GuiNavEditorCtrl , setLinkFlags , void , (U32 flags) , "@Brief Set jump and drop properties of the selected link." )

DefineEngineMethod(GuiNavEditorCtrl , setMode , void , (String mode) , "setMode(<a href="/coding/class/classstring/">String</a> <a href="/coding/file/zipobject_8cpp/#zipobject_8cpp_1ac6c3dfb4c3a68f849f32cbfb21da4e77">mode</a>)" )

DefineEngineMethod(GuiNavEditorCtrl , spawnPlayer , void , () , "@brief Spawn an <a href="/coding/class/classaiplayer/">AIPlayer</a> at the centre of the screen." )

IMPLEMENT_CONOBJECT(GuiNavEditorCtrl )

renderBoxOutline(const Box3F & box, const ColorI & col)

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2014 Daniel Buckmaster
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "guiNavEditorCtrl.h"
 26#include "duDebugDrawTorque.h"
 27#include "console/engineAPI.h"
 28
 29#include "console/consoleTypes.h"
 30#include "math/util/frustum.h"
 31#include "math/mathUtils.h"
 32#include "gfx/primBuilder.h"
 33#include "gfx/gfxDrawUtil.h"
 34#include "scene/sceneRenderState.h"
 35#include "scene/sceneManager.h"
 36#include "gui/core/guiCanvas.h"
 37#include "gui/buttons/guiButtonCtrl.h"
 38#include "gui/worldEditor/undoActions.h"
 39#include "T3D/gameBase/gameConnection.h"
 40
 41IMPLEMENT_CONOBJECT(GuiNavEditorCtrl);
 42
 43ConsoleDocClass(GuiNavEditorCtrl,
 44                "@brief GUI tool that makes up the Navigation Editor\n\n"
 45                "Editor use only.\n\n"
 46                "@internal"
 47                );
 48
 49// Each of the mode names directly correlates with the Nav Editor's tool palette.
 50const String GuiNavEditorCtrl::mSelectMode = "SelectMode";
 51const String GuiNavEditorCtrl::mLinkMode = "LinkMode";
 52const String GuiNavEditorCtrl::mCoverMode = "CoverMode";
 53const String GuiNavEditorCtrl::mTileMode = "TileMode";
 54const String GuiNavEditorCtrl::mTestMode = "TestMode";
 55
 56GuiNavEditorCtrl::GuiNavEditorCtrl()
 57{
 58   mMode = mSelectMode;
 59   mIsDirty = false;
 60   mStartDragMousePoint = InvalidMousePoint;
 61   mMesh = NULL;
 62   mCurTile = mTile = -1;
 63   mPlayer = mCurPlayer = NULL;
 64   mSpawnClass = mSpawnDatablock = "";
 65   mLinkStart = Point3F::Max;
 66   mLink = mCurLink = -1;
 67}
 68
 69GuiNavEditorCtrl::~GuiNavEditorCtrl()
 70{
 71}
 72
 73void GuiNavEditorUndoAction::undo()
 74{
 75}
 76
 77bool GuiNavEditorCtrl::onAdd()
 78{
 79   if(!Parent::onAdd())
 80      return false;
 81
 82   GFXStateBlockDesc desc;
 83   desc.fillMode = GFXFillSolid;
 84   desc.setBlend(false);
 85   desc.setZReadWrite(false, false);
 86   desc.setCullMode(GFXCullNone);
 87
 88   mZDisableSB = GFX->createStateBlock(desc);
 89
 90   desc.setZReadWrite(true, true);
 91   mZEnableSB = GFX->createStateBlock(desc);
 92
 93   SceneManager::getPreRenderSignal().notify(this, &GuiNavEditorCtrl::_prepRenderImage);
 94
 95   return true;
 96}
 97
 98void GuiNavEditorCtrl::initPersistFields()
 99{
100   addField("isDirty", TypeBool, Offset(mIsDirty, GuiNavEditorCtrl));
101
102   addField("spawnClass", TypeRealString, Offset(mSpawnClass, GuiNavEditorCtrl),
103      "Class of object to spawn in test mode.");
104   addField("spawnDatablock", TypeRealString, Offset(mSpawnDatablock, GuiNavEditorCtrl),
105      "Datablock to give new objects in test mode.");
106
107   Parent::initPersistFields();
108}
109
110void GuiNavEditorCtrl::onSleep()
111{
112   Parent::onSleep();
113
114   //mMode = mSelectMode;
115}
116
117void GuiNavEditorCtrl::selectMesh(NavMesh *mesh)
118{
119   mesh->setSelected(true);
120   mMesh = mesh;
121}
122
123DefineEngineMethod(GuiNavEditorCtrl, selectMesh, void, (S32 id),,
124   "@brief Select a NavMesh object.")
125{
126   NavMesh *obj;
127   if(Sim::findObject(id, obj))
128      object->selectMesh(obj);
129}
130
131S32 GuiNavEditorCtrl::getMeshId()
132{
133   return mMesh.isNull() ? 0 : mMesh->getId();
134}
135
136DefineEngineMethod(GuiNavEditorCtrl, getMesh, S32, (),,
137   "@brief Select a NavMesh object.")
138{
139   return object->getMeshId();
140}
141
142S32 GuiNavEditorCtrl::getPlayerId()
143{
144   return mPlayer.isNull() ? 0 : mPlayer->getId();
145}
146
147DefineEngineMethod(GuiNavEditorCtrl, getPlayer, S32, (),,
148   "@brief Select a NavMesh object.")
149{
150   return object->getPlayerId();
151}
152
153void GuiNavEditorCtrl::deselect()
154{
155   if(!mMesh.isNull())
156      mMesh->setSelected(false);
157   mMesh = NULL;
158   mPlayer = mCurPlayer = NULL;
159   mCurTile = mTile = -1;
160   mLinkStart = Point3F::Max;
161   mLink = mCurLink = -1;
162}
163
164DefineEngineMethod(GuiNavEditorCtrl, deselect, void, (),,
165   "@brief Deselect whatever is currently selected in the editor.")
166{
167   object->deselect();
168}
169
170void GuiNavEditorCtrl::deleteLink()
171{
172   if(!mMesh.isNull() && mLink != -1)
173   {
174      mMesh->selectLink(mLink, false);
175      mMesh->deleteLink(mLink);
176      mLink = -1;
177      Con::executef(this, "onLinkDeselected");
178   }
179}
180
181DefineEngineMethod(GuiNavEditorCtrl, deleteLink, void, (),,
182   "@brief Delete the currently selected link.")
183{
184   object->deleteLink();
185}
186
187void GuiNavEditorCtrl::setLinkFlags(const LinkData &d)
188{
189   if(mMode == mLinkMode && !mMesh.isNull() && mLink != -1)
190   {
191      mMesh->setLinkFlags(mLink, d);
192   }
193}
194
195DefineEngineMethod(GuiNavEditorCtrl, setLinkFlags, void, (U32 flags),,
196   "@Brief Set jump and drop properties of the selected link.")
197{
198   object->setLinkFlags(LinkData(flags));
199}
200
201void GuiNavEditorCtrl::buildTile()
202{
203   if(!mMesh.isNull() && mTile != -1)
204      mMesh->buildTile(mTile);
205}
206
207DefineEngineMethod(GuiNavEditorCtrl, buildTile, void, (),,
208   "@brief Build the currently selected tile.")
209{
210   object->buildTile();
211}
212
213void GuiNavEditorCtrl::spawnPlayer(const Point3F &pos)
214{
215   SceneObject *obj = (SceneObject*)Sim::spawnObject(mSpawnClass, mSpawnDatablock);
216   if(obj)
217   {
218      MatrixF mat(true);
219      mat.setPosition(pos);
220      obj->setTransform(mat);
221      SimObject* cleanup = Sim::findObject("MissionCleanup");
222      if(cleanup)
223      {
224         SimGroup* missionCleanup = dynamic_cast<SimGroup*>(cleanup);
225         missionCleanup->addObject(obj);
226      }
227      mPlayer = static_cast<AIPlayer*>(obj);
228      Con::executef(this, "onPlayerSelected", Con::getIntArg(mPlayer->mLinkTypes.getFlags()));
229   }
230}
231
232DefineEngineMethod(GuiNavEditorCtrl, spawnPlayer, void, (),,
233                   "@brief Spawn an AIPlayer at the centre of the screen.")
234{
235   Point3F c;
236   if(object->get3DCentre(c))
237      object->spawnPlayer(c);
238}
239
240void GuiNavEditorCtrl::get3DCursor(GuiCursor *&cursor,
241                                   bool &visible,
242                                   const Gui3DMouseEvent &event_)
243{
244   //cursor = mAddNodeCursor;
245   //visible = false;
246
247   cursor = NULL;
248   visible = false;
249
250   GuiCanvas *root = getRoot();
251   if(!root)
252      return;
253
254   S32 currCursor = PlatformCursorController::curArrow;
255
256   if(root->mCursorChanged == currCursor)
257      return;
258
259   PlatformWindow *window = root->getPlatformWindow();
260   PlatformCursorController *controller = window->getCursorController();
261
262   // We've already changed the cursor,
263   // so set it back before we change it again.
264   if(root->mCursorChanged != -1)
265      controller->popCursor();
266
267   // Now change the cursor shape
268   controller->pushCursor(currCursor);
269   root->mCursorChanged = currCursor;
270}
271
272bool GuiNavEditorCtrl::get3DCentre(Point3F &pos)
273{
274   Point3F screen, start, end;
275
276   screen.set(getExtent().x / 2, getExtent().y / 2, 0);
277   unproject(screen, &start);
278
279   screen.z = 1.0f;
280   unproject(screen, &end);
281
282   RayInfo ri;
283   if(gServerContainer.castRay(start, end, StaticObjectType, &ri))
284   {
285      pos = ri.point;
286      return true;
287   }
288   return false;
289}
290
291void GuiNavEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
292{
293   mGizmo->on3DMouseDown(event);
294
295   if(!isFirstResponder())
296      setFirstResponder();
297
298   mouseLock();
299
300   // Construct a LineSegment from the camera position to 1000 meters away in
301   // the direction clicked.
302   // If that segment hits the terrain, truncate the ray to only be that length.
303
304   Point3F startPnt = event.pos;
305   Point3F endPnt = event.pos + event.vec * 1000.0f;
306
307   RayInfo ri;
308
309   U8 keys = Input::getModifierKeys();
310   bool shift = keys & SI_LSHIFT;
311   bool ctrl = keys & SI_LCTRL;
312
313   if(mMode == mLinkMode && !mMesh.isNull())
314   {
315      if(gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
316      {
317         U32 link = mMesh->getLink(ri.point);
318         if(link != -1)
319         {
320            if(mLink != -1)
321               mMesh->selectLink(mLink, false);
322            mMesh->selectLink(link, true, false);
323            mLink = link;
324            LinkData d = mMesh->getLinkFlags(mLink);
325            Con::executef(this, "onLinkSelected", Con::getIntArg(d.getFlags()));
326         }
327         else
328         {
329            if(mLink != -1)
330            {
331               mMesh->selectLink(mLink, false);
332               mLink = -1;
333               Con::executef(this, "onLinkDeselected");
334            }
335            else
336            {
337               if(mLinkStart != Point3F::Max)
338               {
339                  mMesh->addLink(mLinkStart, ri.point);
340                  if(!shift)
341                     mLinkStart = Point3F::Max;
342               }
343               else
344               {
345                  mLinkStart = ri.point;
346               }
347            }
348         }
349      }
350      else
351      {
352         mMesh->selectLink(mLink, false);
353         mLink = -1;
354         Con::executef(this, "onLinkDeselected");
355      }
356   }
357
358   if(mMode == mTileMode && !mMesh.isNull())
359   {
360      if(gServerContainer.castRay(startPnt, endPnt, StaticShapeObjectType, &ri))
361      {
362         mTile = mMesh->getTile(ri.point);
363         dd.clear();
364         mMesh->renderTileData(dd, mTile);
365      }
366   }
367
368   if(mMode == mTestMode)
369   {
370      // Spawn new character
371      if(ctrl)
372      {
373         if(gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
374            spawnPlayer(ri.point);
375      }
376      // Deselect character
377      else if(shift)
378      {
379         mPlayer = NULL;
380         Con::executef(this, "onPlayerDeselected");
381      }
382      // Select/move character
383      else
384      {
385         if(gServerContainer.castRay(startPnt, endPnt, PlayerObjectType, &ri))
386         {
387            if(dynamic_cast<AIPlayer*>(ri.object))
388            {
389               mPlayer = dynamic_cast<AIPlayer*>(ri.object);
390               Con::executef(this, "onPlayerSelected", Con::getIntArg(mPlayer->mLinkTypes.getFlags()));
391            }
392         }
393         else if(!mPlayer.isNull() && gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
394            mPlayer->setPathDestination(ri.point);
395      }
396   }
397}
398
399void GuiNavEditorCtrl::on3DMouseUp(const Gui3DMouseEvent & event)
400{
401   // Keep the Gizmo up to date.
402   mGizmo->on3DMouseUp(event);
403
404   mouseUnlock();
405}
406
407void GuiNavEditorCtrl::on3DMouseMove(const Gui3DMouseEvent & event)
408{
409   //if(mSelRiver != NULL && mSelNode != -1)
410      //mGizmo->on3DMouseMove(event);
411
412   Point3F startPnt = event.pos;
413   Point3F endPnt = event.pos + event.vec * 1000.0f;
414
415   RayInfo ri;
416
417   if(mMode == mLinkMode && !mMesh.isNull())
418   {
419      if(gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
420      {
421         U32 link = mMesh->getLink(ri.point);
422         if(link != -1)
423         {
424            if(link != mLink)
425            {
426               if(mCurLink != -1)
427                  mMesh->selectLink(mCurLink, false);
428               mMesh->selectLink(link, true, true);
429            }
430            mCurLink = link;
431         }
432         else
433         {
434            if(mCurLink != mLink)
435               mMesh->selectLink(mCurLink, false);
436            mCurLink = -1;
437         }
438      }
439      else
440      {
441         mMesh->selectLink(mCurLink, false);
442         mCurLink = -1;
443      }
444   }
445
446   // Select a tile from our current NavMesh.
447   if(mMode == mTileMode && !mMesh.isNull())
448   {
449      if(gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
450         mCurTile = mMesh->getTile(ri.point);
451      else
452         mCurTile = -1;
453   }
454
455   if(mMode == mTestMode)
456   {
457      if(gServerContainer.castRay(startPnt, endPnt, PlayerObjectType, &ri))
458         mCurPlayer = dynamic_cast<AIPlayer*>(ri.object);
459      else
460         mCurPlayer = NULL;
461   }
462}
463
464void GuiNavEditorCtrl::on3DMouseDragged(const Gui3DMouseEvent & event)
465{
466   mGizmo->on3DMouseDragged(event);
467   if(mGizmo->isDirty())
468   {
469      Point3F scale = mGizmo->getScale();
470      const MatrixF &mat = mGizmo->getTransform();
471      VectorF normal;
472      mat.getColumn(2, &normal);
473
474      //mSelRiver->setNode(pos, scale.x, scale.z, normal, mSelNode);
475      mIsDirty = true;
476   }
477}
478
479void GuiNavEditorCtrl::on3DMouseEnter(const Gui3DMouseEvent & event)
480{
481}
482
483void GuiNavEditorCtrl::on3DMouseLeave(const Gui3DMouseEvent & event)
484{
485}
486
487void GuiNavEditorCtrl::updateGuiInfo()
488{
489}
490
491void GuiNavEditorCtrl::onRender(Point2I offset, const RectI &updateRect)
492{
493   PROFILE_SCOPE(GuiNavEditorCtrl_OnRender);
494
495   Parent::onRender(offset, updateRect);
496   return;
497}
498
499static void renderBoxOutline(const Box3F &box, const ColorI &col)
500{
501   if(box != Box3F::Invalid)
502   {
503      GFXStateBlockDesc desc;
504      desc.setCullMode(GFXCullNone);
505      desc.setFillModeSolid();
506      desc.setZReadWrite(true, false);
507      desc.setBlend(true);
508      GFX->getDrawUtil()->drawCube(desc, box, ColorI(col, 20));
509      desc.setFillModeWireframe();
510      desc.setBlend(false);
511      GFX->getDrawUtil()->drawCube(desc, box, ColorI(col, 255));
512   }
513}
514
515void GuiNavEditorCtrl::renderScene(const RectI & updateRect)
516{
517   GFX->setStateBlock(mZDisableSB);
518
519   // get the projected size...
520   GameConnection* connection = GameConnection::getConnectionToServer();
521   if(!connection)
522      return;
523
524   // Grab the camera's transform
525   MatrixF mat;
526   connection->getControlCameraTransform(0, &mat);
527
528   // Get the camera position
529   Point3F camPos;
530   mat.getColumn(3,&camPos);
531
532   if(mMode == mLinkMode)
533   {
534      if(mLinkStart != Point3F::Max)
535      {
536         GFXStateBlockDesc desc;
537         desc.setBlend(false);
538         desc.setZReadWrite(true ,true);
539         MatrixF linkMat(true);
540       linkMat.setPosition(mLinkStart);
541         Point3F scale(0.8f, 0.8f, 0.8f);
542         GFX->getDrawUtil()->drawTransform(desc, linkMat, &scale);
543      }
544   }
545
546   if(mMode == mTileMode && !mMesh.isNull())
547   {
548      renderBoxOutline(mMesh->getTileBox(mCurTile), ColorI::BLUE);
549      renderBoxOutline(mMesh->getTileBox(mTile), ColorI::GREEN);
550      if(Con::getBoolVariable("$Nav::Editor::renderVoxels", false)) dd.renderGroup(0);
551      if(Con::getBoolVariable("$Nav::Editor::renderInput", false))
552      {
553         dd.depthMask(false);
554         dd.renderGroup(1);
555         dd.depthMask(true);
556      }
557   }
558
559   if(mMode == mTestMode)
560   {
561      if(!mCurPlayer.isNull())
562         renderBoxOutline(mCurPlayer->getWorldBox(), ColorI::BLUE);
563      if(!mPlayer.isNull())
564         renderBoxOutline(mPlayer->getWorldBox(), ColorI::GREEN);
565   }
566
567   duDebugDrawTorque d;
568   if(!mMesh.isNull())
569      mMesh->renderLinks(d);
570   d.render();
571
572   // Now draw all the 2d stuff!
573   GFX->setClipRect(updateRect);
574}
575
576bool GuiNavEditorCtrl::getStaticPos(const Gui3DMouseEvent & event, Point3F &tpos)
577{
578   // Find clicked point on the terrain
579
580   Point3F startPnt = event.pos;
581   Point3F endPnt = event.pos + event.vec * 1000.0f;
582
583   RayInfo ri;
584   bool hit;
585
586   hit = gServerContainer.castRay(startPnt, endPnt, StaticShapeObjectType, &ri);
587   tpos = ri.point;
588
589   return hit;
590}
591
592void GuiNavEditorCtrl::setMode(String mode, bool sourceShortcut = false)
593{
594   mMode = mode;
595   Con::executef(this, "onModeSet", mode);
596
597   if(sourceShortcut)
598      Con::executef(this, "paletteSync", mode);
599}
600
601void GuiNavEditorCtrl::submitUndo(const UTF8 *name)
602{
603   // Grab the mission editor undo manager.
604   UndoManager *undoMan = NULL;
605   if(!Sim::findObject("EUndoManager", undoMan))
606   {
607      Con::errorf("GuiNavEditorCtrl::submitUndo() - EUndoManager not found!");
608      return;
609   }
610
611   // Setup the action.
612   GuiNavEditorUndoAction *action = new GuiNavEditorUndoAction(name);
613
614   action->mNavEditor = this;
615
616   undoMan->addAction(action);
617}
618
619void GuiNavEditorCtrl::_prepRenderImage(SceneManager* sceneGraph, const SceneRenderState* state)
620{
621   /*if(isAwake() && River::smEditorOpen && mSelRiver)
622   {
623      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
624      ri->type = RenderPassManager::RIT_Editor;
625      ri->renderDelegate.bind(this, &GuiNavEditorCtrl::_renderSelectedRiver);
626      ri->defaultKey = 100;
627      state->getRenderPass()->addInst(ri);
628   }*/
629}
630
631DefineEngineMethod(GuiNavEditorCtrl, getMode, const char*, (), , "")
632{
633   return object->getMode();
634}
635
636DefineEngineMethod(GuiNavEditorCtrl, setMode, void, (String mode),, "setMode(String mode)")
637{
638   object->setMode(mode);
639}
640