Leviathan  0.8.0.0
Leviathan game engine
Leviathan::Physics Class Reference

Entity has a physical component. More...

#include <Components.h>

+ Inheritance diagram for Leviathan::Physics:

Classes

class  ApplyForceInfo
 Holder for information regarding a single force. More...
 
struct  BasePhysicsData
 
struct  Data
 

Public Member Functions

 Physics (const Data &args)
 
DLLEXPORT ~Physics ()
 
DLLEXPORT void Release ()
 Destroys the physical body. More...
 
DLLEXPORT bool SetCollision (NewtonCollision *collision)
 Sets collision when body hasn't been created yet. More...
 
DLLEXPORT NewtonBody * CreatePhysicsBody (PhysicalWorld *world, int physicsmaterialid=-1)
 Use this to create a body for this component once Collision is set. More...
 
DLLEXPORT void GiveImpulse (const Float3 &deltaspeed, const Float3 &point=Float3(0))
 
DLLEXPORT void ApplyForce (ApplyForceInfo *pointertohandle)
 Adds an apply force. More...
 
DLLEXPORT bool RemoveApplyForce (const std::string &name)
 Removes an existing ApplyForce. More...
 
DLLEXPORT void AddForce (const Float3 &force)
 Add force to the object. More...
 
DLLEXPORT void SetVelocity (const Float3 &velocities)
 Overrides this objects velocity in ApplyForceAndTorqueEvent. More...
 
DLLEXPORT void ClearVelocity ()
 Clears velocity and last frame forces (but not the applied force list) More...
 
DLLEXPORT Float3 GetVelocity () const
 Gets the absolute velocity. More...
 
DLLEXPORT Float3 GetOmega () const
 Gets the omega (angular velocity) More...
 
DLLEXPORT void SetOmega (const Float3 &velocities)
 Sets the omega. More...
 
DLLEXPORT void AddOmega (const Float3 &velocities)
 Add to the omega. More...
 
DLLEXPORT void AddTorque (const Float3 &torque)
 Adds torque to the object. More...
 
DLLEXPORT void SetTorque (const Float3 &torque)
 Overrides this object's torque in ApplyForceAndTorqueEvent. More...
 
DLLEXPORT Float3 GetTorque () const
 Gets the torque of the body (rotational velocity) More...
 
DLLEXPORT void SetPhysicalMaterialID (int ID)
 Sets the physical material ID of this object. More...
 
DLLEXPORT void SetLinearDamping (float factor=0.1f)
 Sets the linear dampening which slows down the object. More...
 
DLLEXPORT void SetAngularDamping (const Float3 &factor=Float3(0.1f))
 Sets the angular damping. More...
 
DLLEXPORT void ApplyPhysicalState (const BasePhysicsData &data)
 Applies physical state from holder object. More...
 
DLLEXPORT void JumpTo (Position &target)
 Syncs this physics body to a changed position. More...
 
DLLEXPORT bool SetPosition (const Float3 &pos, const Float4 &orientation)
 Moves the physical body to the specified position. More...
 
DLLEXPORT bool SetOnlyOrientation (const Float4 &orientation)
 Same as SetPosition but only sets orientation. More...
 
DLLEXPORT Ogre::Matrix4 GetFullMatrix () const
 Returns the full matrix representing this body's position and rotation. More...
 
DLLEXPORT void SetMass (float mass)
 Calculates the mass matrix and applies the mass parameter to the body. More...
 
DLLEXPORT bool CreatePlaneConstraint (PhysicalWorld *world, const Float3 &planenormal=Float3(0, 1, 0))
 Adds a constraint to the current Body to only move in place. More...
 
 REFERENCE_HANDLE_UNCOUNTED_TYPE (Physics)
 
Float3 _GatherApplyForces (const float &mass)
 Adds all applied forces together. More...
 
DLLEXPORT float GetMass () const
 
NewtonBody * GetBody () const
 
NewtonCollision * GetCollision () const
 
- Public Member Functions inherited from Leviathan::Component
 Component (COMPONENT_TYPE type)
 
 Component (const Component &)=delete
 
Componentoperator= (const Component &)=delete
 

Static Public Member Functions

static void ApplyForceAndTorqueEvent (const NewtonBody *const body, dFloat timestep, int threadIndex)
 
static void DestroyBodyCallback (const NewtonBody *body)
 
