Merge remote-tracking branch 'origin/Physics' into GameLogic
This commit is contained in:
commit
467cf1eb68
|
@ -134,7 +134,7 @@ void Octree::Visit(const Oyster::Collision3D::ICollideable& collideable, Visitor
|
||||||
{
|
{
|
||||||
if(collideable.Intersects(this->leafData[i].container))
|
if(collideable.Intersects(this->leafData[i].container))
|
||||||
{
|
{
|
||||||
hitAction(*this, i);
|
hitAction( this->GetCustomBody(i) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Oyster
|
||||||
static const unsigned int invalid_ref;
|
static const unsigned int invalid_ref;
|
||||||
|
|
||||||
typedef void(*VisitorAction)(Octree&, unsigned int, unsigned int);
|
typedef void(*VisitorAction)(Octree&, unsigned int, unsigned int);
|
||||||
typedef void(*VisitorActionCollideable)(Octree&, unsigned int);
|
typedef void(*VisitorActionCollideable)(ICustomBody*);
|
||||||
|
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
|
|
|
@ -94,9 +94,14 @@ namespace
|
||||||
// proto->Predict( forwardedDeltaPos, forwardedDeltaAxis, bounceLinearImpulse, bounceAngularImpulse, API_instance.GetFrameTimeLength() );
|
// proto->Predict( forwardedDeltaPos, forwardedDeltaAxis, bounceLinearImpulse, bounceAngularImpulse, API_instance.GetFrameTimeLength() );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// protoState.ApplyForwarding( forwardedDeltaPos, forwardedDeltaAxis );
|
// protoState.ApplyForwarding( forwardedDeltaPos, forwardedDeltaAxis );
|
||||||
protoState.ApplyImpulse( bounce, worldPointOfContact, normal );
|
protoState.ApplyImpulse( bounce, worldPointOfContact, normal );
|
||||||
proto->SetState( protoState );
|
proto->SetState( protoState );
|
||||||
|
|
||||||
|
proto->CallSubscription_CollisionResponse( deuter, protoState.GetLinearMomentum().GetMagnitude()/(protoState.GetMass() + protoState.GetLinearMomentum().GetMagnitude()));
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +273,7 @@ void API_Impl::RemoveGravity( const API::Gravity &g )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void(hitAction)(Octree&, unsigned int) )
|
void API_Impl::ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void(hitAction)(ICustomBody*) )
|
||||||
{
|
{
|
||||||
this->worldScene.Visit(collideable, hitAction);
|
this->worldScene.Visit(collideable, hitAction);
|
||||||
}
|
}
|
||||||
|
@ -381,6 +386,11 @@ namespace Oyster { namespace Physics
|
||||||
return ::Oyster::Physics::ICustomBody::SubscriptMessage_none;
|
return ::Oyster::Physics::ICustomBody::SubscriptMessage_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventAction_CollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss )
|
||||||
|
{ /* Do nothing except returning business as usual. */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void EventAction_Move( const ::Oyster::Physics::ICustomBody *object )
|
void EventAction_Move( const ::Oyster::Physics::ICustomBody *object )
|
||||||
{ /* Do nothing. */ }
|
{ /* Do nothing. */ }
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace Oyster
|
||||||
void AddGravity( const API::Gravity &g );
|
void AddGravity( const API::Gravity &g );
|
||||||
void RemoveGravity( const API::Gravity &g );
|
void RemoveGravity( const API::Gravity &g );
|
||||||
|
|
||||||
void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void(hitAction)(Octree&, unsigned int) );
|
void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void(hitAction)(ICustomBody*) );
|
||||||
|
|
||||||
//void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
|
//void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ namespace Oyster
|
||||||
{
|
{
|
||||||
void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto );
|
void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto );
|
||||||
::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_Collision( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter );
|
::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_Collision( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter );
|
||||||
|
void EventAction_CollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss );
|
||||||
void EventAction_Move( const ::Oyster::Physics::ICustomBody *object );
|
void EventAction_Move( const ::Oyster::Physics::ICustomBody *object );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ SimpleRigidBody::SimpleRigidBody()
|
||||||
this->rigid.SetMass_KeepMomentum( 16.0f );
|
this->rigid.SetMass_KeepMomentum( 16.0f );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->onCollision = Default::EventAction_Collision;
|
this->onCollision = Default::EventAction_Collision;
|
||||||
|
this->onCollisionResponse = Default::EventAction_CollisionResponse;
|
||||||
this->onMovement = Default::EventAction_Move;
|
this->onMovement = Default::EventAction_Move;
|
||||||
this->scene = nullptr;
|
this->scene = nullptr;
|
||||||
this->customTag = nullptr;
|
this->customTag = nullptr;
|
||||||
|
@ -74,6 +75,15 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
||||||
this->onCollision = Default::EventAction_Collision;
|
this->onCollision = Default::EventAction_Collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( desc.subscription_onCollisionResponse )
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = desc.subscription_onCollisionResponse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = Default::EventAction_CollisionResponse;
|
||||||
|
}
|
||||||
|
|
||||||
if( desc.subscription_onMovement )
|
if( desc.subscription_onMovement )
|
||||||
{
|
{
|
||||||
this->onMovement= desc.subscription_onMovement;
|
this->onMovement= desc.subscription_onMovement;
|
||||||
|
@ -158,6 +168,11 @@ ICustomBody::SubscriptMessage SimpleRigidBody::CallSubscription_Collision( const
|
||||||
return this->onCollision( this, deuter );
|
return this->onCollision( this, deuter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SimpleRigidBody::CallSubscription_CollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss )
|
||||||
|
{
|
||||||
|
return this->onCollisionResponse( this, deuter, kineticEnergyLoss );
|
||||||
|
}
|
||||||
|
|
||||||
void SimpleRigidBody::CallSubscription_Move()
|
void SimpleRigidBody::CallSubscription_Move()
|
||||||
{
|
{
|
||||||
this->onMovement( this );
|
this->onMovement( this );
|
||||||
|
@ -315,6 +330,18 @@ void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Collision functi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_CollisionResponse functionPointer )
|
||||||
|
{
|
||||||
|
if( functionPointer )
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = functionPointer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = Default::EventAction_CollisionResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Move functionPointer )
|
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Move functionPointer )
|
||||||
{
|
{
|
||||||
if( functionPointer )
|
if( functionPointer )
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace Oyster { namespace Physics
|
||||||
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
||||||
|
|
||||||
SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter );
|
SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter );
|
||||||
|
void CallSubscription_CollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss );
|
||||||
void CallSubscription_Move();
|
void CallSubscription_Move();
|
||||||
|
|
||||||
bool IsAffectedByGravity() const;
|
bool IsAffectedByGravity() const;
|
||||||
|
@ -44,6 +45,7 @@ namespace Oyster { namespace Physics
|
||||||
void SetScene( void *scene );
|
void SetScene( void *scene );
|
||||||
|
|
||||||
void SetSubscription( EventAction_Collision functionPointer );
|
void SetSubscription( EventAction_Collision functionPointer );
|
||||||
|
void SetSubscription( EventAction_CollisionResponse functionPointer );
|
||||||
void SetSubscription( EventAction_Move functionPointer );
|
void SetSubscription( EventAction_Move functionPointer );
|
||||||
|
|
||||||
void SetGravity( bool ignore);
|
void SetGravity( bool ignore);
|
||||||
|
@ -64,6 +66,7 @@ namespace Oyster { namespace Physics
|
||||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
EventAction_Collision onCollision;
|
EventAction_Collision onCollision;
|
||||||
|
EventAction_CollisionResponse onCollisionResponse;
|
||||||
EventAction_Move onMovement;
|
EventAction_Move onMovement;
|
||||||
Octree *scene;
|
Octree *scene;
|
||||||
void *customTag;
|
void *customTag;
|
||||||
|
|
|
@ -14,6 +14,7 @@ SphericalRigidBody::SphericalRigidBody()
|
||||||
this->rigid.SetMass_KeepMomentum( 10.0f );
|
this->rigid.SetMass_KeepMomentum( 10.0f );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->onCollision = Default::EventAction_Collision;
|
this->onCollision = Default::EventAction_Collision;
|
||||||
|
this->onCollisionResponse = Default::EventAction_CollisionResponse;
|
||||||
this->onMovement = Default::EventAction_Move;
|
this->onMovement = Default::EventAction_Move;
|
||||||
this->scene = nullptr;
|
this->scene = nullptr;
|
||||||
this->customTag = nullptr;
|
this->customTag = nullptr;
|
||||||
|
@ -42,6 +43,15 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des
|
||||||
this->onCollision = Default::EventAction_Collision;
|
this->onCollision = Default::EventAction_Collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( desc.subscription_onCollisionResponse )
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = desc.subscription_onCollisionResponse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = Default::EventAction_CollisionResponse;
|
||||||
|
}
|
||||||
|
|
||||||
if( desc.subscription_onMovement )
|
if( desc.subscription_onMovement )
|
||||||
{
|
{
|
||||||
this->onMovement= desc.subscription_onMovement;
|
this->onMovement= desc.subscription_onMovement;
|
||||||
|
@ -123,6 +133,12 @@ ICustomBody::SubscriptMessage SphericalRigidBody::CallSubscription_Collision( co
|
||||||
return this->onCollision( this, deuter );
|
return this->onCollision( this, deuter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SphericalRigidBody::CallSubscription_CollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss )
|
||||||
|
{
|
||||||
|
this->onCollisionResponse( this, deuter, kineticEnergyLoss);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SphericalRigidBody::CallSubscription_Move()
|
void SphericalRigidBody::CallSubscription_Move()
|
||||||
{
|
{
|
||||||
this->onMovement( this );
|
this->onMovement( this );
|
||||||
|
@ -234,6 +250,18 @@ void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision fun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_CollisionResponse functionPointer )
|
||||||
|
{
|
||||||
|
if( functionPointer )
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = functionPointer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->onCollisionResponse = Default::EventAction_CollisionResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Move functionPointer )
|
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Move functionPointer )
|
||||||
{
|
{
|
||||||
if( functionPointer )
|
if( functionPointer )
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace Oyster { namespace Physics
|
||||||
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
||||||
|
|
||||||
SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter );
|
SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter );
|
||||||
|
void CallSubscription_CollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss );
|
||||||
void CallSubscription_Move();
|
void CallSubscription_Move();
|
||||||
|
|
||||||
bool IsAffectedByGravity() const;
|
bool IsAffectedByGravity() const;
|
||||||
|
@ -45,6 +46,7 @@ namespace Oyster { namespace Physics
|
||||||
void SetScene( void *scene );
|
void SetScene( void *scene );
|
||||||
|
|
||||||
void SetSubscription( EventAction_Collision functionPointer );
|
void SetSubscription( EventAction_Collision functionPointer );
|
||||||
|
void SetSubscription( EventAction_CollisionResponse functionPointer );
|
||||||
void SetSubscription( EventAction_Move functionPointer );
|
void SetSubscription( EventAction_Move functionPointer );
|
||||||
|
|
||||||
void SetGravity( bool ignore);
|
void SetGravity( bool ignore);
|
||||||
|
@ -65,6 +67,7 @@ namespace Oyster { namespace Physics
|
||||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
EventAction_Collision onCollision;
|
EventAction_Collision onCollision;
|
||||||
|
EventAction_CollisionResponse onCollisionResponse;
|
||||||
EventAction_Move onMovement;
|
EventAction_Move onMovement;
|
||||||
Octree *scene;
|
Octree *scene;
|
||||||
void *customTag;
|
void *customTag;
|
||||||
|
|
|
@ -16,7 +16,6 @@ namespace Oyster
|
||||||
{
|
{
|
||||||
class API;
|
class API;
|
||||||
class ICustomBody;
|
class ICustomBody;
|
||||||
class Octree;
|
|
||||||
|
|
||||||
namespace Struct
|
namespace Struct
|
||||||
{
|
{
|
||||||
|
@ -137,7 +136,12 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual void RemoveGravity( const API::Gravity &g ) = 0;
|
virtual void RemoveGravity( const API::Gravity &g ) = 0;
|
||||||
|
|
||||||
virtual void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void(hitAction)(Octree&, unsigned int) ) = 0;
|
/********************************************************
|
||||||
|
* Applies an effect to objects that collide with the set volume.
|
||||||
|
* @param collideable: An ICollideable that defines the volume of the effect.
|
||||||
|
* @param hitAction: A function that contains the effect.
|
||||||
|
********************************************************/
|
||||||
|
virtual void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void(hitAction)(ICustomBody*) ) = 0;
|
||||||
|
|
||||||
///********************************************************
|
///********************************************************
|
||||||
// * Apply force on an object.
|
// * Apply force on an object.
|
||||||
|
@ -234,6 +238,7 @@ namespace Oyster
|
||||||
enum SubscriptMessage
|
enum SubscriptMessage
|
||||||
{
|
{
|
||||||
SubscriptMessage_none,
|
SubscriptMessage_none,
|
||||||
|
SubscriptMessage_kineticLoss,
|
||||||
SubscriptMessage_ignore_collision_response
|
SubscriptMessage_ignore_collision_response
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -257,6 +262,11 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter ) = 0;
|
virtual SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter ) = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* @todo TODO: need doc
|
||||||
|
********************************************************/
|
||||||
|
virtual void CallSubscription_CollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* @todo TODO: need doc
|
* @todo TODO: need doc
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
@ -387,6 +397,13 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual void SetSubscription( EventAction_Collision functionPointer ) = 0;
|
virtual void SetSubscription( EventAction_Collision functionPointer ) = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* Sets the function that will be called by the engine
|
||||||
|
* whenever a collision has finished.
|
||||||
|
* @param functionPointer: If NULL, an empty default function will be set.
|
||||||
|
********************************************************/
|
||||||
|
virtual void SetSubscription( EventAction_CollisionResponse functionPointer ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Sets the function that will be called by the engine
|
* Sets the function that will be called by the engine
|
||||||
* whenever an object have moved.
|
* whenever an object have moved.
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace Oyster
|
||||||
this->frictionCoeff_Static = 0.5f;
|
this->frictionCoeff_Static = 0.5f;
|
||||||
this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
|
this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
|
||||||
this->subscription_onCollision = NULL;
|
this->subscription_onCollision = NULL;
|
||||||
|
this->subscription_onCollisionResponse = NULL;
|
||||||
this->subscription_onMovement = NULL;
|
this->subscription_onMovement = NULL;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = false;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +36,7 @@ namespace Oyster
|
||||||
this->frictionCoeff_Dynamic = 0.5f;
|
this->frictionCoeff_Dynamic = 0.5f;
|
||||||
this->frictionCoeff_Static = 0.5f;
|
this->frictionCoeff_Static = 0.5f;
|
||||||
this->subscription_onCollision = NULL;
|
this->subscription_onCollision = NULL;
|
||||||
|
this->subscription_onCollisionResponse = NULL;
|
||||||
this->subscription_onMovement = NULL;
|
this->subscription_onMovement = NULL;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace Oyster { namespace Physics
|
||||||
::Oyster::Math::Float frictionCoeff_Dynamic;
|
::Oyster::Math::Float frictionCoeff_Dynamic;
|
||||||
::Oyster::Math::Float4x4 inertiaTensor;
|
::Oyster::Math::Float4x4 inertiaTensor;
|
||||||
::Oyster::Physics::ICustomBody::EventAction_Collision subscription_onCollision;
|
::Oyster::Physics::ICustomBody::EventAction_Collision subscription_onCollision;
|
||||||
|
::Oyster::Physics::ICustomBody::EventAction_CollisionResponse subscription_onCollisionResponse;
|
||||||
::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement;
|
::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement;
|
||||||
bool ignoreGravity;
|
bool ignoreGravity;
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ namespace Oyster { namespace Physics
|
||||||
::Oyster::Math::Float frictionCoeff_Static;
|
::Oyster::Math::Float frictionCoeff_Static;
|
||||||
::Oyster::Math::Float frictionCoeff_Dynamic;
|
::Oyster::Math::Float frictionCoeff_Dynamic;
|
||||||
::Oyster::Physics::ICustomBody::EventAction_Collision subscription_onCollision;
|
::Oyster::Physics::ICustomBody::EventAction_Collision subscription_onCollision;
|
||||||
|
::Oyster::Physics::ICustomBody::EventAction_CollisionResponse subscription_onCollisionResponse;
|
||||||
::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement;
|
::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement;
|
||||||
bool ignoreGravity;
|
bool ignoreGravity;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue