Some cool stuff

This commit is contained in:
Robin Engman 2014-02-06 21:15:28 +01:00
parent 81d43b59c0
commit f372d3e05b
9 changed files with 258 additions and 61 deletions

View File

@ -19,7 +19,7 @@ Game::PlayerData::PlayerData()
Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release();
//create player with this rigid body //create player with this rigid body
this->player = new Player(rigidBody,Player::PlayerCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); this->player = new Player(rigidBody,Player::DefaultCollisionAfter, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER);
this->player->GetRigidBody()->SetCustomTag(this); this->player->GetRigidBody()->SetCustomTag(this);
/*Oyster::Physics::ICustomBody::State state; /*Oyster::Physics::ICustomBody::State state;
this->player->GetRigidBody()->GetState(state); this->player->GetRigidBody()->GetState(state);

View File

@ -55,7 +55,7 @@ void Level::InitiateLevel(float radius)
sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1); sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1);
sbDesc.ignoreGravity = true; sbDesc.ignoreGravity = true;
sbDesc.radius = 300; sbDesc.radius = 300;
sbDesc.mass = 10e12f; sbDesc.mass = 100;
sbDesc.frictionCoeff_Static = 0; sbDesc.frictionCoeff_Static = 0;
sbDesc.frictionCoeff_Dynamic = 0; sbDesc.frictionCoeff_Dynamic = 0;
//sbDesc.rotation = //sbDesc.rotation =
@ -75,7 +75,7 @@ void Level::InitiateLevel(float radius)
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0); sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0);
sbDesc_TestBox.ignoreGravity = false; sbDesc_TestBox.ignoreGravity = false;
sbDesc_TestBox.mass = 50; sbDesc_TestBox.mass = 20;
sbDesc_TestBox.size = Oyster::Math::Float4(2,2,2,0); sbDesc_TestBox.size = Oyster::Math::Float4(2,2,2,0);
@ -85,7 +85,7 @@ void Level::InitiateLevel(float radius)
int offset = 0; int offset = 0;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20 +( i*7) ,320,20,0); sbDesc_TestBox.centerPosition = Oyster::Math::Float4(0,305 + i*5,5,1);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
@ -95,7 +95,7 @@ void Level::InitiateLevel(float radius)
offset += nrOfBoxex; offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20,320, -20 +( i*7),0); sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20,320, -200 +( i*7),0);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
@ -105,7 +105,7 @@ void Level::InitiateLevel(float radius)
offset += nrOfBoxex; offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(20,320,-20 + ( i*7),0); sbDesc_TestBox.centerPosition = Oyster::Math::Float4(200,320 + ( i*7),0,0);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
@ -115,12 +115,12 @@ void Level::InitiateLevel(float radius)
offset += nrOfBoxex; offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++) for(int i =0; i< nrOfBoxex; i ++)
{ {
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20 +( i*7) ,320,-20,0); sbDesc_TestBox.centerPosition = Oyster::Math::Float4(5,305 + i*5,0,0);
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]); rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]);
} }
@ -129,10 +129,10 @@ void Level::InitiateLevel(float radius)
// add crystal // add crystal
API::SimpleBodyDescription sbDesc_Crystal; API::SimpleBodyDescription sbDesc_Crystal;
sbDesc_Crystal.centerPosition = Oyster::Math::Float4(10, 305, 0, 0); sbDesc_Crystal.centerPosition = Oyster::Math::Float4(10, 305, 0, 1);
sbDesc_Crystal.ignoreGravity = false; sbDesc_Crystal.ignoreGravity = false;
sbDesc_Crystal.mass = 70; sbDesc_Crystal.mass = 80;
sbDesc_Crystal.size = Oyster::Math::Float4(2,3,2,0); sbDesc_Crystal.size = Oyster::Math::Float3(2,3,2);
ICustomBody* rigidBody_Crystal = API::Instance().CreateRigidBody(sbDesc_Crystal).Release(); ICustomBody* rigidBody_Crystal = API::Instance().CreateRigidBody(sbDesc_Crystal).Release();
rigidBody_Crystal->SetSubscription(Level::PhysicsOnMoveLevel); rigidBody_Crystal->SetSubscription(Level::PhysicsOnMoveLevel);
@ -143,11 +143,11 @@ void Level::InitiateLevel(float radius)
// add house // add house
API::SimpleBodyDescription sbDesc_House; API::SimpleBodyDescription sbDesc_House;
//sbDesc_House.centerPosition = Oyster::Math::Float4(212, 212, 0, 0); //sbDesc_House.centerPosition = Oyster::Math::Float4(212, 212, 0, 0);
sbDesc_House.centerPosition = Oyster::Math::Float4(-50, 290, 0, 0); sbDesc_House.centerPosition = Oyster::Math::Float4(-50, 290, 0, 1);
sbDesc_House.ignoreGravity = false; sbDesc_House.ignoreGravity = false;
sbDesc_House.rotation = Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0); sbDesc_House.rotation = Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0);
sbDesc_House.mass = 70; sbDesc_House.mass = 90;
sbDesc_House.size = Oyster::Math::Float4(40,40,40,0); sbDesc_House.size = Oyster::Math::Float3(40,40,40);
ICustomBody* rigidBody_House = API::Instance().CreateRigidBody(sbDesc_House).Release(); ICustomBody* rigidBody_House = API::Instance().CreateRigidBody(sbDesc_House).Release();

View File

@ -167,6 +167,7 @@ void Object::EndFrame()
//error //error
int i =0 ; int i =0 ;
} }
axis.Normalize();
currPhysicsState.SetRotation(axis.xyz); currPhysicsState.SetRotation(axis.xyz);
currPhysicsState.SetAngularMomentum(Float3::null); currPhysicsState.SetAngularMomentum(Float3::null);
Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y);
@ -177,13 +178,13 @@ void Object::EndFrame()
//300, 0,0, //300, 0,0,
//1,0,0 //1,0,0
if( pos.GetLength() < 303.5f) /*if( pos.GetLength() < 303.5f)
{ {
Oyster::Math::Float moveUp = 303.5 - pos.GetLength(); Oyster::Math::Float moveUp = 303.5 - pos.GetLength();
up *= moveUp; up *= moveUp;
currPhysicsState.SetCenterPosition(pos + up); currPhysicsState.SetCenterPosition(pos + up);
} }*/
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum()) if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())