static void PhysicsMovedEvent (const NewtonBody *const body, const dFloat *const matrix, int threadIndex)
 

Public Attributes

GameWorldWorld = nullptr
 Used to access gravity data. More...
 
Position_Position
 Physics object requires a position. More...
 
const ObjectID ThisEntity
 For access from physics callbacks. More...
 
SendableUpdateSendable = nullptr
 
- Public Attributes inherited from Leviathan::Component
bool Marked
 
const COMPONENT_TYPE Type
 Type of this component, used for network serialization. More...
 

Static Public Attributes

static constexpr auto TYPE = COMPONENT_TYPE::Physics
 

Detailed Description

Entity has a physical component.

Precondition
Entity has Position component
Todo:
Global Newton lock

Definition at line 319 of file Components.h.

Constructor & Destructor Documentation

◆ Physics()

Leviathan::Physics::Physics ( const Data args)
inline

Definition at line 386 of file Components.h.

386  :
387  Component(TYPE), World(args.world), _Position(args.updatepos), ThisEntity(args.id),
388  UpdateSendable(args.updatesendable)
389  {
390  }
Component(COMPONENT_TYPE type)
Definition: Component.h:55
static constexpr auto TYPE
Definition: Components.h:562
const ObjectID ThisEntity
For access from physics callbacks.
Definition: Components.h:556
Sendable * UpdateSendable
Definition: Components.h:560
GameWorld * World
Used to access gravity data.
Definition: Components.h:550
Position & _Position
Physics object requires a position.
Definition: Components.h:553

◆ ~Physics()

DLLEXPORT Physics::~Physics ( )

Definition at line 87 of file Components.cpp.

88 {
89  if(Body) {
90  LOG_ERROR("Physics: Release not called before destructor!");
91  Release();
92  }
93 }
#define LOG_ERROR(x)
Definition: Define.h:83
DLLEXPORT void Release()
Destroys the physical body.
Definition: Components.cpp:95

Member Function Documentation

◆ _GatherApplyForces()

Float3 Physics::_GatherApplyForces ( const float &  mass)

Adds all applied forces together.

Definition at line 498 of file Components.cpp.

499 {
500  // Return if just an empty list //
501  if(ApplyForceList.empty())
502  return Float3(0);
503 
504  Float3 total(0);
505 
506  for(auto iter = ApplyForceList.begin(); iter != ApplyForceList.end(); ++iter) {
507  // Add to total, and multiply by mass if wanted //
508  const Float3 force = (*iter)->Callback((*iter).get(), *this);
509 
510  total += (*iter)->MultiplyByMass ? force * mass : force;
511 
512  // We might assert/crash here if the force was removed //
513  }
514 
515  return total;
516 }

◆ AddForce()

DLLEXPORT void Physics::AddForce ( const Float3 force)

Add force to the object.

Note
This is applied in ApplyForceAndTorqueEvent

Definition at line 332 of file Components.cpp.

333 {
334  // Safety check. Can be disabled in release builds if this is a performance issue
335  if(force.HasInvalidValues()) {
336 
337  std::stringstream msg;
338  msg << "AddForce call had at least one value with non-finite value, force: "
339  << Convert::ToString(force);
340  LOG_ERROR("Physics: " + msg.str());
341  throw InvalidArgument(msg.str());
342  }
343 
344  SumQueuedForce += force;
345 }
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ AddOmega()

DLLEXPORT void Physics::AddOmega ( const Float3 velocities)

Add to the omega.

Definition at line 414 of file Components.cpp.

415 {
416  if(!Body)
417  throw InvalidState("Physics object doesn't have a body");
418 
419  // Safety check. Can be disabled in release builds if this is a performance issue
420  if(velocities.HasInvalidValues()) {
421 
422  std::stringstream msg;
423  msg << "AddOmega call had at least one value with non-finite value, velocities: "
424  << Convert::ToString(velocities);
425  LOG_ERROR("Physics: " + msg.str());
426  throw InvalidArgument(msg.str());
427  }
428 
429  Float3 temp;
430  NewtonBodyGetOmega(Body, &temp.X);
431  temp += velocities;
432  NewtonBodySetOmega(Body, &temp.X);
433 }
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ AddTorque()

DLLEXPORT void Physics::AddTorque ( const Float3 torque)

Adds torque to the object.

Note
This is applied in ApplyForceAndTorqueEvent

Definition at line 445 of file Components.cpp.

