Torque3D Documentation / _generateds / forestWindAccumulator.cpp

forestWindAccumulator.cpp

Engine/source/forest/forestWindAccumulator.cpp

More...

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "forest/forestWindAccumulator.h"
 26
 27#include "forest/forestWindMgr.h"
 28#include "forest/forestItem.h"
 29#include "platform/profiler.h"
 30
 31
 32ForestWindAccumulator::ForestWindAccumulator( const TreePlacementInfo &info )
 33:  mCurrentStrength( 0.0f )
 34{
 35   mCurrentDir.set( 0, 0 );   
 36   mPosition.set( info.pos );
 37   mScale = info.scale;
 38
 39   mDataBlock = info.dataBlock;
 40
 41   dMemset( &mParticles[0], 0, sizeof( VerletParticle ) );
 42   dMemset( &mParticles[1], 0, sizeof( VerletParticle ) );
 43}
 44
 45ForestWindAccumulator::~ForestWindAccumulator()
 46{
 47}
 48
 49void ForestWindAccumulator::presimulate( const VectorF &windVector, U32 ticks )
 50{
 51   PROFILE_SCOPE( ForestWindAccumulator_Presimulate );
 52
 53   for ( U32 i = 0; i < ticks; i++ )
 54      updateWind( windVector, TickSec );
 55}
 56
 57void ForestWindAccumulator::updateWind( const VectorF &windForce, F32 timeDelta )
 58{
 59   PROFILE_SCOPE( ForestWindAccumulator_UpdateWind );
 60
 61   // Update values from datablock... this way we can
 62   // change settings live and see instant results.
 63   const F32 tightnessCoefficient = mDataBlock->mTightnessCoefficient;
 64   const F32 dampingCoefficient = mDataBlock->mDampingCoefficient;
 65   const F32 mass = mDataBlock->mMass * mScale;
 66   const F32 rigidity = mDataBlock->mRigidity * mScale;
 67
 68   // This will be the accumulated
 69   // target strength for flutter.
 70   //F32 targetStrength = windForce.len();
 71
 72   // This will be the accumulated
 73   // target displacement vector.
 74   Point2F target( windForce.x, windForce.y );
 75
 76   // This particle is the spring target.
 77   // It has a mass of 0, which we count as
 78   // an infinite mass.
 79   mParticles[0].position = target;
 80
 81   Point2F diff( 0, 0 );
 82   Point2F springForce( 0, 0 );
 83
 84   // Spring length is the target
 85   // particle's position minus the
 86   // current displacement/direction vector.
 87   diff = mParticles[0].position - mCurrentDir;
 88
 89   // F = diff * tightness - v * -damping
 90   diff *= tightnessCoefficient;
 91   springForce = diff - ( (mParticles[1].position - mParticles[1].lastPosition) * -dampingCoefficient );
 92
 93   Point2F accel( 0, 0 );
 94   accel = springForce * (rigidity * 0.001f) / (mass * 0.001f);
 95
 96   _updateParticle( &mParticles[1], accel, timeDelta );
 97
 98   mCurrentDir *= 0.989f;
 99   mCurrentDir += mParticles[1].position;
100
101   mCurrentStrength += windForce.len() * timeDelta;
102   mCurrentStrength *= 0.98f;
103}
104
105void ForestWindAccumulator::_updateParticle( VerletParticle *particle, const Point2F &accel, F32 timeDelta )
106{
107   // Verlet integration:
108   // x' = 2x - x* + a * dt^2
109   // x' is the new position.
110   // x is the current position.
111   // x* is the last position.
112   // a is the acceleration for this frame.
113   // dt is the delta time.
114  
115   particle->position = ((particle->position * 2.0f) - particle->lastPosition) + accel * (timeDelta * timeDelta);
116   particle->lastPosition = particle->position;
117}
118
119void ForestWindAccumulator::applyImpulse( const VectorF &impulse )
120{
121   // First build the current force.
122   VectorF force( mCurrentDir.x, mCurrentDir.y, 0 );
123
124   // Add in our mass corrected force.
125   const F32 mass = mDataBlock->mMass * mScale;
126   force += impulse / mass;
127
128   // Set the new direction and force.
129   mCurrentDir.set( force.x, force.y );  
130   mCurrentStrength += impulse.len() * TickSec;
131}
132