48 #ifndef __ORCA_TYPE_AGENT_CONTEXT_H__
49 #define __ORCA_TYPE_AGENT_CONTEXT_H__
61 template <
class Agent >
77 virtual std::string
contextName()
const {
return "UNDEFINED ORCA TYPE"; }
103 virtual void draw3DGL(
bool select=
false );
175 void visORCA(
const Agent * agt )
const;
180 template<
class Agent >
186 template<
class Agent >
188 if ( this->_selected && _visNbrID ) {
189 const Agent * agt =
dynamic_cast< const Agent *
>( this->_selected->getAgent() );
190 if ( _visNbrID > 0 ) {
191 size_t NBR_COUNT = agt->_nearAgents.size();
192 if ( _visNbrID > NBR_COUNT ) {
193 _visNbrID = NBR_COUNT;
201 template<
class Agent >
205 SDLMod mods = e.key.keysym.mod;
206 bool hasCtrl = ( mods & KMOD_CTRL ) > 0;
207 bool hasAlt = ( mods & KMOD_ALT ) > 0;
208 bool hasShift = ( mods & KMOD_SHIFT ) > 0;
209 bool noMods = !(hasCtrl || hasAlt || hasShift );
210 if ( e.type == SDL_KEYDOWN ) {
212 if ( e.key.keysym.sym == SDLK_c ) {
213 _showOrcaLines = !_showOrcaLines;
214 result.
set(
true,
true );
215 }
else if ( e.key.keysym.sym == SDLK_z ) {
216 _visualizeORCA = !_visualizeORCA;
218 result.
set(
true,
true );
219 }
else if ( e.key.keysym.sym == SDLK_UP ) {
220 if ( _visualizeORCA && this->_selected ) {
221 const Agent * agt =
dynamic_cast< const Agent *
>( this->_selected->getAgent() );
223 if ( _visNbrID >= agt->_nearAgents.size() ) _visNbrID = 0;
224 result.
set(
true,
true );
226 }
else if ( e.key.keysym.sym == SDLK_DOWN ) {
227 if ( _visualizeORCA && this->_selected ) {
228 const Agent * agt =
dynamic_cast< const Agent *
>( this->_selected->getAgent() );
229 if ( _visNbrID == 0 ) _visNbrID = agt->_nearAgents.size() - 1;
231 result.
set(
true,
true );
242 template<
class Agent >
245 if ( !select && this->_selected ) {
246 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT );
247 glDepthMask( GL_FALSE );
248 glDisable( GL_DEPTH_TEST );
249 const Agent * agt =
dynamic_cast< const Agent *
>( this->_selected->getAgent() );
250 drawORCALines( agt );
258 template<
class Agent >
260 const Agent * agent =
dynamic_cast< const Agent *
>( agt );
262 std::stringstream ss;
263 ss << std::setiosflags(std::ios::fixed) << std::setprecision( 2 );
265 ss <<
"\n_________________________";
266 ss <<
"\nDraw OR(C)A lines";
267 if ( _showOrcaLines ) {
268 const size_t LINE_COUNT = agent->_orcaLines.size();
269 const size_t AGT_COUNT = agent->_nearAgents.size();
270 const size_t OBST_COUNT = LINE_COUNT - AGT_COUNT;
271 ss <<
"\n " << OBST_COUNT <<
" obstacle lines";
272 ss <<
"\n " << AGT_COUNT <<
" agent lines";
274 ss <<
"\nVisuali(z)e ORCA";
275 if ( _visualizeORCA ) {
276 if ( agent->_nearAgents.size() == 0 ) {
277 ss <<
"\n No nearby agents.";
279 size_t id = (agent->_nearAgents[_visNbrID].agent)->_id;
280 ss <<
"\n Showing agent: " <<
id <<
" (up/down arrow to change)";
288 template<
class Agent >
290 const float DIST = 35.f;
297 glColor4f( r, g, b, 0.1f );
298 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
299 glEnable( GL_BLEND );
302 glVertex3f( p0.x(), Y, p0.y() );
303 glVertex3f( p1.
x(), Y, p1.
y() );
304 glVertex3f( p2.
x(), Y, p2.
y() );
305 glVertex3f( p3.
x(), Y, p3.
y() );
307 glDisable( GL_BLEND );
310 glVertex3f( p0.x(), Y, p0.y() );
311 glVertex3f( p3.
x(), Y, p3.
y() );
317 template<
class Agent >
319 if ( _showOrcaLines && this->_selected ) {
320 Agent * agt =
const_cast< Agent *
>( agent );
321 agt->computeORCALines();
322 const size_t LINE_COUNT = agt->_orcaLines.size();
323 const size_t FIRST_AGENT = LINE_COUNT - agt->_nearAgents.size();
324 const float DIST = 35.f;
326 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
327 glEnable( GL_BLEND );
329 glColor4f( 0.75f, 0.75f, 0.75f, 0.1f );
331 for (
size_t i = 0; i < LINE_COUNT; ++i ) {
333 if ( i == FIRST_AGENT ) {
334 glColor4f( 1.f, 0.f, 0.f, 0.1f );
346 glVertex3f( p0.
x(), this->Y, p0.
y() );
347 glVertex3f( p1.
x(), this->Y, p1.
y() );
348 glVertex3f( p2.
x(), this->Y, p2.
y() );
349 glVertex3f( p3.
x(), this->Y, p3.
y() );
352 glDisable( GL_BLEND );
354 glColor4f( 0.75f, 0.75f, 0.75f, 0.1f );
356 for (
size_t i = 0; i < LINE_COUNT; ++i ) {
357 if ( i == FIRST_AGENT ) {
358 glColor4f( 1.f, 0.f, 0.f, 0.1f );
365 glVertex3f( p0.
x(), this->Y, p0.
y() );
366 glVertex3f( p1.
x(), this->Y, p1.
y() );
370 glColor4f( 1.f, 0.f, 0.f, 1.f );
371 for (
size_t i = FIRST_AGENT; i < LINE_COUNT; ++i ) {
372 std::stringstream ss;
377 this->writeTextRadially( ss.str(), p, d, true );
378 this->writeAlignedText( ss.str(), nbr->
_pos, Menge::SceneGraph::TextWriter::CENTERED, true );
385 template<
class Agent >
387 if ( _visualizeORCA && this->_selected ) {
388 if ( agt->_nearAgents.size() > 0 ) {
389 Vector2 velPref = agt->_velPref.getPreferredVel();
391 glColor3f( 0.1f, 1.f, 0.1f );
392 Agent * agent =
const_cast< Agent *
>( agt );
393 agent->computeORCALines();
394 const Agent * nbr =
static_cast< const Agent *
>( agent->_nearAgents[ _visNbrID ].agent );
395 float R = agent->_radius + nbr->_radius;
396 Vector2 disp = nbr->_pos - agent->_pos;
397 float dist = abs( disp );
402 float cosPhi = R / dist;
403 float sinPhi = sqrtf( 1 - cosPhi * cosPhi );
404 float cx = cosPhi * -dir.
x();
405 float sx = sinPhi * -dir.
x();
406 float cy = cosPhi * -dir.
y();
407 float sy = sinPhi * -dir.
y();
410 Vector2 l0 = disp + R * Vector2( cx + sy, -sx + cy );
413 float l = dist / ( r0 * dir );
420 const float TAU = agent->_timeHorizon;
421 float minVel = dist / TAU;
422 float Rmin = R / TAU;
423 Vector2 center( agent->_pos + dir * minVel );
426 glTranslatef( center.
x(), this->Y, center.
y() );
430 Vector2 r1 = center + Rmin * Vector2( cx - sy, sx + cy );
431 Vector2 l1 = center + Rmin * Vector2( cx + sy, -sx + cy );
434 glVertex3f( r0.
x(), this->Y, r0.
y() );
435 glVertex3f( r1.
x(), this->Y, r1.
y() );
436 glVertex3f( l0.
x(), this->Y, l0.
y() );
437 glVertex3f( l1.
x(), this->Y, l1.
y() );
441 float row = agent->_priority - nbr->_priority;
442 Vector2 agtVel = agent->_vel;
443 Vector2 nbrVel = nbr->_vel;
444 Vector2 nbrVelPref = nbr->_velPref.getPreferredVel();
447 row = row > 1.f ? 1.f : row;
448 if ( dir * velPref > dir * agent->_vel ) {
449 agtVel = velPref * row + ( 1.f - row ) * agent->_vel;
451 }
else if ( row < 0.f ) {
453 row = row < -1.f ? 1.f : -row;
454 if ( dir * nbrVelPref < dir * nbr->_vel ) {
455 nbrVel = nbrVelPref * row + ( 1.f - row ) * nbr->_vel;
460 glColor3f( 0.1f, 0.1f, 0.8f );
462 glVertex3f( nbr->_pos.x(), this->Y, nbr->_pos.y() );
463 glVertex3f( nbr->_pos.x() + nbrVel.
x(), this->Y, nbr->_pos.y() + nbrVel.
y() );
465 this->writeTextRadially(
"v_j", nbr->_pos + nbrVel, nbrVel,
true);
468 glColor3f( 0.1f, 0.8f, 0.1f );
470 glVertex3f( agent->_pos.x(), this->Y, agent->_pos.y() );
471 glVertex3f( agent->_pos.x() + agtVel.
x(), this->Y, agent->_pos.y() + agtVel.
y() );
473 this->writeTextRadially(
"v_i", agent->_pos + agtVel, agtVel,
true );
476 glColor3f( 0.1f, 0.8f, 0.8f );
478 Vector2 rel = agtVel - nbrVel;
479 glVertex3f( agent->_pos.x(), this->Y, agent->_pos.y() );
480 glVertex3f( agent->_pos.x() + rel.
x(), this->Y, agent->_pos.y() + rel.
y() );
482 this->writeTextRadially(
"v_ij", agent->_pos + rel, rel,
true );
487 size_t NBR_COUNT = agent->_nearAgents.size();
488 size_t FIRST_NBR = agent->_orcaLines.size() - NBR_COUNT;
489 drawORCALine( agent, agent->_orcaLines[ FIRST_NBR + _visNbrID ],
true );
492 drawOptVelocity( agent );
499 template<
class Agent >
502 drawHalfPlane( line, agent->_pos, 1.f, 0.f, 0.f, this->Y );
504 drawHalfPlane( line, agent->_pos, 0.75f, 0.75f, 0.75f, this->Y );
510 template<
class Agent >
513 agent->computeNewVelocity();
515 glPushAttrib( GL_POINT_BIT );
517 glColor3f( 0.2f, 0.2f, 1.f );
518 glBegin( GL_POINTS );
519 glVertex3f( agent->_pos.x() + agent->_velNew.x(), this->Y, agent->_pos.y() + agent->_velNew.y() );
521 this->writeTextRadially(
" v_new ", agent->_pos + agent->_velNew, agent->_velNew,
true );
525 #endif // __ORCA_TYPE_AGENT_CONTEXT_H__
static void drawCircle(float radius, float r, float g, float b, float a, GLenum style=GL_FILL)
Static function for drawing circles in the context with out instances.
Definition: shapes.cpp:179
void drawORCALine(const Agent *agent, const Menge::Math::Line &line, bool isAgent) const
Draws the given ORCA line for the given agent.
Definition: ORCATypeAgentContext.h:500
SDL_Event SDL_Event
Forward declaration of the SDL event type.
Definition: Context.h:53
void drawHalfPlane(const Menge::Math::Line &line, const Vector2 &pos, float r, float g, float b, float Y) const
Helper function for drawing a halfplane.
Definition: ORCATypeAgentContext.h:289
The core namespace. All elements of Menge are contained in this namespace.
Definition: AgentGenerator.cpp:43
ORCATypeAgentContext(Menge::VisAgent **agents, unsigned int agtCount)
Construtor.
Definition: ORCATypeAgentContext.h:181
Simple, cylindrical visualization for agents.
Context class for displaying various aspects of the ORCA-type agent computation.
Definition: ORCATypeAgentContext.h:62
Vector2 _pos
The current 2D position of the agent.
Definition: BaseAgent.h:208
virtual void draw3DGL(bool select=false)
Draw context elements into the 3D world.
Definition: ORCATypeAgentContext.h:243
virtual std::string agentText(const Agents::BaseAgent *agent) const
Creates a formatted string to be printed in the context for a particular agent.
Definition: BaseAgentContext.cpp:333
virtual void draw3DGL(bool select=false)
Draw context elements into the 3D world.
Definition: BaseAgentContext.cpp:202
std::vector< NearAgent > _nearAgents
The nearby agents to which the agent should respond.
Definition: BaseAgent.h:313
bool _showOrcaLines
Determines if the ORCA lines are drawn.
Definition: ORCATypeAgentContext.h:150
size_t _id
A globally unique identifier for each agent.
Definition: BaseAgent.h:287
Vector2 _direction
The direction of the directed line.
Definition: Line.h:91
virtual std::string contextName() const
Returns the name of the context for display.
Definition: ORCATypeAgentContext.h:77
virtual Menge::SceneGraph::ContextResult handleKeyboard(SDL_Event &e)
Give the context the opportunity to respond to a keyboard event.
Definition: ORCATypeAgentContext.h:202
A library of simple renderable OpenGL shapes.
bool isHandled() const
Reports if the result considers the event handled.
Definition: Context.h:105
Context class for displaying various characteristics of the Agents::BaseAgent class.
Definition: BaseAgentContext.h:73
void set(bool handled, bool redraw)
Sets the handled and needs redraw state simultaneously.
Definition: Context.h:127
Defines the result of the context's consideration of user input.
Definition: Context.h:74
The basic agent visualization class: a selectable cylinder.
Definition: VisAgent.h:66
void visORCA(const Agent *agt) const
The function that draws the visualization of the orca construction.
Definition: ORCATypeAgentContext.h:386
Defines the basic agent properties and functionality that all simulation agents share.
Definition: BaseAgent.h:123
MENGE_API const float RAD_TO_DEG
Scale factor for converting radians to degrees.
Definition: geomQuery.cpp:51
virtual void update()
Allow the context to update any time-dependent state it might have to the given global time...
Definition: ORCATypeAgentContext.h:187
Defines a directed line.
Definition: Line.h:57
void drawOptVelocity(Agent *agent) const
Draw the optimized velocity for the current set of orca lines.
Definition: ORCATypeAgentContext.h:511
Type x() const
Get the x-value.
Definition: Vector2.h:106
A basic context for interacting with and displaying basic agent parameters.
void drawORCALines(const Agent *agt) const
Function for drawing the ORCA lines acting on agt.
Definition: ORCATypeAgentContext.h:318
static const float Y
The drawing depth for the 3D elements.
Definition: BaseAgentContext.h:179
Type y() const
Get the y-value.
Definition: Vector2.h:113
bool _visualizeORCA
Determines if the ORCA line construction is visualized.
Definition: ORCATypeAgentContext.h:162
virtual std::string agentText(const Menge::Agents::BaseAgent *agent) const
Creates a formatted string to be printed in the context for a particular agent.
Definition: ORCATypeAgentContext.h:259
size_t _visNbrID
The agent to visualize.
Definition: ORCATypeAgentContext.h:167
Vector2 _point
A point on the directed line.
Definition: Line.h:86