Vec2f BaseParticleSpring::normalize() { if( p1->fixed && p2->fixed ) return Vec2f( 0, 0 ); BaseParticle *particleBase = p1; BaseParticle *particleNorm = p2; if( p2->fixed ) { particleBase = p2; particleNorm = p1; } Vec2f direction = particleNorm->position - particleBase->position; float d = direction.length(); if( d != distance ) { direction.normalize(); Vec2f posNorm = particleNorm->position; particleNorm->position = particleBase->position + direction * distance; direction = particleNorm->position - particleBase->position; d = direction.length(); return Vec2f( posNorm - particleNorm->position ); } return Vec2f( 0, 0 ); }
//---------------------------------------------------------------------- // Calculates the orientations of the contours // Author: afischle //---------------------------------------------------------------------- void TextVectorGlyph::computeContourOrientations() const { #if !defined(OSG_OGL_ES2) || defined(OSG_CHECK_COREONLY) // get the simplest outline available as it should suffice for the // orientation check const PolygonOutline &outline = getLines(0); UInt32 start = 0, end; vector<UInt32>::const_iterator it; for (it = outline.contours.begin(); it != outline.contours.end(); ++it) { end = *it; // return value does not matter if (end - start < 3) _contourOrientations.push_back(CCW); OSG_ASSERT(start + 2 < outline.coords.size()); Vec2f en1 = computeEdgeNormal(outline.coords[start], outline.coords[start + 1], false); Vec2f en2 = computeEdgeNormal(outline.coords[start + 1], outline.coords[start + 2], false); // compute the mean of the edge normals at vertex 0. Vec2f testNormal = en1 + en2; testNormal.normalize(); // calculate the displacement of vertex 0 along its mean edge normal Vec2f testPoint = outline.coords[start + 1] + testNormal * (1000.f * TypeTraits<Real32>::getDefaultEps()); if (isInteriorPoint(testPoint, outline, GLU_TESS_WINDING_NONZERO)) _contourOrientations.push_back(CW); else _contourOrientations.push_back(CCW); start = end; } #endif }
void NOC_1_6_vector_normalizeApp::draw() { gl::clear( Color( 1, 1, 1 ) ); // A vector that points to the mouse location Vec2f mouse = Vec2f( getMousePos().x, getMousePos().y ); // A vector that points to the center of the window Vec2f center = Vec2f( getWindowWidth() / 2, getWindowHeight() / 2 ); // Subtract center from mouse which results in a vector that points from center to mouse mouse -= center; // Normalize the vector mouse.normalize(); // Multiply its length by 50 mouse *= 150; // Need push and pop matrix since the matrix doesn't reset on draw like in processing glPushMatrix(); gl::translate( getWindowWidth() / 2, getWindowHeight() / 2 ); glLineWidth( 2.0 ); gl::color( 0, 0, 0 ); gl::drawLine( Vec2f( 0,0 ), Vec2f( mouse.x, mouse.y ) ); glPopMatrix(); }
void ParticleEmitter::repulseParticles() { for( list<Particle>::iterator p1 = mParticles.begin(); p1 != mParticles.end(); ++p1 ){ list<Particle>::iterator p2 = p1; for( ++p2; p2 != mParticles.end(); ++p2 ) { Vec2f dir = p1->mLoc - p2->mLoc; float thresh = ( p1->mRadius + p2->mRadius ) * 5.0f; if( dir.x > -thresh && dir.x < thresh && dir.y > -thresh && dir.y < thresh ){ float distSqrd = dir.lengthSquared() * dir.length(); if( distSqrd > 0.0f ){ float F = 1.0f/distSqrd; dir.normalize(); // acceleration = force / mass p1->mAcc += ( F * dir ) / p1->mMass; p2->mAcc -= ( F * dir ) / p2->mMass; // TMP p1->mAcc *= 0.005; p2->mAcc *= 0.005; } } } } }
Vec2f VertexOrientation2DF0D::operator()(Interface0DIterator& iter) { Vec2f A,C; Vec2f B(iter->getProjectedX(), iter->getProjectedY()); if(iter.isBegin()) A = Vec2f(iter->getProjectedX(), iter->getProjectedY()); else { Interface0DIterator previous = iter; --previous ; A = Vec2f(previous->getProjectedX(), previous->getProjectedY()); } Interface0DIterator next = iter; ++next ; if(next.isEnd()) C = Vec2f(iter->getProjectedX(), iter->getProjectedY()); else C = Vec2f(next->getProjectedX(), next->getProjectedY()); Vec2f AB(B-A); if(AB.norm() != 0) AB.normalize(); Vec2f BC(C-B); if(BC.norm() != 0) BC.normalize(); Vec2f res (AB + BC); if(res.norm() != 0) res.normalize(); return res; }
//---------------------------------------------------------------------- // Returns a normal outline containining normal contours. These normal contours // contain GlyphVertexNormal structs providing the normals of the adjacent edges, // the mean normal and the angle enclosed by the edge normals. // // Author: afischle //---------------------------------------------------------------------- const TextVectorGlyph::Normals &TextVectorGlyph::getNormals(UInt32 level) const { // Try to find the normal outline of the specified detail level in the // cache map NormalMap::const_iterator it = _normalMap.find(level); if (it != _normalMap.end()) // We already have that level - return the corresponding outline return it->second; // We did not find that level, so we have to create it Normals &normals = _normalMap.insert(NormalMap::value_type(level, Normals())).first->second; // get the polygon outline of this glyph at the desired detail level // The contours of this outline are not closed! const PolygonOutline &outline = getLines(level); // compute the contour orientations when they are not available if (_contourOrientations.empty()) computeContourOrientations(); UInt32 start = 0, end, index = 0; vector<UInt32>::const_iterator iIt; vector<Orientation>::const_iterator oriIt = _contourOrientations.begin(); for (iIt = outline.contours.begin(); iIt != outline.contours.end(); ++iIt, ++oriIt) { end = *iIt; OSG_ASSERT(end - 1 < outline.coords.size()); OSG_ASSERT(start < outline.coords.size()); OSG_ASSERT(oriIt != _contourOrientations.end()); Vec2f prevEdgeNormal = computeEdgeNormal(outline.coords[end - 1], outline.coords[start], (*oriIt) == CW); while (index < end) { UInt32 nextIndex = index + 1; if (nextIndex >= end) nextIndex = start; OSG_ASSERT(index < outline.coords.size()); OSG_ASSERT(nextIndex < outline.coords.size()); Vec2f nextEdgeNormal = computeEdgeNormal(outline.coords[index], outline.coords[nextIndex], (*oriIt) == CW); Vec2f meanEdgeNormal = prevEdgeNormal + nextEdgeNormal; meanEdgeNormal.normalize(); Real32 edgeAngle = osgACos(osgAbs(prevEdgeNormal.dot(nextEdgeNormal))); normals.push_back(VertexNormal(nextEdgeNormal, meanEdgeNormal, edgeAngle)); //the outgoing edge of this vertex is the incoming of the next vertex prevEdgeNormal = nextEdgeNormal; ++index; } start = end; } return normals; }
void update(float dt) { Vec2f middle = Vec2f(getWindowWidth()/2.0f, getWindowHeight()/2.0f); vel = pos - middle; vel.normalize(); vel.rotate(M_PI/1.97f); vel *= 25.0f; pos += vel * dt; }
Planet(Vec2f _p, float _r) { pos = _p; radius = _r; Vec2f middle = Vec2f(getWindowWidth()/2.0f, getWindowHeight()/2.0f); vel = pos - middle; vel.normalize(); vel.rotate(M_PI/1.97f); vel *= 25.0f; }
void addParkingSpaces(Vec2f from, Vec2f direction, size_t count, bool entryFromLeft = true, float width = 30.f, float length = 75.f) { direction.normalize(); Vec2f entryVec = direction; entryVec.rotate(static_cast<float>(entryFromLeft ? M_PI / 2.f : -M_PI / 2.f)); for (size_t i = 0; i < count; ++i) { addSingleParkingSpace(ParkingSpace(width, length, from, entryVec)); from += direction * width; } }
vector<Vec2WithId*> Vec2Helper::orderCW(vector<Vec2WithId*> points, Vec2f center) { for (unsigned int i=0; i<points.size(); i++) { Vec2f p = points[i]->vec-center; p.normalize(); points[i]->vec = p; } std::sort(points.begin(), points.end(), compareAngle); return points; }
void Arm::update( const Vec2f &mouse ) { for ( auto& component : FullArm ) { component->update(); } if ( mouse.x != 0 && mouse.y != 0 ) { // FullArm[3]->getBody()->SetTransform( Conversions::toPhysics( mouse ), 0.0f ); Vec2f diff = mouse - Conversions::toScreen( FullArm[3]->getBody()->GetPosition() ); diff.normalize(); diff *= 20000.0f; FullArm[3]->getBody()->ApplyForce( Conversions::toPhysics( diff ), FullArm[3]->getBody()->GetPosition() ); } }
// A method that calculates a steering force towards a target // STEER = DESIRED MINUS VELOCITY Vec2f Vehicle::seek( Vec2f target ) { Vec2f desired = target - mLocation; // A vector pointing from the location to the target // Normalize desired and scale to maximum speed desired.normalize(); desired *= mMaxSpeed; // Steering = Desired minus velocity Vec2f steer = desired - mVelocity; steer.limit( mMaxForce ); // Limit to maximum steering force return steer; }
// Calculate drag force Vec2f Liquid::drag( const Mover &m ) { // Magnitude is coefficient * speed squared float speed = m.mVelocity.length(); float dragMagnitude = mC * speed * speed; // Direction is inverse of velocity Vec2f dragForce = Vec2f( m.mVelocity ); dragForce *= -1; // Scale according to magnitude // dragForce.setMag(dragMagnitude); dragForce.normalize(); dragForce *= dragMagnitude; return dragForce; }
int Plaaster::shoot(Vec3f pos) { int count=0; for (int i=0;i< triangles.size();i++) { if (triangles[i]->center.x > pos.x -70 && triangles[i]->center.x < pos.x +70 ) { if (triangles[i]->center.z > pos.y -70 && triangles[i]->center.z < pos.y +70 ) { Vec2f a = Vec2f(triangles[i]->center.x ,triangles[i]->center.z); float dist =a.distance(Vec2f(pos.x,pos.y )); Vec2f dir =a-Vec2f(pos.x,pos.y ); dir.normalize(); //if (dist < 70) { count ++; PlaasterParticle *p = triangles[i]->particle; p->reset(100-dist ,dir); particles.push_back(p); triangles.erase(triangles.begin()+i ); // cinder::app::console()<< "delete"; } i--; } } } //cinder::app::console()<< count <<endl; ; updateMainMesh(); return count; }
void MyAppli::onExec () { if (getClock("RequestTime").getElapsedTime().asSeconds() >= timeBtwnTwoReq.asSeconds()) { std::string request = "GETCARPOS"; sf::Packet packet; packet<<request; Network::sendUdpPacket(packet); getClock("RequestTime").restart(); received = false; } std::string response; if (Network::getResponse("STOPCARMOVE", response)) { std::vector<std::string> infos = split(response, "*"); int id = conversionStringInt(infos[0]); Vec3f newPos (conversionStringFloat(infos[1]), conversionStringFloat(infos[2]), 0); Caracter* caracter = static_cast<Caracter*>(World::getEntity(id)); Vec3f actualPos = Vec3f(caracter->getCenter().x, caracter->getCenter().y, 0); if (hero->getId() == id) { for (unsigned int i = 0; i < getRenderComponentManager().getNbComponents(); i++) { View view = getRenderComponentManager().getRenderComponent(i)->getView(); Vec3f d = newPos - view.getPosition(); view.move(d.x, d.y, d.y); getRenderComponentManager().getRenderComponent(i)->setView(view); } Vec3f d = newPos - getView().getPosition(); getView().move(d.x, d.y, d.y); } Vec3f d = newPos - actualPos; World::moveEntity(caracter, d.x, d.y, d.y); caracter->setMoving(false); World::update(); } if (Network::getResponse("MONSTERONMOUSE", response)) { std::cout<<"monster on mouse!"<<std::endl; } if (Network::getResponse("NEWPATH", response)) { std::vector<std::string> infos = split(response, "*"); std::vector<Vec2f> path; int size = conversionStringInt(infos[0]); int id = conversionStringInt(infos[1]); Caracter* caracter = static_cast<Caracter*>(World::getEntity(id)); Vec2f actualPos (conversionStringFloat(infos[2]), conversionStringFloat(infos[3])); Vec2f newPos = Computer::getPosOnPathFromTime(actualPos, caracter->getPath(),ping,caracter->getSpeed()); for (int i = 0; i < size; i++) { path.push_back(Vec2f(conversionStringFloat(infos[i*2+4]), conversionStringFloat(infos[i*2+5]))); } Vec2f d = newPos - actualPos; Vec2f dir = d.normalize(); if (dir != caracter->getDir()) caracter->setDir(dir); World::moveEntity(caracter, d.x, d.y, d.y); caracter->setPath(path); caracter->setMoving(true); caracter->interpolation.first = caracter->getCenter(); caracter->interpolation.second = Computer::getPosOnPathFromTime(caracter->interpolation.first, caracter->getPath(),ping + timeBtwnTwoReq.asMicroseconds(),caracter->getSpeed()); caracter->getClkTransfertTime().restart(); } if (Network::getResponse("NEWPOS", response)) { std::vector<std::string> infos = split(response, "*"); if (infos.size() == 4) { int id = conversionStringInt(infos[0]); ping = conversionStringLong(infos[1]); Caracter* caracter = static_cast<Caracter*>(World::getEntity(id)); Vec3f actualPos = Vec3f(caracter->getCenter().x, caracter->getCenter().y, 0); Vec3f newPos (conversionStringFloat(infos[2]), conversionStringFloat(infos[3]), 0); Vec3f d = newPos - actualPos; if (id == hero->getId()) { for (unsigned int i = 0; i < getRenderComponentManager().getNbComponents(); i++) { View view = getRenderComponentManager().getRenderComponent(i)->getView(); view.move(d.x, d.y, d.y); getRenderComponentManager().getRenderComponent(i)->setView(view); } getView().move (d.x, d.y, d.y); } World::moveEntity(caracter, d.x, d.y, d.y); World::update(); caracter->interpolation.first = Vec3f(caracter->getCenter().x, caracter->getCenter().y, 0); if (caracter->isMoving()) { if (caracter->isMovingFromKeyboard()) { caracter->interpolation.second = caracter->interpolation.first + Vec3f(caracter->getDir().x,caracter->getDir().y,0) * caracter->getSpeed() * (ping + timeBtwnTwoReq.asMicroseconds()); } else { caracter->interpolation.second = Computer::getPosOnPathFromTime(caracter->interpolation.first, caracter->getPath(),ping + timeBtwnTwoReq.asMicroseconds(),caracter->getSpeed()); } } else { caracter->interpolation.second = caracter->interpolation.first; } caracter->getClkTransfertTime().restart(); } } else { std::vector<Entity*> caracters = World::getEntities("E_MONSTER+E_HERO"); for (unsigned int i = 0; i < caracters.size(); i++) { Caracter* caracter = static_cast<Caracter*>(caracters[i]); if (caracter->isMoving()) { if (caracter->isMovingFromKeyboard()) { Vec3f actualPos = Vec3f(caracter->getCenter().x, caracter->getCenter().y, 0); sf::Int64 elapsedTime = caracter->getClkTransfertTime().getElapsedTime().asMicroseconds(); Vec3f newPos = caracter->interpolation.first + (caracter->interpolation.second - caracter->interpolation.first) * ((float) elapsedTime / (float) (ping + timeBtwnTwoReq.asMicroseconds())); Ray ray(actualPos, newPos); if (World::collide(caracter, ray)) { newPos = actualPos; } for (unsigned int i = 0; i < getRenderComponentManager().getNbComponents(); i++) { View view = getRenderComponentManager().getRenderComponent(i)->getView(); Vec3f d = newPos - view.getPosition(); view.move(d.x, d.y, d.y); getRenderComponentManager().getRenderComponent(i)->setView(view); } Vec3f d = newPos - actualPos; World::moveEntity(caracter, d.x, d.y, d.y); getView().move(d.x, d.y, d.y); World::update(); } else { Vec3f actualPos (caracter->getCenter().x, caracter->getCenter().y, 0); sf::Int64 elapsedTime = caracter->getClkTransfertTime().getElapsedTime().asMicroseconds(); Vec3f newPos = caracter->interpolation.first + (caracter->interpolation.second - caracter->interpolation.first) * ((float) elapsedTime / (float) (ping + timeBtwnTwoReq.asMicroseconds())); Vec3f d = newPos - actualPos; if (newPos.computeDist(caracter->getPath()[caracter->getPath().size() - 1]) <= PATH_ERROR_MARGIN) { caracter->setMoving(false); newPos = caracter->getPath()[caracter->getPath().size() - 1]; } if (caracter->getId() == hero->getId()) { for (unsigned int i = 0; i < getRenderComponentManager().getNbComponents(); i++) { View view = getRenderComponentManager().getRenderComponent(i)->getView(); view.move(d.x, d.y, d.y); getRenderComponentManager().getRenderComponent(i)->setView(view); } getView().move(d.x, d.y, d.y); } Vec2f dir = d.normalize(); if (dir != caracter->getDir()) caracter->setDir(dir); World::moveEntity(caracter, d.x, d.y, d.y); World::update(); } } } } if (hero->isInFightingMode()) { if (hero->getFocusedCaracter() != nullptr) { int distToEnnemi = hero->getCenter().computeDist(hero->getFocusedCaracter()->getCenter()); if (distToEnnemi <= hero->getRange()) { if (hero->isMoving()) hero->setMoving(false); hero->setAttacking(true); hero->attackFocusedCaracter(); } else { hero->setAttacking(false); } } } }
void TrafficSimulation::update() { networkDataMutex.lock(); // Update the position of the player to be send to the server if (player != NULL) { // Move the vehicle Value vehicle; vehicle["id"] = 0; Value pos; Vec3f worldPosition = player->getFrom(); pos[0u] = worldPosition[0]; pos[1] = worldPosition[1]; pos[2] = worldPosition[2]; vehicle["pos"] = pos; // Pack as the requested array entry dataToSend["moveVehicles"][0] = vehicle; } if (!receivedData.isNull()) { //cout << "Received data\n"; // New data received per network. Update the positions of vehicles and the states of traffic lights // A set which contains the IDs of the currently existing vehicles. // If data for one of those is received, the entry in the set will be removed. // All vehicles that are in the set after the loop finished are no longer in the // area and can be deleted. set<uint> vehicleIDs; for (auto iter : vehicles) vehicleIDs.insert(iter.first); if (!receivedData["vehicles"].isNull() && receivedData["vehicles"].isArray()) { // Update the vehicles //cout << "Received vehicles " << receivedData["vehicles"].size(); // A set for possible collisions // Add them all to the set and resolve them later on to avoid doubled checks set< pair<unsigned int, unsigned int> > collisions; // Sleeps for 10ms each tick, but the send deltas are for one second // Use only a part of them to avoid moving too fast static const float partDelta = 10 / 1000; for (auto vehicleIter : receivedData["vehicles"]) { // Check if the values have valid types if (!vehicleIter["id"].isConvertibleTo(uintValue) || !vehicleIter["pos"].isConvertibleTo(arrayValue) || !vehicleIter["pos"][0].isConvertibleTo(realValue) || !vehicleIter["pos"][1].isConvertibleTo(realValue) || !vehicleIter["pos"][2].isConvertibleTo(realValue) || !vehicleIter["dPos"].isConvertibleTo(arrayValue) || !vehicleIter["dPos"][0].isConvertibleTo(realValue) || !vehicleIter["dPos"][1].isConvertibleTo(realValue) || !vehicleIter["dPos"][2].isConvertibleTo(realValue) || !vehicleIter["angle"].isConvertibleTo(arrayValue) || !vehicleIter["angle"][0].isConvertibleTo(realValue) || !vehicleIter["angle"][1].isConvertibleTo(realValue) || !vehicleIter["angle"][2].isConvertibleTo(realValue) || !vehicleIter["dAngle"].isConvertibleTo(arrayValue) || !vehicleIter["dAngle"][0].isConvertibleTo(realValue) || !vehicleIter["dAngle"][1].isConvertibleTo(realValue) || !vehicleIter["dAngle"][2].isConvertibleTo(realValue)) { cout << "TrafficSimulation: Warning: Received invalid vehicle data.\n"; continue; } uint ID = vehicleIter["id"].asUInt(); if (vehicles.count(ID) == 0) { // The vehicle is new, create it if (!vehicleIter["vehicle"].isConvertibleTo(uintValue) || !vehicleIter["driver"].isConvertibleTo(uintValue)) { cout << "TrafficSimulation: Warning: Received invalid vehicle data.\n"; continue; } uint vID = vehicleIter["vehicle"].asUInt(); if (meshes.count(vID) == 0) { // If it is bigger than 500 it is our user-controlled vehicle if (vID < 500) cout << "TrafficSimulation: Warning: Received unknown vehicle type " << vID << ".\n"; continue; } Vehicle v; v.id = ID; v.vehicleTypeId = vID; v.driverTypeId = vehicleIter["driver"].asUInt(); if (meshes.count(v.vehicleTypeId) == 0) v.vehicleTypeId = 404; v.geometry = (VRGeometry*)meshes[v.vehicleTypeId]->duplicate(true); v.geometry->addAttachment("dynamicaly_generated", 0); // Add it to the map vehicles.insert(make_pair(v.id, v)); } else vehicleIDs.erase(ID); // Already (and still) exists, remove its ID from the vehicle-id-set // Now the vehicle exists, update its position and state Vehicle& v = vehicles[ID]; v.pos = Vec3f(vehicleIter["pos"][0].asFloat(), vehicleIter["pos"][1].asFloat(), vehicleIter["pos"][2].asFloat()); v.deltaPos = Vec3f(vehicleIter["dPos"][0].asFloat(), vehicleIter["dPos"][1].asFloat(), vehicleIter["dPos"][2].asFloat()); v.deltaPos *= partDelta; v.orientation = Vec3f(vehicleIter["angle"][0].asFloat(), vehicleIter["angle"][1].asFloat(), vehicleIter["angle"][2].asFloat()); v.deltaOrientation = Vec3f(vehicleIter["dAngle"][0].asFloat(), vehicleIter["dAngle"][1].asFloat(), vehicleIter["dAngle"][2].asFloat()); v.deltaOrientation *= partDelta; if (!vehicleIter["state"].isNull() && vehicleIter["state"].isArray()) { v.state = Vehicle::NONE; for (auto state : vehicleIter["state"]) { if (!state.isConvertibleTo(stringValue)) continue; if(state.asString() == "rightIndicator") { v.state |= Vehicle::RIGHT_INDICATOR; } else if(state.asString() == "leftIndicator") { v.state |= Vehicle::LEFT_INDICATOR; } else if(state.asString() == "accelerating") { v.state |= Vehicle::ACCELERATING; } else if(state.asString() == "braking") { v.state |= Vehicle::BRAKING; } else if(state.asString() == "waiting") { v.state |= Vehicle::WAITING; } else if(state.asString() == "blocked") { v.state |= Vehicle::BLOCKED; } else if(state.asString() == "collision") { v.state |= Vehicle::COLLIDED; } } } if (!vehicleIter["colliding"].isNull() && vehicleIter["colliding"].isArray()) { for (auto collisionIter : vehicleIter["colliding"]) { if (!collisionIter.isConvertibleTo(uintValue)) continue; uint other = collisionIter.asUInt(); if (other < v.id) collisions.insert(make_pair(other, v.id)); else collisions.insert(make_pair(v.id, other)); } } } // End vehicle iteration // Okay, all vehicles are updated now // Resolve collisions if (collisionHandler != NULL) { for (auto c : collisions) { if (collisionHandler(vehicles[c.first], vehicles[c.second])) { dataToSend["collision"].append(c.first); dataToSend["collision"].append(c.second); } } } } // End vehicle updates // Remove vehicles which are no longer on the map for (auto v : vehicleIDs) { vehicles[v].geometry->destroy(); vehicles.erase(v); } // Get traffic light updates if (!receivedData["trafficlights"].isNull() && receivedData["trafficlights"].isArray()) { // The light bulbs in the array will be moved around arbitrary whichever light posts are given // If there are not enough bulbs in the array, more are added // If there are too many bulbs, they are deleted size_t bulbIndex = 0; static const double postHeight = 2; static const double bulbSize = 1; // Note: If you change this value from 2, change the value further down in new VRGeometry(), too. for (auto lightpost : receivedData["trafficlights"]) { if (!lightpost.isObject()) continue; if (!lightpost["at"].isConvertibleTo(uintValue) || !lightpost["to"].isConvertibleTo(uintValue) || lightpost["state"].isNull() || !lightpost["state"].isArray()) { cout << "TrafficSimulation: Warning: Received invalid light post data.\n"; continue; } // Calculate the vector of the street // Get the node positions Vec2f atPos, toPos; string atId = lexical_cast<string>(lightpost["at"].asUInt()); string toId = lexical_cast<string>(lightpost["to"].asUInt()); bool foundAt = false, foundTo = false; for (auto mapIter : loadedMaps) { for (auto nodeIter : mapIter->osmNodes) { if (!foundAt && nodeIter->id == atId) { atPos = mapCoordinator->realToWorld(Vec2f(nodeIter->lat, nodeIter->lon)); foundAt = true; } if (!foundTo && nodeIter->id == toId) { toPos = mapCoordinator->realToWorld(Vec2f(nodeIter->lat, nodeIter->lon)); foundTo = true; } if (foundAt && foundTo) break; } if (foundAt && foundTo) break; } Vec2f streetOffset = toPos - atPos; const float prevLength = streetOffset.length(); streetOffset.normalize(); streetOffset *= min(prevLength / 2, Config::get()->STREET_WIDTH); Vec2f normal(-streetOffset[1], streetOffset[0]); normal.normalize(); normal *= Config::get()->STREET_WIDTH; streetOffset += atPos; // streetOffset now contains a position in the center of a street a bit away from the crossing // normal is a vector that is orthogonal to the street // Now iterate over the lanes and hang up the lights double lane = -0.5; for (auto light : lightpost["state"]) { lane += 1; if (!light.isConvertibleTo(stringValue)) continue; while (bulbIndex+1 >= lightBulbs.size()) { if (VRSceneManager::get()->getActiveScene() == NULL) break; // Create a new light VRGeometry* geo = new VRGeometry("ampel"); geo->addAttachment("dynamicaly_generated", 0); geo->setPrimitive("Sphere", "0.5 2"); // The first value has to be half of bulbSize geo->setMaterial(a_red); VRSceneManager::get()->getActiveScene()->add(geo); lightBulbs.push_back(geo); } // color switch VRGeometry* bulb = lightBulbs[bulbIndex++]; Vec3f p = Vec3f(streetOffset[0] + lane * normal[0], postHeight, streetOffset[1] + lane * normal[1]); string lcol = light.asString(); if (lcol == "red") { bulb->setWorldPosition(p+Vec3f(0,3 * bulbSize,0)); bulb->setMaterial(a_red); } else if (lcol == "redamber") { bulb->setWorldPosition(p+Vec3f(0,3 * bulbSize,0)); bulb->setMaterial(a_red); bulb = lightBulbs[bulbIndex++]; bulb->setWorldPosition(p+Vec3f(0,2 * bulbSize,0)); bulb->setMaterial(a_orange); } else if (lcol == "amber") { bulb->setWorldPosition(p+Vec3f(0,2 * bulbSize,0)); bulb->setMaterial(a_orange); } else if (lcol == "green") { bulb->setWorldPosition(p+Vec3f(0,bulbSize,0)); bulb->setMaterial(a_green); } } } // Remove unused lightbulbs while (bulbIndex < lightBulbs.size()) { lightBulbs.back()->destroy(); lightBulbs.pop_back(); } } } networkDataMutex.unlock(); // Advance the vehicles a bit //cout << "Update " << vehicles.size() << " vehicles\n"; for (auto v : vehicles) { Vec3f p = v.second.pos; p[1] = -1.2;//TODO: get right street height v.second.geometry->setFrom(p); v.second.geometry->setDir(v.second.pos - v.second.orientation); v.second.pos += v.second.deltaPos; v.second.orientation += v.second.deltaOrientation; } }
void update(float dt, vector<Planet*>& planets, paramStruct& params) { if(charging && charge < MAXCHARGE) charge += dt * 1.5f; pars = params; if(jumpInert > .0f) jumpInert-=dt; if(jumpInert < .0f) jumpInert = .0f; if(turn != params.turn) { charging = false; charge = .0f; } turn = params.turn; pos += vel * dt; if(pos.x > getWindowWidth()) { pos.x = pos.x-getWindowWidth(); } if(pos.x < 0) { pos.x = getWindowWidth()+pos.x; } if(pos.y > getWindowHeight()) { pos.y = pos.y-getWindowHeight(); } if(pos.y < 0) { pos.y = getWindowHeight()+pos.y; } Planet* closest = planets[0]; float dst = 999999999.0f; vector<Planet*>::iterator it; for(it = planets.begin(); it < planets.end(); it++) { Vec2f moonToPlanet = ((*it)->pos - pos); if(moonToPlanet.length() < dst) { closest = (*it); dst = moonToPlanet.length(); } // vel += moonToPlanet.normalized() * 1.0f * (*it)->radius * (*it)->radius * 3.14 / (math<float>::max(moonToPlanet.length() * moonToPlanet.length(), 80.0f)); // vel += moonToPlanet.normalized() * params.distFactor * moonToPlanet.length();//20000.0f/(math<float>::max(moonToPlanet.length(), 100.0f)); // vel += (-params.repulse)* moonToPlanet.normalized() / moonToPlanet.length(); } nearest = closest; Vec2f moonToPlanet = closest->pos - pos; if(!closestPlanet && moonToPlanet.length() > closest->radius * 2.5f) { vel += moonToPlanet.normalized() * 36.5f * pars.speed * closest->radius * closest->radius * closest->radius * (2.0f/3.0f) * M_PI / (math<float>::max(moonToPlanet.length() * moonToPlanet.length(), 80.0f)); } if(!jumpInert && !closestPlanet && moonToPlanet.length() < closest->radius * 1.7f && losing.size() == 0) { closestPlanet = closest; } if(closestPlanet && !jumpInert && losing.size() == 0) { Vec2f m2cp = (closestPlanet->pos - pos); Vec2f r = pos - closestPlanet->pos; r.normalize(); r.rotate(M_PI/1.97f); vel = r * 300.0f * pars.speed; if(m2cp.length() < closestPlanet->radius) { pos += -m2cp.normalized() * (5.0f + closestPlanet->radius - m2cp.length()); } } //vel /= planets.size(); // // Vec2f newpos = (pos + vel * dt); // for(it = planets.begin(); it < planets.end(); it++) // { // if(newpos.distance((*it)->pos) < (*it)->radius * 1.5f) // vel -= ((*it)->pos - pos); // } closest = 0; delete closest; // particles vector<Particle*>::iterator pit; for(pit = losing.begin(); pit < losing.end(); pit++) { (*pit)->update(dt); if((*pit)->time > (*pit)->lt) losing.erase(pit); } }
//---------------------------------------------------------------------- // the next edge normal is computed as a pi/2 clockwise rotation of // the direction from this point to the next one. The edge normals // do thus point to the left of the path. // Author: afischle //---------------------------------------------------------------------- static Vec2f computeEdgeNormal(const Vec2f &a, const Vec2f &b, bool cw) { Vec2f d = b - a; d.normalize(); return cw == true ? Vec2f(d.y(), -d.x()) : Vec2f(-d.y(), d.x()); }
void SerialTestApp::mouseDrag( MouseEvent event ) { mousePos = event.getPos(); Vec2f offset = mousePos - getWindowCenter(); float speed = offset.length(); offset.normalize(); float amtLeftWheel = 0; float amtRightWheel = 0; // Turning scheme: // 0-90° // 0 == other wheel moves forward @ speed // 90 == other wheel moves backwards @ speed // Never account for moving backwards. // Hard left or right is all we can do. float yRange = (MAX((offset.y*-1), 0.0)*2.0f) - 1.0f; // -1..1 //yRange*=-1; // Always having one wheel moving forward ensures we're // driving forward. We can't drive backwards. if(offset.x < 0){ amtRightWheel = 1; amtLeftWheel = yRange;// -1..1 //offset.y*-1; }else{ amtLeftWheel = 1; amtRightWheel = yRange;// -1..1 //offset.y*-1; } // Making the lw / rw amount a function of the speed const static int MAX_SPEED = 200; float speedScalar = MIN((speed/(float)MAX_SPEED), 1.0); amtLeftWheel *= speedScalar; amtRightWheel *= speedScalar; int lw = 255+(amtLeftWheel*255); // 0..255..500 int rw = 255+(amtRightWheel*255); // 0..255..500 string directions = "" + boost::lexical_cast<string>((int)lw) + "," + boost::lexical_cast<string>((int)rw) + ",\n"; console() << directions << "\n"; serial.writeString(directions); // SIM Arduino code long val = (lw*(long)1000)+rw; int rVal = val % 1000; int lVal = (val - rVal) * 0.001; int lDirection = lVal >= 255 ? 1 : -1; int rDirection = rVal >= 255 ? 1 : -1; int lAbsVal = abs(lVal-255); int rAbsVal = abs(rVal-255); console() << "lw : " << lw << " rw: " << rw; console() << " lAbsVal : " << lAbsVal << " rAbsVal: " << rAbsVal << "\n"; _ardLDir = lDirection; _ardRDir = rDirection; _ardLVal = lAbsVal; _ardRVal = rAbsVal; }
void ModuleBuildings::addBuildingWallLevel(Vec2f pos1, Vec2f pos2, int level, int bNum, float elevation) { srand(bNum); //seed for random windows float len = (pos2 - pos1).length(); Vec2f wallDir = (pos2 - pos1); wallDir.normalize(); float wall_segment = Config::get()->WINDOW_DOOR_WIDTH; float FLOOR_HEIGHT = Config::get()->BUILDING_FLOOR_HEIGHT; int segN = floor(len / wall_segment); segN = max(segN, 1); wall_segment = len / segN; float low = level * FLOOR_HEIGHT + elevation; float high = low + FLOOR_HEIGHT; // insert a door at a random place (when on level 0 && there is enough room) int doorIndex = -1; if (level == 0 && segN > 2) doorIndex = bNum % segN; int N = 4; float _N = 1./N; float e = 0.01; int di = N*float(rand()) / RAND_MAX; int wi = N*float(rand()) / RAND_MAX; int fi = N*float(rand()) / RAND_MAX; float d_tc1 = di * _N + e; float d_tc2 = di * _N - e + _N; float w_tc1 = wi * _N + e; float w_tc2 = wi * _N - e + _N; float f_tc1 = fi * _N + e; float f_tc2 = fi * _N - e + _N; for (int i=0; i<segN; i++) { Vec2f w1 = pos1 + (wallDir * (i*wall_segment)); Vec2f w2 = pos1 + (wallDir * ((i+1)*wall_segment)); Vec2f wallVector = w2-w1; Vec3f normal = Vec3f(-wallVector.getValues()[1], 0, wallVector.getValues()[0]); b_geo_d->pos->addValue(Vec3f(w1.getValues()[0], low, w1.getValues()[1])); b_geo_d->pos->addValue(Vec3f(w2.getValues()[0], low, w2.getValues()[1])); b_geo_d->pos->addValue(Vec3f(w2.getValues()[0], high, w2.getValues()[1])); b_geo_d->pos->addValue(Vec3f(w1.getValues()[0], high, w1.getValues()[1])); for (int k=0; k<4; k++) { b_geo_d->inds->addValue(b_geo_d->inds->size()); b_geo_d->norms->addValue(normal); } if (i == doorIndex) { // door b_geo_d->texs2->addValue(Vec2f(d_tc1, 0.5+e)); b_geo_d->texs2->addValue(Vec2f(d_tc2, 0.5+e)); b_geo_d->texs2->addValue(Vec2f(d_tc2, 0.75-e)); b_geo_d->texs2->addValue(Vec2f(d_tc1, 0.75-e)); } else { // window b_geo_d->texs2->addValue(Vec2f(w_tc1, 0.25+e)); b_geo_d->texs2->addValue(Vec2f(w_tc2, 0.25+e)); b_geo_d->texs2->addValue(Vec2f(w_tc2, 0.5-e)); b_geo_d->texs2->addValue(Vec2f(w_tc1, 0.5-e)); } // wall b_geo_d->texs->addValue(Vec2f(f_tc1, e)); b_geo_d->texs->addValue(Vec2f(f_tc2, e)); b_geo_d->texs->addValue(Vec2f(f_tc2, 0.25-e)); b_geo_d->texs->addValue(Vec2f(f_tc1, 0.25-e)); } }
void Branch::addArc( const Vec2f &p1 ) { if ( mPath.empty() ) { mPath.moveTo( p1 ); return; } size_t segmentNum = mPath.getNumSegments(); if ( segmentNum == 0 ) { mPath.lineTo( p1 ); return; } // last point Vec2f p0 = mPath.getSegmentPosition( segmentNum - 1, 1.f ); // same point as the last one -> skip if ( p0.distanceSquared( p1 ) < EPSILON ) return; // segment tangent - direction of the last segment Vec2f tangent = p0 - mPath.getSegmentPosition( segmentNum - 1, .98f ); Vec2f n( -tangent.y, tangent.x ); // segment normal Vec2f d( p1 - p0 ); // distance of the arc center and the last path point d *= .5f; Vec2f b( -d.y, d.x ); // arc bisector // parallel vectors, p1 lies on the tangent float dot = b.dot( n ); float sqrLength = b.lengthSquared() * n.lengthSquared(); // does not seem to be a very precise test, hence the .1f limit instead of EPSILON if ( math< float >::abs( dot * dot - sqrLength ) < .1f ) { mPath.lineTo( p1 ); return; } // the arc center is the intersection of the segment normal and the bisector float s; if ( n.x == 0.f ) { if ( b.x == 0.f ) // parallel { mPath.lineTo( p1 ); return; } s = -d.x / b.x; } else { float den = b.x * n.y / n.x - b.y; if ( den == 0.f ) // parallel { mPath.lineTo( p1 ); return; } s = ( d.y - d.x * n.y / n.x ) / ( b.x * n.y / n.x - b.y ); } Vec2f c( ( p0 + p1 ) *.5f + s * b ); // arc center Vec2f d0( p0 - c ); float a0 = math< float >::atan2( d0.y, d0.x ); Vec2f d1( p1 - c ); float a1 = math< float >::atan2( d1.y, d1.x ); // segment normal line and segment bisector distance tangent.normalize(); float C = tangent.dot( p0 ); float dist = tangent.dot( ( p0 + p1 ) * .5f ) - C; // arc direction depends on the quadrant, in which the new point resides bool forward = ( s > 0.f ) ^ ( dist < 0.f ); mPath.arc( c, d0.length(), a0, a1, forward ); }