View File

@ -14,7 +14,7 @@ API_Impl API_instance;
namespace namespace
{ {
void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef ) /*void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef )
{ {
auto proto = worldScene.GetCustomBody( protoTempRef ); auto proto = worldScene.GetCustomBody( protoTempRef );
auto deuter = worldScene.GetCustomBody( deuterTempRef ); auto deuter = worldScene.GetCustomBody( deuterTempRef );
@ -27,26 +27,26 @@ namespace
ICustomBody::State deuterState; deuter->GetState( deuterState ); ICustomBody::State deuterState; deuter->GetState( deuterState );
// calc from perspective of deuter. // calc from perspective of deuter.
Float4 normal = (worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f )).GetNormalized(); // Init value is only borrowed Float4 normal = (worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f )); // Init value is only borrowed
if( normal.Dot(normal) > 0.0f ) //if( normal.Dot(normal) > 0.0f )
{ {
deuter->GetNormalAt( worldPointOfContact, normal ); deuter->GetNormalAt( worldPointOfContact, normal );
} }
else //else
{ // special case: deuter is completly contained within proto or they have overlapping centers. //{ // special case: deuter is completly contained within proto or they have overlapping centers.
normal = Float4( protoState.GetCenterPosition() - deuterState.GetCenterPosition(), 0.0f ); // normal = Float4( protoState.GetCenterPosition() - deuterState.GetCenterPosition(), 0.0f );
if( normal.Dot(normal) == 0.0f ) // if( normal.Dot(normal) == 0.0f )
{ // they have overlapping centers. Rebound at least // { // they have overlapping centers. Rebound at least
// calculate and store time interpolation value, for later rebound. // // calculate and store time interpolation value, for later rebound.
proto->SetTimeOfContact( worldPointOfContact ); // proto->SetTimeOfContact( worldPointOfContact );
return; // return;
} // }
//
// borrowing the negated normal of proto. // // borrowing the negated normal of proto.
proto->GetNormalAt( worldPointOfContact, normal ); // proto->GetNormalAt( worldPointOfContact, normal );
normal = -normal; // normal = -normal;
} //}
normal.Normalize(); normal.Normalize();
Float4 protoG = Float4(protoState.GetLinearMomentum( worldPointOfContact.xyz ), 0), Float4 protoG = Float4(protoState.GetLinearMomentum( worldPointOfContact.xyz ), 0),
@ -93,13 +93,13 @@ namespace
// PLayerHAck // PLayerHAck
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response ) if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response )
{ {
Float3 linearMomentum = protoState.GetLinearMomentum(); //Float3 linearMomentum = protoState.GetLinearMomentum();
Float3 up = -protoState.GetGravityNormal(); //Float3 up = -protoState.GetGravityNormal();
Float3 upForce = (linearMomentum.Dot(up) * up); //Float3 upForce = (linearMomentum.Dot(up) * up);
Float3 noBounceForce = linearMomentum - upForce; //Float3 noBounceForce = linearMomentum - upForce;
protoState.SetLinearMomentum(noBounceForce); //protoState.SetLinearMomentum(noBounceForce);
proto->SetState(protoState); //proto->SetState(protoState);
return; return;
} }
// calculate and store time interpolation value, for later rebound. // calculate and store time interpolation value, for later rebound.
@ -114,24 +114,25 @@ namespace
// calc from perspective of proto // calc from perspective of proto
normal = (worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f )).GetNormalized(); normal = (worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f )).GetNormalized();
if( normal.Dot(normal) > 0.0f ) //if( normal.Dot(normal) > 0.0f )
{ {
proto->GetNormalAt( worldPointOfContact, normal ); proto->GetNormalAt( worldPointOfContact, normal );
protoG_Magnitude = protoG.Dot( normal ); protoG_Magnitude = protoG.Dot( normal );
deuterG_Magnitude = deuterG.Dot( normal ); deuterG_Magnitude = deuterG.Dot( normal );
normal.Normalize();
} }
else //else
{ // special case: proto is completly contained within deuter. //{ // special case: proto is completly contained within deuter.
// borrowing the negated normal of deuter. // // borrowing the negated normal of deuter.
deuter->GetNormalAt( worldPointOfContact, normal ); // deuter->GetNormalAt( worldPointOfContact, normal );
normal = -normal; // normal = -normal;
protoG_Magnitude = -protoG_Magnitude; // protoG_Magnitude = -protoG_Magnitude;
deuterG_Magnitude = -deuterG_Magnitude; // deuterG_Magnitude = -deuterG_Magnitude;
} //}
if( normal != normal ) // debug: trap if( normal != normal ) // debug: trap
const char *breakpoint = "This should never happen"; const char *breakpoint = "This should never happen";
// bounce // bounce
Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(), Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(),
protoState.GetMass(), protoG_Magnitude, protoState.GetMass(), protoG_Magnitude,
@ -143,9 +144,183 @@ namespace
Float4(protoState.GetLinearMomentum(), 0), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(), Float4(protoState.GetLinearMomentum(), 0), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(),
Float4(deuterState.GetLinearMomentum(), 0), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass()); Float4(deuterState.GetLinearMomentum(), 0), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass());
if(protoState.GetMass() == 70)
{
const char* breakPoint = "here";
}
Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() ); Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() );
protoState.ApplyImpulse( bounce.xyz - friction.xyz, worldPointOfContact.xyz, normal.xyz ); protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz );
proto->SetState( protoState );
Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() );
proto->CallSubscription_AfterCollisionResponse( deuter, kineticEnergyPBefore - kineticEnergyPAFter );
}
}*/
void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef )
{
auto proto = worldScene.GetCustomBody( protoTempRef );
auto deuter = worldScene.GetCustomBody( deuterTempRef );
if(proto->GetState().GetMass() == 70)
{
const char *breakpoint = "STOP";
}
Float4 worldPointOfContact;
if( proto->Intersects(*deuter, worldPointOfContact) )
{
// Apply CollisionResponse in pure gather pattern
ICustomBody::State protoState; proto->GetState( protoState );
ICustomBody::State deuterState; deuter->GetState( deuterState );
// calc from perspective of deuter.
// calc from perspective of deuter.
Float4 normal = (worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f )).GetNormalized(); // Init value is only borrowed
if( normal.Dot(normal) > 0.0f )
{
deuter->GetNormalAt( worldPointOfContact, normal );
}
else
{ // special case: deuter is completly contained within proto or they have overlapping centers.
normal = Float4( protoState.GetCenterPosition() - deuterState.GetCenterPosition(), 0.0f );
if( normal.Dot(normal) == 0.0f )
{ // they have overlapping centers. Rebound at least
// calculate and store time interpolation value, for later rebound.
proto->SetTimeOfContact( worldPointOfContact );
return;
}
// borrowing the negated normal of proto.
proto->GetNormalAt( worldPointOfContact, normal );
normal = -normal;
}
normal.Normalize();
Float4 protoG = Float4(protoState.GetLinearMomentum( worldPointOfContact.xyz ), 0),
deuterG = Float4(deuterState.GetLinearMomentum( worldPointOfContact.xyz ), 0);
Float protoG_Magnitude = protoG.Dot( normal ),
deuterG_Magnitude = deuterG.Dot( normal );
if(protoState.GetMass() == 70)
{
const char *breakpoint = "STOP";
}
// if they are not relatively moving towards eachother, there is no collision
Float deltaPos = normal.Dot( Float4(deuterState.GetCenterPosition(), 1) - Float4(protoState.GetCenterPosition(), 1) );
if( deltaPos < 0.0f )
{
if( protoG_Magnitude >= deuterG_Magnitude )
{
return;
}
}
else if( deltaPos > 0.0f )
{
if( protoG_Magnitude <= deuterG_Magnitude )
{
return;
}
}
else
{
return;
}
// calc from perspective of proto
normal = (worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f )).GetNormalized();
if( normal.Dot(normal) > 0.0f )
{
proto->GetNormalAt( worldPointOfContact, normal );
protoG_Magnitude = protoG.Dot( normal );
deuterG_Magnitude = deuterG.Dot( normal );
normal.Normalize();
}
else
{ // special case: proto is completly contained within deuter.
// borrowing the negated normal of deuter.
deuter->GetNormalAt( worldPointOfContact, normal );
normal = -normal;
protoG_Magnitude = -protoG_Magnitude;
deuterG_Magnitude = -deuterG_Magnitude;
}
normal.Normalize();
if( normal != normal ) // debug: trap
const char *breakpoint = "This should never happen";
Float4 friction = Formula::CollisionResponse::Friction( protoG_Magnitude, normal,
Float4(protoState.GetLinearMomentum(), 0), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(),
Float4(deuterState.GetLinearMomentum(), 0), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass());
if(protoState.GetMass() == 70)
{
const char *breakpoint = "STOP";
}
protoState.ApplyFriction( -friction.xyz );
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_ignore_collision_response )
{
return;
}
// PLayerHAck
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response )
{
return;
}
if(protoState.GetMass() == 50)
{
const char* breakPoint = "Break";
}
// bounce
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
deuterState.GetMass(), deuterG_Magnitude,
protoState.GetMass(), protoG_Magnitude );
// calc from perspective of proto
proto->GetNormalAt( worldPointOfContact, normal );
normal.Normalize();
protoG_Magnitude = protoG.Dot( normal );
deuterG_Magnitude = deuterG.Dot( normal );
// bounce
Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(),
protoState.GetMass(), protoG_Magnitude,
deuterState.GetMass(), deuterG_Magnitude );
Float4 bounce = bounceP;
//LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp(state.SetOrientation(, Float4(state.GetGravityNormal(), 0.0f), 1.0f);
if( abs(bounce.x) < 0.001 )
{
bounce.x = 0;
}
if( abs(bounce.y) < 0.001 )
{
bounce.y = 0;
}
if( abs(bounce.z) < 0.001 )
{
bounce.z = 0;
}
Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() );
protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz );
proto->SetState( protoState ); proto->SetState( protoState );
Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() ); Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() );
@ -232,8 +407,12 @@ void API_Impl::Update()
Float rSquared = d.Dot( d ); Float rSquared = d.Dot( d );
if( rSquared != 0.0 ) if( rSquared != 0.0 )
{ {
if(state.GetMass() == 70)
{
const char *breakpoint = "STOP";
}
Float force = Physics3D::Formula::ForceField( this->gravityConstant, state.GetMass(), this->gravity[i].well.mass, rSquared ); Float force = Physics3D::Formula::ForceField( this->gravityConstant, state.GetMass(), this->gravity[i].well.mass, rSquared );
gravityImpulse += (this->updateFrameLength * force / ::std::sqrt(rSquared)) * d; gravityImpulse += ((this->updateFrameLength * force)) * d.GetNormalized();
} }
break; break;
} }
@ -250,14 +429,17 @@ void API_Impl::Update()
if( gravityImpulse != gravityImpulse ) // debug: trap if( gravityImpulse != gravityImpulse ) // debug: trap
const char *breakpoint = "This should never happen"; const char *breakpoint = "This should never happen";
Float posLength = state.GetCenterPosition().GetLength();
if( gravityImpulse != Float4::null ) if( gravityImpulse != Float4::null && posLength - 300 > 3.5 )
{ {
state.ApplyLinearImpulse( gravityImpulse.xyz ); state.ApplyLinearImpulse( gravityImpulse.xyz );
state.SetGravityNormal( gravityImpulse.GetNormalized().xyz ); state.SetGravityNormal( gravityImpulse.GetNormalized().xyz );
(*proto)->SetState( state ); (*proto)->SetState( state );
} }
if(state.GetMass() == 70)
{
const char *breakpoint = "STOP";
}
// Step 2: Apply Collision Response // Step 2: Apply Collision Response
this->worldScene.Visit( *proto, OnPossibleCollision ); this->worldScene.Visit( *proto, OnPossibleCollision );
} }
@ -271,7 +453,7 @@ void API_Impl::Update()
//LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp(state.SetOrientation(, Float4(state.GetGravityNormal(), 0.0f), 1.0f); //LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp(state.SetOrientation(, Float4(state.GetGravityNormal(), 0.0f), 1.0f);
if( abs(lM.x) < this->epsilon ) /*if( abs(lM.x) < this->epsilon )
{ {
state.linearMomentum.x = 0; state.linearMomentum.x = 0;
} }
@ -282,7 +464,7 @@ void API_Impl::Update()
if( abs(lM.z) < this->epsilon ) if( abs(lM.z) < this->epsilon )
{ {
state.linearMomentum.z = 0; state.linearMomentum.z = 0;
} }*/
(*proto)->SetState( state ); (*proto)->SetState( state );

