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;
					
				}
			}
		}
	}
}
Exemple #5
0
  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;
}
Exemple #7
0
	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;
	}
Exemple #8
0
	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;
	}
Exemple #9
0
	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;
		}
	}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #14
0
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;

}
Exemple #15
0
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;
    }

}
Exemple #17
0
	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));
    }
}
Exemple #21
0
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 );
}