2
0
Эх сурвалжийг харах

off mesh connection tool

Adds off mesh connection tool
upgrade functionality to allow setting the direction to be bi-directional
added immediate draw to duDebugDrawtorque so we can draw offmesh connections
marauder2k7 1 сар өмнө
parent
commit
2df2cb5c15

+ 22 - 0
Engine/source/navigation/duDebugDrawTorque.cpp

@@ -421,3 +421,25 @@ void duDebugDrawTorque::render(SceneRenderState* state)
    }
 }
 
+void duDebugDrawTorque::immediateRender()
+{
+   for (U32 i = 0; i < mDrawCache.size(); ++i)
+   {
+      const CachedDraw& draw = mDrawCache[i];
+
+      GFX->setPrimitiveBuffer(draw.primitiveBuffer);
+      GFX->setStateBlockByDesc(draw.state);
+      GFX->setupGenericShaders(GFXDevice::GSColor);
+      GFX->setVertexBuffer(draw.buffer);
+
+      GFX->drawIndexedPrimitive(
+         draw.primType,
+         0,                      // start vertex
+         0,                      // min vertex index
+         draw.vertexCount,       // vertex count
+         0,                      // start index
+         draw.primitiveCount     // primitive count
+      );
+   }
+}
+

+ 1 - 0
Engine/source/navigation/duDebugDrawTorque.h

@@ -105,6 +105,7 @@ public:
 
    void clearCache();
    void render(SceneRenderState* state);
+   void immediateRender();
 
 private:
 

+ 0 - 74
Engine/source/navigation/guiNavEditorCtrl.cpp

@@ -323,51 +323,6 @@ void GuiNavEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
    bool shift = keys & SI_LSHIFT;
    bool ctrl = keys & SI_LCTRL;
 