446 {
447  // Safety check. Can be disabled in release builds if this is a performance issue
448  if(torque.HasInvalidValues()) {
449 
450  std::stringstream msg;
451  msg << "AddTorque call had at least one value with non-finite value, torque: "
452  << Convert::ToString(torque);
453  LOG_ERROR("Physics: " + msg.str());
454  throw InvalidArgument(msg.str());
455  }
456 
457  if(TorqueOverride) {
458 
459  SumQueuedTorque = Float3(0, 0, 0);
460  TorqueOverride = false;
461  }
462 
463  SumQueuedTorque += torque;
464 }
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ ApplyForce()

DLLEXPORT void Physics::ApplyForce ( ApplyForceInfo pointertohandle)

Adds an apply force.

Note
Overwrites old forces with the same name
Parameters
pointertohandlePointer to the force which will be deleted by this

Definition at line 518 of file Components.cpp.

519 {
520  // Overwrite old if found //
521  for(auto iter = ApplyForceList.begin(); iter != ApplyForceList.end(); ++iter) {
522 
523  // Check do the names match //
524  if((bool)(*iter)->OptionalName == (bool)pointertohandle->OptionalName) {
525 
526  if(!pointertohandle->OptionalName ||
527  *pointertohandle->OptionalName == *(*iter)->OptionalName) {
528  // it's the default, overwrite //
529  **iter = *pointertohandle;
530  SAFE_DELETE(pointertohandle);
531  return;
532  }
533  }
534  }
535  // got here, so add a new one //
536  ApplyForceList.push_back(std::shared_ptr<ApplyForceInfo>(pointertohandle));
537 }
#define SAFE_DELETE(x)
Definition: Define.h:116

◆ ApplyForceAndTorqueEvent()

void Physics::ApplyForceAndTorqueEvent ( const NewtonBody *const  body,
dFloat  timestep,
int  threadIndex 
)
static

Definition at line 227 of file Components.cpp.

229 {
230  // Get object from body //
231  Physics* tmp = static_cast<Physics*>(NewtonBodyGetUserData(body));
232 
233  // Check if physics can't apply //
234  // Newton won't call this if the mass is 0
235 
236  Float3 Torque = tmp->SumQueuedTorque;
237 
238  // Get properties from newton //
239  float mass;
240  float Ixx;
241  float Iyy;
242  float Izz;
243 
244  NewtonBodyGetMass(body, &mass, &Ixx, &Iyy, &Izz);
245 
246  Float3 Force = tmp->SumQueuedForce;
247 
248  // get gravity force and apply mass to it //
249  if(tmp->ApplyGravity)
250  Force += tmp->World->GetGravityAtPosition(tmp->_Position.Members._Position) * mass;
251 
252  // add other forces //
253  if(!tmp->ApplyForceList.empty()) {
254 
255  Force += tmp->_GatherApplyForces(mass);
256  }
257 
258 #ifdef CHECK_FOR_NANS
259  if(Force.HasInvalidValues()) {
260 
261  LOG_ERROR("Physics::ApplyForceAndTorqueEvent: Force was calculated to have a "
262  "non-finite value in it. Skipping applying");
263 
264  return;
265  }
266 #endif // CHECK_FOR_NANS
267 
268  NewtonBodyAddForce(body, &Force.X);
269 
270  tmp->SumQueuedForce = Float3(0, 0, 0);
271 
272  // Torque applying //
273  Float3 torque;
274 
275  if(tmp->TorqueOverride) {
276 
277  torque = tmp->SumQueuedTorque;
278  tmp->TorqueOverride = false;
279  tmp->SumQueuedTorque = Float3(0, 0, 0);
280 
281  } else {
282 
283  torque = Torque;
284  }
285 
286 
287 #ifdef CHECK_FOR_NANS
288  if(Force.HasInvalidValues()) {
289 
290  LOG_ERROR("Physics::ApplyForceAndTorqueEvent: Torque was calculated to have a "
291  "non-finite value in it. Skipping applying");
292 
293  return;
294  }
295 #endif // CHECK_FOR_NANS
296 
297  NewtonBodyAddTorque(body, &torque.X);
298 }
#define LOG_ERROR(x)
Definition: Define.h:83
DLLEXPORT Float3 GetGravityAtPosition(const Float3 &pos)
Definition: GameWorld.cpp:767
Float3 _GatherApplyForces(const float &mass)
Adds all applied forces together.
Definition: Components.cpp:498
GameWorld * World
Used to access gravity data.
Definition: Components.h:550
Entity has a physical component.
Definition: Components.h:319
Position & _Position
Physics object requires a position.
Definition: Components.h:553
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ ApplyPhysicalState()

DLLEXPORT void Leviathan::Physics::ApplyPhysicalState ( const BasePhysicsData data)

Applies physical state from holder object.

◆ ClearVelocity()

DLLEXPORT void Physics::ClearVelocity ( )

Clears velocity and last frame forces (but not the applied force list)

Definition at line 365 of file Components.cpp.

366 {
367  if(!Body)
368  throw InvalidState("Physics object doesn't have a body");
369 
370  Float3 zeroVector(0, 0, 0);
371  NewtonBodySetVelocity(Body, &zeroVector.X);
372  // Forces are recalculated each physics update so we can't set them here
373  SetTorque(Float3(0, 0, 0));
374 }
DLLEXPORT void SetTorque(const Float3 &torque)
Overrides this object&#39;s torque in ApplyForceAndTorqueEvent.
Definition: Components.cpp:466

◆ CreatePhysicsBody()

DLLEXPORT NewtonBody * Physics::CreatePhysicsBody ( PhysicalWorld world,
int  physicsmaterialid = -1 
)

Use this to create a body for this component once Collision is set.

Parameters
physicsmaterialidRetrieve from the same world with GameWorld::GetPhysicalMaterial. -1 to use default material

Definition at line 566 of file Components.cpp.

568 {
569  if(!world || !Collision)
570  return nullptr;
571 
572  // Destroy old if there is one //
573  if(Body)
574  NewtonDestroyBody(Body);
575 
576  Body = world->CreateBodyFromCollision(Collision);
577 
578  if(!Body)
579  return nullptr;
580 
581  // Add this as user data //
582  NewtonBodySetUserData(Body, this);
583 
584  // Callbacks //
585  NewtonBodySetTransformCallback(Body, Physics::PhysicsMovedEvent);
586 
587  NewtonBodySetForceAndTorqueCallback(Body, Physics::ApplyForceAndTorqueEvent);
588 
589  NewtonBodySetDestructorCallback(Body, Physics::DestroyBodyCallback);
590 
591  // And material //
592  if(physicsmaterialid != -1)
593  NewtonBodySetMaterialGroupID(Body, physicsmaterialid);
594 
595  return Body;
596 }
static void DestroyBodyCallback(const NewtonBody *body)
Definition: Components.cpp:300
static void PhysicsMovedEvent(const NewtonBody *const body, const dFloat *const matrix, int threadIndex)
Definition: Components.cpp:186
DLLEXPORT NewtonBody * CreateBodyFromCollision(NewtonCollision *collision)
static void ApplyForceAndTorqueEvent(const NewtonBody *const body, dFloat timestep, int threadIndex)
Definition: Components.cpp:227

◆ CreatePlaneConstraint()

DLLEXPORT bool Physics::CreatePlaneConstraint ( PhysicalWorld world,
const Float3 planenormal = Float3(0, 1, 0) 
)

Adds a constraint to the current Body to only move in place.

Definition at line 660 of file Components.cpp.

662 {
663  if(!Body || !world)
664  return false;
665 
666  world->Create2DJoint(Body, planenormal);
667  return true;
668 }
DLLEXPORT NewtonJoint * Create2DJoint(NewtonBody *body, const Float3 &planenormal)
Constraints body to a 2d plane of movement specified by its normal.

◆ DestroyBodyCallback()

void Physics::DestroyBodyCallback ( const NewtonBody *  body)
static

Definition at line 300 of file Components.cpp.

301 {
302  // This shouldn't be required as the newton world won't be cleared while running
303  // Physics* tmp = reinterpret_cast<Physics*>(NewtonBodyGetUserData(body));
304  // LOG_INFO("Destroy body callback");
305 
306  // GUARD_LOCK_OTHER(tmp);
307 
308  // tmp->Body = nullptr;
309  // tmp->Collision = nullptr;
310 }

◆ GetBody()

NewtonBody* Leviathan::Physics::GetBody ( ) const
inline

Definition at line 514 of file Components.h.

515  {
516  return Body;
517  }

◆ GetCollision()

NewtonCollision* Leviathan::Physics::GetCollision ( ) const
inline

Definition at line 519 of file Components.h.