View File

@ -333,6 +333,12 @@ namespace Oyster
this->isDisturbed = true; this->isDisturbed = true;
} }
inline void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j )
{
this->linearImpulse += j;
this->isDisturbed = true;
}
inline void CustomBodyState::ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis ) inline void CustomBodyState::ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis )
{ {
this->deltaPos += deltaPos; this->deltaPos += deltaPos;

View File

@ -109,6 +109,7 @@ namespace Oyster { namespace Physics
void ApplyLinearImpulse( const ::Oyster::Math::Float3 &j ); void ApplyLinearImpulse( const ::Oyster::Math::Float3 &j );
void ApplyAngularImpulse( const ::Oyster::Math::Float3 &j ); void ApplyAngularImpulse( const ::Oyster::Math::Float3 &j );
void ApplyImpulse( const ::Oyster::Math::Float3 &j, const ::Oyster::Math::Float3 &at, const ::Oyster::Math::Float3 &normal ); void ApplyImpulse( const ::Oyster::Math::Float3 &j, const ::Oyster::Math::Float3 &at, const ::Oyster::Math::Float3 &normal );
void CustomBodyState::ApplyFriction( const ::Oyster::Math::Float3 &j);
void ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis ); void ApplyForwarding( const ::Oyster::Math::Float3 &deltaPos, const ::Oyster::Math::Float3 &deltaAxis );
bool IsSpatiallyAltered() const; bool IsSpatiallyAltered() const;

View File

@ -516,7 +516,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
Float4 C = sphereA.center; Float4 C = sphereA.center;
C -= sphereB.center; C -= sphereB.center;
Float r = (sphereA.radius + sphereB.radius); Float r = (sphereA.radius + sphereB.radius);
Float dotprod = C.Dot(C);
if (r*r >= C.Dot(C)) if (r*r >= C.Dot(C))
{ {
return true; // Intersect detected! return true; // Intersect detected!

View File

@ -279,7 +279,7 @@ namespace Oyster { namespace Physics3D
******************************************************************/ ******************************************************************/
inline ::Oyster::Math::Float ForceField( ::Oyster::Math::Float g, ::Oyster::Math::Float massA, ::Oyster::Math::Float massB, ::Oyster::Math::Float radiusSquared ) inline ::Oyster::Math::Float ForceField( ::Oyster::Math::Float g, ::Oyster::Math::Float massA, ::Oyster::Math::Float massB, ::Oyster::Math::Float radiusSquared )
{ {
return g * massA * massB / radiusSquared; return g * massB / radiusSquared;
} }
/****************************************************************** /******************************************************************

View File

@ -51,12 +51,19 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength )
// updating the linear // updating the linear
//Decrease momentum with 1% as "fall-off" //Decrease momentum with 1% as "fall-off"
//! HACK: @todo Add real solution with fluid drag //! HACK: @todo Add real solution with fluid drag
this->momentum_Linear = this->momentum_Linear*0.9999f; //this->momentum_Linear = this->momentum_Linear*0.99f;
this->momentum_Angular = this->momentum_Angular*0.9999f; //this->momentum_Angular = this->momentum_Angular*0.99f;
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G // ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); Float3 delta = AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
Float3 newPos = ( updateFrameLength)*this->momentum_Linear;
this->centerPos += newPos;
if(this->mass == 70)
{
const char *breakpoint = "STOP";
}
// updating the angular // updating the angular
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H // dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
this->axis += updateFrameLength * this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, AverageWithDelta(this->momentum_Angular, this->impulse_Angular) ); this->axis += updateFrameLength * this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, AverageWithDelta(this->momentum_Angular, this->impulse_Angular) );