-   if(mMode == mLinkMode && !mMesh.isNull())
-   {
-      if(gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
-      {
-         U32 link = mMesh->getLink(ri.point);
-         if(link != -1)
-         {
-            if(mLink != -1)
-               mMesh->selectLink(mLink, false);
-            mMesh->selectLink(link, true, false);
-            mLink = link;
-            LinkData d = mMesh->getLinkFlags(mLink);
-            Con::executef(this, "onLinkSelected", Con::getIntArg(d.getFlags()));
-         }
-         else
-         {
-            if(mLink != -1)
-            {
-               mMesh->selectLink(mLink, false);
-               mLink = -1;
-               Con::executef(this, "onLinkDeselected");
-            }
-            else
-            {
-               if(mLinkStart != Point3F::Max)
-               {
-                  mMesh->addLink(mLinkStart, ri.point);
-                  if(!shift)
-                     mLinkStart = Point3F::Max;
-               }
-               else
-               {
-                  mLinkStart = ri.point;
-               }
-            }
-         }
-      }
-      else
-      {
-         mMesh->selectLink(mLink, false);
-         mLink = -1;
-         Con::executef(this, "onLinkDeselected");
-      }
-   }
-
    if(mMode == mTestMode)
    {
       // Spawn new character
@@ -471,35 +426,6 @@ void GuiNavEditorCtrl::on3DMouseMove(const Gui3DMouseEvent & event)
 
    RayInfo ri;
 
-   if(mMode == mLinkMode && !mMesh.isNull())
-   {
-      if(gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
-      {
-         U32 link = mMesh->getLink(ri.point);
-         if(link != -1)
-         {
-            if(link != mLink)
-            {
-               if(mCurLink != -1)
-                  mMesh->selectLink(mCurLink, false);
-               mMesh->selectLink(link, true, true);
-            }
-            mCurLink = link;
-         }
-         else
-         {
-            if(mCurLink != mLink)
-               mMesh->selectLink(mCurLink, false);
-            mCurLink = -1;
-         }
-      }
-      else
-      {
-         mMesh->selectLink(mCurLink, false);
-         mCurLink = -1;
-      }
-   }
-
    if(mMode == mTestMode)
    {
       if(gServerContainer.castRay(startPnt, endPnt, PlayerObjectType | VehicleObjectType, &ri))

+ 23 - 6
Engine/source/navigation/navMesh.cpp

@@ -405,7 +405,7 @@ void NavMesh::setScale(const VectorF &scale)
    Parent::setScale(scale);
 }
 
-S32 NavMesh::addLink(const Point3F &from, const Point3F &to, U32 flags)
+S32 NavMesh::addLink(const Point3F &from, const Point3F &to, bool biDir, U32 flags)
 {
    Point3F rcFrom = DTStoRC(from), rcTo = DTStoRC(to);
    mLinkVerts.push_back(rcFrom.x);
@@ -416,7 +416,7 @@ S32 NavMesh::addLink(const Point3F &from, const Point3F &to, U32 flags)
    mLinkVerts.push_back(rcTo.z);
    mLinksUnsynced.push_back(true);
    mLinkRads.push_back(mWalkableRadius);
-   mLinkDirs.push_back(0);
+   mLinkDirs.push_back(biDir ? 1 : 0);
    mLinkAreas.push_back(OffMeshArea);
    if (flags == 0) {
       Point3F dir = to - from;
@@ -435,11 +435,11 @@ S32 NavMesh::addLink(const Point3F &from, const Point3F &to, U32 flags)
    return mLinkIDs.size() - 1;
 }
 
-DefineEngineMethod(NavMesh, addLink, S32, (Point3F from, Point3F to, U32 flags), (0),
+DefineEngineMethod(NavMesh, addLink, S32, (Point3F from, Point3F to, bool biDir, U32 flags), (0),
    "Add a link to this NavMesh between two points.\n\n"
    "")
 {
-   return object->addLink(from, to, flags);
+   return object->addLink(from, to, biDir, flags);
 }
 
 S32 NavMesh::getLink(const Point3F &pos)
@@ -482,6 +482,23 @@ LinkData NavMesh::getLinkFlags(U32 idx)
    return LinkData();
 }
 
+bool NavMesh::getLinkDir(U32 idx)
+{
+   if (idx < mLinkIDs.size())
+   {
+      return mLinkDirs[idx];
+   }
+}
+
+void NavMesh::setLinkDir(U32 idx, bool biDir)
+{
+   if (idx < mLinkIDs.size())
+   {
+      mLinkDirs[idx] = biDir ? 1 : 0;
+      mLinksUnsynced[idx] = true;
+   }
+}
+
 DefineEngineMethod(NavMesh, getLinkFlags, S32, (U32 id),,
    "Get the flags set for a particular off-mesh link.")
 {
@@ -1667,8 +1684,8 @@ void NavMesh::renderLinks(duDebugDraw &dd)
 {
    if(mBuilding)
       return;
-   dd.depthMask(true);
    dd.begin(DU_DRAW_LINES);
+   dd.depthMask(false);
    for(U32 i = 0; i < mLinkIDs.size(); i++)
    {
       U32 col = 0;
@@ -1686,7 +1703,7 @@ void NavMesh::renderLinks(duDebugDraw &dd)
          s[0], s[1], s[2],
          e[0], e[1], e[2],
          0.3f,
-         0.0f, mLinkFlags[i] == DropFlag ? 0.0f : 0.4f,
+         (mLinkDirs[i]&1) ? 0.6f : 0.0f, mLinkFlags[i] == DropFlag ? 0.0f : 0.6f,
          col);
       if(!mDeleteLinks[i])
          duAppendCircle(&dd, e[0], e[1], e[2], mLinkRads[i], col);

+ 5 - 1
Engine/source/navigation/navMesh.h

@@ -151,7 +151,7 @@ public:
    /// @{
 
    /// Add an off-mesh link.
-   S32 addLink(const Point3F &from, const Point3F &to, U32 flags = 0);
+   S32 addLink(const Point3F &from, const Point3F &to, bool biDir, U32 flags = 0);
 
    /// Get the ID of the off-mesh link near the point.
    S32 getLink(const Point3F &pos);
@@ -168,6 +168,10 @@ public:
    /// Get the flags used by a link.
    LinkData getLinkFlags(U32 idx);
 
+   bool getLinkDir(U32 idx);
+
+   void setLinkDir(U32 idx, bool biDir);
+
    /// Set flags used by a link.
    void setLinkFlags(U32 idx, const LinkData &d);
 

+ 189 - 0
Engine/source/navigation/navMeshTools/offMeshConnTool.cpp

@@ -0,0 +1,189 @@
+#include "offMeshConnTool.h"
+#include "navigation/guiNavEditorCtrl.h"
+#include "console/consoleTypes.h"
+#include "gfx/gfxDrawUtil.h"
+#include "scene/sceneManager.h"
+#include "math/mathUtils.h"
+
+IMPLEMENT_CONOBJECT(OffMeshConnectionTool);
+
+void OffMeshConnectionTool::onActivated(const Gui3DMouseEvent& evt)
+{
+   Con::executef(this, "onActivated");
+}
+
+void OffMeshConnectionTool::onDeactivated()
+{
+   Con::executef(this, "onDeactivated");
+}
+
+void OffMeshConnectionTool::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 (gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri))
+   {
+      U32 link = mNavMesh->getLink(ri.point);
+      if (link != -1)
+      {
+         if (mLink != -1)
+            mNavMesh->selectLink(mLink, false);
+         mNavMesh->selectLink(link, true, false);
+         mLink = link;
+
+         if (ctrl)
+         {
+            mNavMesh->selectLink(mLink, false);
+            mNavMesh->deleteLink(mLink);
+            mLink = -1;
+            Con::executef(this, "onLinkDeselected");
+            return;
+         }
+         else
+         {
+            LinkData d = mNavMesh->getLinkFlags(mLink);
+            bool biDir = mNavMesh->getLinkDir(mLink);
+            Con::executef(this, "onLinkSelected", Con::getIntArg(d.getFlags()), Con::getBoolArg(biDir));
+         }
+      }
+      else
+      {
+         if (mLink != -1)
+         {
+            mNavMesh->selectLink(mLink, false);
+            mLink = -1;
+            Con::executef(this, "onLinkDeselected");
+         }
+
+         if (mLinkStart != Point3F::Max)
+         {
+            mLink = mNavMesh->addLink(mLinkStart, ri.point, mBiDir);
+            mNavMesh->selectLink(mLink, true, false);
+            mLinkStart = Point3F::Max;
+            Con::executef(this, "onLinkSelected", Con::getIntArg(mLinkCache.getFlags()), Con::getBoolArg(mBiDir));
+         }
+         else
+         {
+            mLinkStart = ri.point;
+         }
+      }
+   }
+   else
+   {
+      if (mLink != -1)
+      {
+         mNavMesh->selectLink(mLink, false);
+         mLink = -1;
+         Con::executef(this, "onLinkDeselected");
+      }
+   }
+
+}
+
+void OffMeshConnectionTool::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, StaticObjectType, &ri))
+   {
+      U32 link = mNavMesh->getLink(ri.point);
+      if (link != -1)
+      {
+         if (link != mLink)
+         {
+            if (mCurLink != -1)
+               mNavMesh->selectLink(mCurLink, false);
+            mNavMesh->selectLink(link, true, true);
+         }
+         mCurLink = link;
+      }
+      else
+      {
+         if (mCurLink != mLink)
+            mNavMesh->selectLink(mCurLink, false);
+         mCurLink = -1;
+      }
+   }
+   else
+   {
+      mNavMesh->selectLink(mCurLink, false);
+      mCurLink = -1;
+   }
+}
+
+void OffMeshConnectionTool::onRender3D()
+{
+   if (mNavMesh.isNull())
+      return;
+
+   duDebugDrawTorque dd;
+
+   if (mLinkStart != Point3F::Max)
+   {
+      Point3F rcFrom = DTStoRC(mLinkStart);
+      dd.begin(DU_DRAW_LINES);
+      dd.depthMask(false);
+      duAppendCircle(&dd, rcFrom.x, rcFrom.y, rcFrom.z, mNavMesh->mWalkableRadius, duRGBA(0, 255, 0, 255));
+      dd.end();
+   }
+
+   mNavMesh->renderLinks(dd);
+
+   dd.immediateRender();
+}
+
+bool OffMeshConnectionTool::updateGuiInfo()
+{
+   SimObject* statusbar;
+   Sim::findObject("EditorGuiStatusBar", statusbar);
+
+   GuiTextCtrl* selectionBar;
+   Sim::findObject("EWorldEditorStatusBarSelection", selectionBar);
+
+   String text;
+   text = "LMB To Select Link. CTRL+LMB To Delete Link";
+
+   if (statusbar)
+      Con::executef(statusbar, "setInfo", text.c_str());
+
+   if (mLink != -1)
+      text = String::ToString("Selected Link: %d", mLink);
+   else
+      text = "";
+
+   if (selectionBar)
+      selectionBar->setText(text);
+
+   return true;
+}
+
+void OffMeshConnectionTool::setLinkProperties(const LinkData& d, bool biDir)
+{
+   if (!mNavMesh.isNull() && mLink != -1)
+   {
+      mNavMesh->setLinkFlags(mLink, d);
+      mNavMesh->setLinkDir(mLink, biDir);
+   }
+
+   mLinkCache = d;
+   mBiDir = biDir;
+}
+
+DefineEngineMethod(OffMeshConnectionTool, setLinkProperties, void, (U32 flags, bool biDir), ,
+   "@Brief Set properties of the selected link.")
+{
+   object->setLinkProperties(LinkData(flags), biDir);
+}

+ 44 - 0
Engine/source/navigation/navMeshTools/offMeshConnTool.h

@@ -0,0 +1,44 @@
+#ifndef _OFFMESHCONNTOOL_H_
+#define _OFFMESHCONNTOOL_H_
+
+
+#ifndef _NAVMESH_TOOL_H_
+#include "navigation/navMeshTool.h"
+#endif
+
+class OffMeshConnectionTool : public NavMeshTool
+{
+   typedef NavMeshTool Parent;
+   bool mStartPosSet;
+   bool mBiDir;
+   S32 mLink;
+   S32 mCurLink;
+   Point3F mLinkStart;
+   LinkData mLinkCache;
+public:
+
+   DECLARE_CONOBJECT(OffMeshConnectionTool);
+
+   OffMeshConnectionTool() {
+      mStartPosSet = false;
+      mBiDir = false;
+      mLink = -1;
+      mCurLink = -1;
+      mLinkStart = Point3F::Max;
+      mLinkCache = LinkData(0);
+   }
+   virtual ~OffMeshConnectionTool() {}
+
+   void onActivated(const Gui3DMouseEvent& evt) override;
+   void onDeactivated() override;
+
+   void on3DMouseDown(const Gui3DMouseEvent& evt) override;
+   void on3DMouseMove(const Gui3DMouseEvent& evt) override;
+   void onRender3D() override;
+
+   bool updateGuiInfo() override;
+
+   void setLinkProperties(const LinkData& d, bool biDir);
+};
+
+#endif

+ 3 - 6
Engine/source/navigation/navMeshTools/tileTool.cpp

@@ -69,9 +69,6 @@ void TileTool::onRender3D()
    if (mNavMesh.isNull())
       return;
 
-   // Optional: Draw all tile bounds as overlays
-   //mNavMesh->renderTilesOverlay(DebugDraw::get()->getDD());
-
    if(mCurTile != -1)
       renderBoxOutline(mNavMesh->getTileBox(mCurTile), ColorI::BLUE);
 
@@ -87,8 +84,8 @@ void TileTool::buildTile()
 
 bool TileTool::updateGuiInfo()
 {
-   GuiTextCtrl* statusbar;
-   Sim::findObject("EWorldEditorStatusBarInfo", statusbar);
+   SimObject* statusbar;
+   Sim::findObject("EditorGuiStatusBar", statusbar);
 
    GuiTextCtrl* selectionBar;
    Sim::findObject("EWorldEditorStatusBarSelection", selectionBar);
@@ -98,7 +95,7 @@ bool TileTool::updateGuiInfo()
    text = "LMB To select NavMesh Tile";
 
    if (statusbar)
-      statusbar->setText(text);
+      Con::executef(statusbar, "setInfo", text.c_str());
 
    if (mSelTile != -1)
       text = String::ToString("Selected Tile: %d", mSelTile);