520  {
521  return Collision;
522  }

◆ GetFullMatrix()

DLLEXPORT Ogre::Matrix4 Physics::GetFullMatrix ( ) const

Returns the full matrix representing this body's position and rotation.

Definition at line 175 of file Components.cpp.

176 {
177  if(!Body)
178  return Ogre::Matrix4::IDENTITY;
179 
180  float matrix[16];
181  NewtonBodyGetMatrix(Body, &matrix[0]);
182 
183  return NewtonMatrixToOgre(matrix);
184 }
DLLEXPORT Ogre::Matrix4 NewtonMatrixToOgre(const dFloat *const matrix)

◆ GetMass()

DLLEXPORT float Leviathan::Physics::GetMass ( ) const
inline

Definition at line 509 of file Components.h.

510  {
511  return Mass;
512  }

◆ GetOmega()

DLLEXPORT Float3 Physics::GetOmega ( ) const

Gets the omega (angular velocity)

Definition at line 386 of file Components.cpp.

387 {
388  if(!Body)
389  throw InvalidState("Physics object doesn't have a body");
390 
391  Float3 vel(0);
392  NewtonBodyGetOmega(Body, &vel.X);
393  return vel;
394 }

◆ GetTorque()

DLLEXPORT Float3 Physics::GetTorque ( ) const

Gets the torque of the body (rotational velocity)

Definition at line 435 of file Components.cpp.

436 {
437  if(!Body)
438  throw InvalidState("Physics object doesn't have a body");
439 
440  Float3 torq(0);
441  NewtonBodyGetTorque(Body, &torq.X);
442  return torq;
443 }

◆ GetVelocity()

DLLEXPORT Float3 Physics::GetVelocity ( ) const

Gets the absolute velocity.

Definition at line 376 of file Components.cpp.

377 {
378  if(!Body)
379  throw InvalidState("Physics object doesn't have a body");
380 
381  Float3 vel(0);
382  NewtonBodyGetVelocity(Body, &vel.X);
383  return vel;
384 }

◆ GiveImpulse()

DLLEXPORT void Physics::GiveImpulse ( const Float3 deltaspeed,
const Float3 point = Float3(0) 
)
Exceptions
InvalidArgumentif deltaspeed or point has non-finite values

Definition at line 312 of file Components.cpp.

314 {
315  if(!Body)
316  throw InvalidState("Physics object doesn't have a body");
317 
318  // Safety check. Can be disabled in release builds if this is a performance issue
319  if(deltaspeed.HasInvalidValues() || point.HasInvalidValues()) {
320 
321  std::stringstream msg;
322  msg << "GiveImpulse call had at least one value with non-finite value, deltaspeed: "
323  << Convert::ToString(deltaspeed) << " point: " << Convert::ToString(point);
324  LOG_ERROR("Physics: " + msg.str());
325  throw InvalidArgument(msg.str());
326  }
327 
328  // No clue what the delta step should be
329  NewtonBodyAddImpulse(Body, &deltaspeed.X, &point.X, 0.1f);
330 }
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ JumpTo()

DLLEXPORT void Physics::JumpTo ( Position target)

Syncs this physics body to a changed position.

Call after making changes to Position component if you don't want this physics body to overwrite the change on next tick.

Definition at line 106 of file Components.cpp.

107 {
108  SetPosition(target.Members._Position, target.Members._Orientation);
109 }
DLLEXPORT bool SetPosition(const Float3 &pos, const Float4 &orientation)
Moves the physical body to the specified position.
Definition: Components.cpp:111

◆ PhysicsMovedEvent()

void Physics::PhysicsMovedEvent ( const NewtonBody *const  body,
const dFloat *const  matrix,
int  threadIndex 
)
static

Definition at line 186 of file Components.cpp.

