//--------------------------------------------------------------
void testApp::updateMovers(){
  //ofVec2f wind(ofMap(mouseX, ofGetWidth()/2, ofGetWidth(), 0, 0.01), 0);
  ofVec2f windCartesian(-sin(ofDegToRad(wind.y)), cos(ofDegToRad(wind.y)));
  ofVec2f windForce(wind_speed * wind_speed * windCartesian/coefPixelToRealWorld);  
  //ofVec2f gravity(0, 0.1);
  //generate balls here
  if (wind_speed > 2 && (ofRandomuf() < 0.00001 * wind_speed * cloudProbability || wind_speed - last_wind_speed > 4)){
  //if (wind_speed > 2 && (ofRandomuf() < 0.00001 * 60 * cloudProbability || wind_speed - last_wind_speed > 4)){
		movers.push_back(ofPtr<Mover>(new Mover()));
		movers.back().get()->setup();
    //movers.back().get()->setMass(ofRandom(1.1, 4));
    movers.back().get()->setMass(1);
    ofVec2f location;
    location.y = ofGetHeight()/2.;
    float width = 2/3.*ofGetHeight();
    if (windCartesian.x > 0){
      //location.x =  0-movers.back().get()->getDiameter();
      location.x =  -width;
    }
    else {
      //location.x =  ofGetWidth();
      location.x =  ofGetWidth()+width;
    }

    //coefPixelToRealWorld = 1;
    movers.back().get()->setLocation(location.x, location.y);
    windCartesian.y = 0;
    windCartesian.normalize();
    movers.back().get()->setVelocity(windCartesian*wind_speed/coefPixelToRealWorld);

  }
  last_wind_speed = wind_speed;
  // update balls
  for (unsigned int i = 0; i < movers.size(); i++){
    //friction
    float c = frictionCoef;
    ofVec2f friction(movers[i].get()->getVelocity());
    friction *= -1;
    friction.normalize();
    friction *= c;


    movers[i].get()->applyForce(friction);
    //movers[i].applyForce(windForce);
    //movers[i].applyForce(gravity);
    movers[i].get()->update();
    movers[i].get()->checkEdges();
  }
  // delete balls
  ofRemove(movers, Mover::shouldRemoveOffScreen);

}
Beispiel #2
0
void ForestWindMgr::updateWind(  const Point3F &camPos, 
                                 const TreePlacementInfo &info, 
                                 F32 timeDelta )
{
   PROFILE_SCOPE(ForestWindMgr_updateWind);

   // See if we have the blended source available.
   ForestWindAccumulator *blendDest = NULL;
   {
      IdToWindMap::Iterator iter = mPrevSources->find( info.itemKey );
      if ( iter != mPrevSources->end() )
      {
         blendDest = iter->value;
         mPrevSources->erase( iter );
      }
   }

   // Get some stuff we'll need for finding the emitters.
   F32 treeHeight = info.scale * info.dataBlock->getObjBox().len_z();
   Point3F top = info.pos;
   top.z += treeHeight;
   if ( blendDest )
      top += ( 1.0f / info.scale ) * blendDest->getDirection();

   // Go thru the emitters to accumulate the total wind force.
   VectorF windForce( 0, 0, 0 );

   F32 time = Sim::getCurrentTime() / 1000.0f;

   ForestWindEmitterList::iterator iter = mEmitters.begin();
   for ( ; iter != mEmitters.end(); iter++ )
   {
      ForestWindEmitter *emitter = (*iter);

      // If disabled or no wind object... skip it.
      if ( !emitter->isEnabled() || !emitter->getWind() )
         continue;

      ForestWind *wind = emitter->getWind();

      F32 strength = wind->getStrength();
      
      if ( emitter->isRadialEmitter() )
      {
         Point3F closest = MathUtils::mClosestPointOnSegment( info.pos, top, emitter->getPosition() );
         Point3F dir = closest - emitter->getPosition();
         F32 lenSquared = dir.lenSquared();
         if ( lenSquared > emitter->getWindRadiusSquared() )
            continue;

         dir *= 1.0f / mSqrt( lenSquared );

         F32 att = lenSquared / emitter->getWindRadiusSquared();
         strength *= 1.0f - att;
         windForce += dir * strength;
      }
      else
      {
         F32 d = mDot( info.pos, Point3F::One ); //PlaneF( Point3F::Zero, wind->getDirection() ).distToPlane( Point3F( info.pos.x, info.pos.y, 0 ) );
         //F32 d = PlaneF( Point3F::Zero, wind->getDirection() ).distToPlane( Point3F( info.pos.x, info.pos.y, 0 ) );
         F32 scale = 1.0f + ( mSin( d + ( time / 10.0 ) ) * 0.5f );
         windForce += wind->getDirection() * strength * scale;
      }
   }

   // If we need a accumulator then we also need to presimulate.
   if ( !blendDest )
   {
      blendDest = new ForestWindAccumulator( info );
      blendDest->presimulate( windForce, 4.0f / TickSec );
   }
   else
      blendDest->updateWind( windForce, timeDelta );

   mSources->insertUnique( info.itemKey, blendDest );
}