2013-11-12 00:10:48 +01:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
// Created by Dan Andersson 2013
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "Particle.h"
|
|
|
|
#include "Utilities.h"
|
|
|
|
|
|
|
|
using namespace ::Oyster::Math3D;
|
|
|
|
using namespace ::Oyster::Collision3D;
|
|
|
|
using namespace ::Oyster::Physics3D;
|
|
|
|
|
|
|
|
Particle::Particle( const Sphere &s, Float m )
|
|
|
|
: sphere(s), linearMomentum(Float3::null), impulseForceSum(Float3::null)
|
|
|
|
{
|
|
|
|
if( m == 0.0f )
|
|
|
|
{
|
|
|
|
this->mass = ::Utility::Value::numeric_limits<Float>::epsilon();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->mass = m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Particle & Particle::operator = ( const Particle &particle )
|
|
|
|
{
|
|
|
|
this->sphere = particle.sphere;
|
|
|
|
this->linearMomentum = particle.linearMomentum;
|
|
|
|
this->impulseForceSum = particle.impulseForceSum;
|
|
|
|
this->mass = particle.mass;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::Update_LeapFrog( Float deltaTime )
|
|
|
|
{ // Euler leap frog update when Runga Kutta is not needed
|
|
|
|
this->impulseForceSum *= (deltaTime / this->mass); // is now deltaLinearVelocity ( dt * a = dt * F / m )
|
2013-12-18 08:57:27 +01:00
|
|
|
this->sphere.center.xyz += deltaTime * ::Utility::Value::AverageWithDelta( Formula::LinearVelocity(this->mass, this->linearMomentum), this->impulseForceSum );
|
2013-11-12 00:10:48 +01:00
|
|
|
this->linearMomentum += Formula::LinearMomentum( this->mass, this->impulseForceSum );
|
|
|
|
this->impulseForceSum = Float3::null;
|
|
|
|
|
|
|
|
/* Fun notation
|
|
|
|
the operations above can be written like this
|
|
|
|
p = p0 + dt*( v0 + dt*(F/m)/2 )
|
|
|
|
= p0 + dt*v0 + dt^2*(F/m)/2
|
|
|
|
there:
|
|
|
|
* dt = deltaTime
|
|
|
|
* p = this->sphere.position at the end of deltaTime
|
|
|
|
* p0 = this->sphere.position at beginning of deltaTime
|
|
|
|
* v0 = this->velocity at beginning of deltaTime
|
|
|
|
* m = this->mass
|
|
|
|
* F = this->sumForces pushing during deltaTime
|
|
|
|
|
|
|
|
It is the law of motion with constant acceleration.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::ApplyImpulseForce( const Float3 &f )
|
|
|
|
{
|
|
|
|
this->impulseForceSum += f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::ApplyLinearImpulseAcceleration( const Float3 &a )
|
|
|
|
{
|
|
|
|
this->impulseForceSum += this->mass * a;
|
|
|
|
}
|
|
|
|
|
|
|
|
Float3 & Particle::AccessCenter()
|
|
|
|
{
|
2013-12-18 08:57:27 +01:00
|
|
|
return this->sphere.center.xyz;
|
2013-11-12 00:10:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const Float3 & Particle::AccessCenter() const
|
|
|
|
{
|
2013-12-18 08:57:27 +01:00
|
|
|
return this->sphere.center.xyz;
|
2013-11-12 00:10:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Float & Particle::AccessRadius()
|
|
|
|
{
|
|
|
|
return this->sphere.radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Float & Particle::AccessRadius() const
|
|
|
|
{
|
|
|
|
return this->sphere.radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Float & Particle::GetMass() const
|
|
|
|
{
|
|
|
|
return this->mass;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Float3 & Particle::GetCenter() const
|
|
|
|
{
|
2013-12-18 08:57:27 +01:00
|
|
|
return this->sphere.center.xyz;
|
2013-11-12 00:10:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const Float & Particle::GetRadius() const
|
|
|
|
{
|
|
|
|
return this->sphere.radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Float3 & Particle::GetImpulseForce() const
|
|
|
|
{
|
|
|
|
return this->impulseForceSum;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Float3 & Particle::GetLinearMomentum() const
|
|
|
|
{
|
|
|
|
return this->linearMomentum;
|
|
|
|
}
|
|
|
|
|
|
|
|
Float3 Particle::GetLinearImpulseAcceleration() const
|
|
|
|
{
|
|
|
|
return Formula::LinearImpulseAcceleration( this->mass, this->impulseForceSum );
|
|
|
|
}
|
|
|
|
|
|
|
|
Float3 Particle::GetLinearVelocity() const
|
|
|
|
{
|
|
|
|
return Formula::LinearVelocity( this->mass, this->linearMomentum );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetMass_KeepVelocity( Float m )
|
|
|
|
{
|
|
|
|
Float3 velocity = Formula::LinearVelocity( this->mass, this->linearMomentum );
|
|
|
|
this->SetMass_KeepMomentum( m );
|
|
|
|
this->linearMomentum = Formula::LinearMomentum( this->mass, velocity );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetMass_KeepMomentum( Float m )
|
|
|
|
{
|
|
|
|
if( m == 0.0f )
|
|
|
|
{
|
|
|
|
this->mass = ::Utility::Value::numeric_limits<Float>::epsilon();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->mass = m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetCenter( const Float3 &p )
|
|
|
|
{
|
|
|
|
this->sphere.center = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetRadius( Float r )
|
|
|
|
{
|
|
|
|
this->sphere.radius = r;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetImpulseForce( const Float3 &f )
|
|
|
|
{
|
|
|
|
this->impulseForceSum = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetLinearMomentum( const Float3 &g )
|
|
|
|
{
|
|
|
|
this->linearMomentum = g;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetLinearImpulseAcceleration( const Float3 &a )
|
|
|
|
{
|
|
|
|
this->impulseForceSum = Formula::ImpulseForce( this->mass, a );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Particle::SetLinearVelocity( const Float3 &v )
|
|
|
|
{
|
|
|
|
this->linearMomentum = Formula::LinearMomentum( this->mass, v );
|
|
|
|
}
|