188 {
189  // first create Ogre 4x4 matrix from the matrix //
190  Ogre::Matrix4 mat = NewtonMatrixToOgre(matrix);
191 
192  Physics* tmp = static_cast<Physics*>(NewtonBodyGetUserData(body));
193 
194  const auto pos = mat.getTrans();
195 
196  // #ifdef CHECK_FOR_NANS
197  if(!std::isfinite(pos.x)) {
198 
199  LOG_ERROR("Physics::PhysicsMovedEvent: physics body has NaN translation");
200  // Would really like to find a fix instead of this hack
201  if(std::isnan(tmp->_Position.Members._Position.X)) {
202  LOG_ERROR("Even Position.X is NaN");
203  tmp->SetPosition(Float3(0, 0, 0), Ogre::Quaternion::IDENTITY);
204  } else {
205  // Doesn't seem to work
206  // tmp->JumpTo(tmp->_Position);
207  // This doesn't work either
208  tmp->SetPosition(Float3(0, 0, 0), Ogre::Quaternion::IDENTITY);
209  }
210 
211  return;
212  }
213  // #endif // CHECK_FOR_NANS
214 
215  tmp->_Position.Members._Position = pos;
216  tmp->_Position.Members._Orientation = mat.extractQuaternion();
217  tmp->_Position.Marked = true;
218 
219  if(tmp->UpdateSendable) {
220 
221  tmp->UpdateSendable->Marked = true;
222  }
223 
224  tmp->Marked = true;
225 }
#define LOG_ERROR(x)
Definition: Define.h:83
Sendable * UpdateSendable
Definition: Components.h:560
Entity has a physical component.
Definition: Components.h:319
DLLEXPORT Ogre::Matrix4 NewtonMatrixToOgre(const dFloat *const matrix)
Position & _Position
Physics object requires a position.
Definition: Components.h:553
DLLEXPORT bool SetPosition(const Float3 &pos, const Float4 &orientation)
Moves the physical body to the specified position.
Definition: Components.cpp:111

◆ REFERENCE_HANDLE_UNCOUNTED_TYPE()

Leviathan::Physics::REFERENCE_HANDLE_UNCOUNTED_TYPE ( Physics  )

◆ Release()

DLLEXPORT void Physics::Release ( )

Destroys the physical body.

Definition at line 95 of file Components.cpp.

96 {
97  if(Body)
98  NewtonDestroyBody(Body);
99  if(Collision)
100  NewtonDestroyCollision(Collision);
101 
102  Body = NULL;
103  Collision = NULL;
104 }

◆ RemoveApplyForce()

DLLEXPORT bool Physics::RemoveApplyForce ( const std::string &  name)

Removes an existing ApplyForce.

Parameters
namename of force to delete, pass empty std::string to delete the default named force

Definition at line 539 of file Components.cpp.

540 {
541  // Search for a matching name //
542  auto end = ApplyForceList.end();
543  for(auto iter = ApplyForceList.begin(); iter != end; ++iter) {
544 
545  // Check do the names match //
546  if((!((*iter)->OptionalName) && name.size() == 0) ||
547  ((*iter)->OptionalName && *(*iter)->OptionalName == name)) {
548 
549  ApplyForceList.erase(iter);
550  return true;
551  }
552  }
553 
554  return false;
555 }

◆ SetAngularDamping()

DLLEXPORT void Physics::SetAngularDamping ( const Float3 factor = Float3(0.1f))

Sets the angular damping.

Definition at line 490 of file Components.cpp.

491 {
492  if(!Body)
493  throw InvalidState("Physics object doesn't have a body");
494 
495  NewtonBodySetAngularDamping(Body, &factor.X);
496 }

◆ SetCollision()

DLLEXPORT bool Physics::SetCollision ( NewtonCollision *  collision)

Sets collision when body hasn't been created yet.

Definition at line 647 of file Components.cpp.

648 {
649  if(Body)
650  return false;
651 
652  if(Collision)
653  Release();
654 
655  Collision = collision;
656 
657  return true;
658 }
DLLEXPORT void Release()
Destroys the physical body.
Definition: Components.cpp:95

◆ SetLinearDamping()

DLLEXPORT void Physics::SetLinearDamping ( float  factor = 0.1f)

Sets the linear dampening which slows down the object.

Parameters
factorThe factor to set. Must be between 0.f and 1.f. Default is 0.1f
Note
This can be used to set the viscosity of the substance the object is in for example to mimic drag in water (this needs verification...)

More on this in the Newton wiki here: http://newtondynamics.com/wiki/index.php5?title=NewtonBodySetLinearDamping

Definition at line 482 of file Components.cpp.

483 {
484  if(!Body)
485  throw InvalidState("Physics object doesn't have a body");
486 
487  NewtonBodySetLinearDamping(Body, factor);
488 }

◆ SetMass()

DLLEXPORT void Physics::SetMass ( float  mass)

Calculates the mass matrix and applies the mass parameter to the body.

Definition at line 598 of file Components.cpp.

