//-------------------------------------------------------------- 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); }
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 ); }