//----------------------------------------------------------------------------- // reset all instance state void Pedestrian::reset (void) { float currRadius = radius(); // reset the vehicle // but keep the radius SteeringVehicle::reset (); setRadius( currRadius ); // max speed and max steering force (maneuverability) // setMaxSpeed (2.0); setMaxForce (8.0); setMaxSpeed (4.0f * currRadius); // setMaxForce (16.0f * currRadius); // initially stopped setSpeed (0); // // size of bounding sphere, for obstacle avoidance, etc. // setRadius (0.5); // width = 0.7, add 0.3 margin, take half // set the path for this Pedestrian to follow // path = getTestPath (); if( path != NULL ) { // set initial position // (random point on path + random horizontal offset) const float d = path->length() * frandom01(); const float r = path->radius(); const osVector3 randomOffset = randomVectorOnUnitRadiusXZDisk () * r; setPosition( path->mapPathDistanceToPoint (d) + randomOffset ); } // randomize 2D heading #if OPENSTEER_Z_ISUP randomizeHeadingOnXYPlane (); #else randomizeHeadingOnXZPlane (); #endif // pick a random direction for path following (upstream or downstream) pathDirection = (frandom01() > 0.5) ? -1 : +1; // trail parameters: 3 seconds with 60 points along the trail setTrailParameters (3, 60); // notify proximity database that our position has changed if( _proximityToken != nullptr) { _proximityToken->updateForNewPosition(position()); } #if 0 // notify the update states _steeringForceUpdate.setVehicle( this ); _eulerUpdate.setVehicle( this ); #endif }
OpenSteer::Vec3 OpenSteer::RandomVectorInUnitRadiusSphere (void) { Vec3 v; do { v.set ((frandom01()*2) - 1, (frandom01()*2) - 1, (frandom01()*2) - 1); } while (v.length() >= 1); return v; }
OpenSteer::Vec3 OpenSteer::randomVectorOnUnitRadiusXZDisk (void) { Vec3 v; do { v.set ((frandom01()*2) - 1, 0, (frandom01()*2) - 1); } while (v.length() >= 1); return v; }
float scalarRandomWalk(const float initial,const float walkspeed, const float min,const float max) { const float next = initial + (((frandom01() * 2) - 1) * walkspeed); if (next < min) return min; if (next > max) return max; return next; }
//----------------------------------------------------------------------------- // compute combined steering force: move forward, avoid obstacles // or neighbors if needed, otherwise follow the path and wander osVector3 Pedestrian::determineCombinedSteering (const float elapsedTime) { // note: to enable a better view on a remote vehicle we just // skip computing a steering force for these guys // it is the model to use anyways // AI code has nothing todo on the remote side if( isRemoteObject() ) { return osVector3::zero; } // move forward osVector3 steeringForce = forward(); // probability that a lower priority behavior will be given a // chance to "drive" even if a higher priority behavior might // otherwise be triggered. // const float leakThrough = 0.1f; // no random behaviour for network samples const float leakThrough = -1.0f; // determine if obstacle avoidance is required osVector3 obstacleAvoidance; if (leakThrough < frandom01()) { const float oTime = 6; // minTimeToCollision = 6 seconds // ------------------------------------ xxxcwr11-1-04 fixing steerToAvoid // just for testing // obstacleAvoidance = steerToAvoidObstacles (oTime, gObstacles); // obstacleAvoidance = steerToAvoidObstacle (oTime, gObstacle1); // obstacleAvoidance = steerToAvoidObstacle (oTime, gObstacle3); obstacleAvoidance = steerToAvoidObstacles (oTime, gObstacles); // ------------------------------------ xxxcwr11-1-04 fixing steerToAvoid } // if obstacle avoidance is needed, do it if (obstacleAvoidance != osVector3::zero) { steeringForce += obstacleAvoidance; } else { // otherwise consider avoiding collisions with others osVector3 collisionAvoidance; const float caLeadTime = 3; // find all neighbors within maxRadius using proximity database // (radius is largest distance between vehicles traveling head-on // where a collision is possible within caLeadTime seconds.) const float maxRadius = caLeadTime * maxSpeed() * 2; if( _proximityToken != nullptr) { _neighbors.clear(); _proximityToken->findNeighbors (position(), maxRadius, _neighbors); } // allways avoid neighbors // if (leakThrough < frandom01()) { collisionAvoidance = steerToAvoidNeighbors (caLeadTime, _neighbors) * 10; } // if collision avoidance is needed, do it if (collisionAvoidance != osVector3::zero) { steeringForce += collisionAvoidance; } else { #if 0 NetPedestrianPlugin* netPedestrianPlugin = dynamic_cast<NetPedestrianPlugin*>(getParentEntity()); // add in wander component (according to user switch) if (netPedestrianPlugin->m_bWanderSwitch) steeringForce += steerForWander (elapsedTime); #endif // do (interactively) selected type of path following const float pfLeadTime = 3; const bool useDirectPathFollowing(true); const osVector3 pathFollow = (useDirectPathFollowing ? //(netPedestrianPlugin->m_bUseDirectedPathFollowing ? steerToFollowPath (pathDirection, pfLeadTime, *path) : steerToStayOnPath (pfLeadTime, *path)); // add in to steeringForce steeringForce += pathFollow * 0.5; } } #if OPENSTEER_Z_ISUP // return steering constrained to global XY "ground" plane return steeringForce.setZtoZero(); #else // return steering constrained to global XZ "ground" plane return steeringForce.setYtoZero(); #endif }