599 {
600  if(!Body)
601  return;
602 
603  // Safety check. Shouldn't be disabled
604  if(!std::isfinite(mass)) {
605 
606  std::stringstream msg;
607  msg << "SetMass mass is invalid value: " << Convert::ToString(mass)
608  << " (use 0 for immovable)";
609  LOG_ERROR("Physics: " + msg.str());
610  throw InvalidArgument(msg.str());
611  }
612 
613  Mass = mass;
614 
615  // First calculate inertia and center of mass points //
616  Float3 inertia;
617  Float3 centerofmass;
618 
619  // TODO: cache this per Collision object
620  NewtonConvexCollisionCalculateInertialMatrix(Collision, &inertia.X, &centerofmass.X);
621 
622  // Apply mass to inertia
623  inertia *= Mass;
624 
625 #ifdef CHECK_FOR_NANS
626 
627  // Doesn't work. Apparently there is a chance to screw up the collision object permanently
628  // if(std::isnan(inertia.X) || std::isnan(inertia.Y) || std::isnan(inertia.Z) ||
629  // std::isnan(centerofmass.X) || std::isnan(centerofmass.Y) ||
630  // std::isnan(centerofmass.Z)) {
631 
632  // LOG_ERROR("Physics: SetMass: failed to calculate collision inertial matrix, "
633  // "trying again");
634  // SetMass(mass);
635  // return;
636  // }
637 
638  inertia.CheckForNans();
639  centerofmass.CheckForNans();
640 
641 #endif // CHECK_FOR_NANS
642 
643  NewtonBodySetMassMatrix(Body, Mass, inertia.X, inertia.Y, inertia.Z);
644  NewtonBodySetCentreOfMass(Body, &centerofmass.X);
645 }
DLLEXPORT void CheckForNans()
Definition: Types.h:677
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72

◆ SetOmega()

DLLEXPORT void Physics::SetOmega ( const Float3 velocities)

Sets the omega.

Definition at line 396 of file Components.cpp.

397 {
398  if(!Body)
399  throw InvalidState("Physics object doesn't have a body");
400 
401  // Safety check. Can be disabled in release builds if this is a performance issue
402  if(velocities.HasInvalidValues()) {
403 
404  std::stringstream msg;
405  msg << "SetOmega call had at least one value with non-finite value, velocities: "
406  << Convert::ToString(velocities);
407  LOG_ERROR("Physics: " + msg.str());
408  throw InvalidArgument(msg.str());
409  }
410 
411  NewtonBodySetOmega(Body, &velocities.X);
412 }
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ SetOnlyOrientation()

DLLEXPORT bool Physics::SetOnlyOrientation ( const Float4 orientation)

Same as SetPosition but only sets orientation.

Definition at line 140 of file Components.cpp.

141 {
142  if(!Body)
143  return false;
144 
145  // Safety check. Can be disabled in release builds if this is a performance issue
146  if(orientation.HasInvalidValues()) {
147 
148  std::stringstream msg;
149  msg << "SetOnlyOrientation call had at least one value with non-finite value, "
150  "orientation: "
151  << Convert::ToString(orientation);
152  LOG_ERROR("Physics: " + msg.str());
153  throw InvalidArgument(msg.str());
154  }
155 
156  float newtonMatrix[16];
157  NewtonBodyGetMatrix(Body, &newtonMatrix[0]);
158 
159  const auto pos = ExtractNewtonMatrixTranslation(newtonMatrix);
160 
161  Ogre::Matrix4 matrix;
162 
163  Ogre::Vector3 ogrepos = pos;
164  Ogre::Quaternion ogrerot = orientation;
165  matrix.makeTransform(ogrepos, Float3(1, 1, 1), ogrerot);
166 
167  Ogre::Matrix4 tmatrix = PrepareOgreMatrixForNewton(matrix);
168 
169  // Update body //
170  NewtonBodySetMatrix(Body, &tmatrix[0][0]);
171 
172  return true;
173 }
#define LOG_ERROR(x)
Definition: Define.h:83
DLLEXPORT Float3 ExtractNewtonMatrixTranslation(const float(&matrix)[16])
Grabs the translation from a newton matrix without transposing.
DLLEXPORT Ogre::Matrix4 PrepareOgreMatrixForNewton(const Ogre::Matrix4 &matrix)
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:1015
static std::string ToString(const T &val)
Definition: Convert.h:72

◆ SetPhysicalMaterialID()

