Position inside Waypoint Author Message
Houge
Silver Supporter

 Post: #1 Position inside Waypoint If we are using Waypoints to define/limit areas, sometimes we need to check if the position (of a character) is inside of a Waypoint. For complex polygons there is an algorithm HERE, and here's the code for EE to use it: Code: /******************************************************************************/ /******************************************************************************/ // struct saWaypointChecker { public:     void init(C UID &waypointID);     Bool posInside(C Vec2 &pos);     C UID &waypointID(){    return T._waypointID;    }          C Rect rect(){    return T._waypointRect;    }      private:     volatile Bool _init = false;     Game::Waypoint        *_waypoint   = nullptr;     UID _waypointID = UIDZero;     Memc _constant;     Memc _multiple;          Rect _waypointRect; } /******************************************************************************/ /******************************************************************************/ // void saWaypointChecker::init(C UID &waypointID) {     C Flt minMax = 32767.0f;          T._waypoint     = Game::World.findWaypoint(waypointID);     T._waypointID   = (T._waypoint ? waypointID : UIDZero);     T._waypointRect = Rect(minMax, minMax, -minMax, -minMax);          // Perform precalculation     if(T._waypoint)     {         Game::Waypoint &wp = *T._waypoint;                  T._constant.setNum(wp.points.elms());         T._multiple.setNum(wp.points.elms());                  Int j = wp.points.elms() - 1;         for(Int i = 0; i < wp.points.elms(); i++)         {             if(wp.points[j].pos.z == wp.points[i].pos.z)             {                 T._constant[i] = wp.points[i].pos.x;                 T._multiple[i] = 0;             }             else             {                 T._constant[i] = wp.points[i].pos.x - (wp.points[i].pos.z * wp.points[j].pos.x) / (wp.points[j].pos.z - wp.points[i].pos.z) +                                                       (wp.points[i].pos.z * wp.points[i].pos.x) / (wp.points[j].pos.z - wp.points[i].pos.z);                 T._multiple[i] = (wp.points[j].pos.x - wp.points[i].pos.x) / (wp.points[j].pos.z - wp.points[i].pos.z);             }                          j = i;                          // Defining bounding Rect             T._waypointRect.min.x = Min(T._waypointRect.min.x, wp.points[i].pos.x);             T._waypointRect.min.y = Min(T._waypointRect.min.y, wp.points[i].pos.z);                          T._waypointRect.max.x = Max(T._waypointRect.max.x, wp.points[i].pos.x);             T._waypointRect.max.y = Max(T._waypointRect.max.y, wp.points[i].pos.z);         }     }              T._init = (T._waypoint && T._waypointID != UIDZero); } Bool saWaypointChecker::posInside(C Vec2 &pos) {     if(!T._init)     {         return false;     }          // First and fastest check     if(!T._waypointRect.includes(pos))     {         return false;     }          // If position is inside rect, perform more precise check     if(T._waypoint)     {         Game::Waypoint &wp = *T._waypoint;         Bool oddNodes = false, current = wp.points.last().pos.z > pos.y, previous;         for(Int i = 0; i < wp.points.elms(); i++)         {             previous = current;             current = wp.points[i].pos.z > pos.y;             if(current != previous)             {                 oddNodes ^= (pos.y * T._multiple[i] + T._constant[i] < pos.x);             }         }              return oddNodes;     }          return false; } /******************************************************************************/ /******************************************************************************/ the usage is the following (initialization to perform precalculations just once): Code: saWaypointChecker wpHandler; ... init just once ... wpHandler.init(UID(0, 0, 0, 0)); // your Waypoint ID here ... and then check XZ position in any loop ... if(wpHandler.posInside(pos.xz())) {     // do something } P.S. Greg, maybe you can move these precalculations to waypoint class and add "Waypoint.Cuts" function?
07-27-2019 11:26 PM
 « Next Oldest | Next Newest »