wns::Position Street::getNextPosition(MapUser* user, simTimeType dt) const { // in case we just entered this street, we have to determine the // user's heading. If we come from the crossing at endPoint[0], we // call it "Forward", otherwise we'll call it "Reverse" if (user->currentObject!=this->id) { MapObject::ID from = user->currentObject; user->heading = ( ( from==connections.at(0)) ? int(Headings::Forward()) : int(Headings::Reverse()) ); user->currentObject=this->id; } // how much of this road remains? double remaining = (1-user->percent)*streetVector.abs(); // is user velocity on this street bounded by vMax? double currentVelocity = ( user->velocity < vMax ? user->velocity : vMax ); if (currentVelocity*dt < remaining) { // we stay on this road and only advance by a certain // percentage (given through velocity and timestep) user->percent += (currentVelocity*dt)/streetVector.abs(); MESSAGE_BEGIN(NORMAL, log, m, "MapUser advancing on street "); m << id << ", completed " << int(100.0*user->percent) << "%, velocity " << currentVelocity << "(desired: " << user->velocity << ") m/s"; MESSAGE_END(); return this->getPosition(user); } else { // we reach the end of this street, how long does that take? double untilCrossing = remaining/currentVelocity; // determine the object we'll reach next MapObject* nextObject = map->getObject(( user->heading==Headings::Forward() ? connections.at(1) : connections.at(0) )); // and delegate the decision about the new final position return nextObject->getNextPosition(user,dt-untilCrossing); } }