DLLEXPORT void Physics::SetPhysicalMaterialID ( int  ID)

Sets the physical material ID of this object.

Note
You have to fetch the ID from the world's corresponding PhysicalMaterialManager

Definition at line 557 of file Components.cpp.

558 {
559  if(!Body) {
560  throw InvalidState("Calling set material ID without having physical Body");
561  }
562 
563  NewtonBodySetMaterialGroupID(Body, ID);
564 }

◆ SetPosition()

DLLEXPORT bool Physics::SetPosition ( const Float3 pos,
const Float4 orientation 
)

Moves the physical body to the specified position.

Returns
False if this fails because there currently is no physics body for this component
Exceptions
InvalidArgumentif pos or orientation has non-finite values

Definition at line 111 of file Components.cpp.

112 {
113  if(!Body)
114  return false;
115 
116  // Safety check. Can be disabled in release builds if this is a performance issue
117  if(pos.HasInvalidValues() || orientation.HasInvalidValues()) {
118 
119  std::stringstream msg;
120  msg << "SetPosition call had at least one value with non-finite value, pos: "
121  << Convert::ToString(pos) << " orientation: " << Convert::ToString(orientation);
122  LOG_ERROR("Physics: " + msg.str());
123  throw InvalidArgument(msg.str());
124  }
125 
126  Ogre::Matrix4 matrix;
127 
128  Ogre::Vector3 ogrepos = pos;
129  Ogre::Quaternion ogrerot = orientation;
130  matrix.makeTransform(ogrepos, Float3(1, 1, 1), ogrerot);
131 
132  Ogre::Matrix4 tmatrix = PrepareOgreMatrixForNewton(matrix);
133 
134  // Update body //
135  NewtonBodySetMatrix(Body, &tmatrix[0][0]);
136 
137  return true;
138 }
#define LOG_ERROR(x)
Definition: Define.h:83
DLLEXPORT Ogre::Matrix4 PrepareOgreMatrixForNewton(const Ogre::Matrix4 &matrix)
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:1015
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ SetTorque()

DLLEXPORT void Physics::SetTorque ( const Float3 torque)

Overrides this object's torque in ApplyForceAndTorqueEvent.

Definition at line 466 of file Components.cpp.

467 {
468  // Safety check. Can be disabled in release builds if this is a performance issue
469  if(torque.HasInvalidValues()) {
470 
471  std::stringstream msg;
472  msg << "SetTorque call had at least one value with non-finite value, torque: "
473  << Convert::ToString(torque);
474  LOG_ERROR("Physics: " + msg.str());
475  throw InvalidArgument(msg.str());
476  }
477 
478  SumQueuedTorque = torque;
479  TorqueOverride = true;
480 }
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

◆ SetVelocity()

DLLEXPORT void Physics::SetVelocity ( const Float3 velocities)

Overrides this objects velocity in ApplyForceAndTorqueEvent.

Definition at line 347 of file Components.cpp.

348 {
349  if(!Body)
350  throw InvalidState("Physics object doesn't have a body");
351 
352  // Safety check. Can be disabled in release builds if this is a performance issue
353  if(velocities.HasInvalidValues()) {
354 
355  std::stringstream msg;
356  msg << "SetVelocity call had at least one value with non-finite value, velocities: "
357  << Convert::ToString(velocities);
358  LOG_ERROR("Physics: " + msg.str());
359  throw InvalidArgument(msg.str());
360  }
361 
362  NewtonBodySetVelocity(Body, &velocities.X);
363 }
#define LOG_ERROR(x)
Definition: Define.h:83
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT bool HasInvalidValues() const
Definition: Types.h:668

Member Data Documentation

◆ _Position

Position& Leviathan::Physics::_Position

Physics object requires a position.

Definition at line 553 of file Components.h.

◆ ThisEntity

const ObjectID Leviathan::Physics::ThisEntity

For access from physics callbacks.

Definition at line 556 of file Components.h.

◆ TYPE

constexpr auto Leviathan::Physics::TYPE = COMPONENT_TYPE::Physics
static

Definition at line 562 of file Components.h.

◆ UpdateSendable

Sendable* Leviathan::Physics::UpdateSendable = nullptr

Definition at line 560 of file Components.h.

◆ World

GameWorld* Leviathan::Physics::World = nullptr

Used to access gravity data.

Definition at line 550 of file Components.h.


The documentation for this class was generated from the following files: