Merge branch 'main' into PlayerController

This commit is contained in:
Glence 2023-03-09 13:44:49 +08:00
commit 63360a4616
2 changed files with 35 additions and 11 deletions

View File

@ -274,6 +274,7 @@ namespace SHADE
// Invert the inertia // Invert the inertia
for (size_t i = 0; i < SHVec3::SIZE; ++i) for (size_t i = 0; i < SHVec3::SIZE; ++i)
localInvInertia[i] = 1.0f / localInvInertia[i]; localInvInertia[i] = 1.0f / localInvInertia[i];
// Build raycast layer from colliders. If none exist....then this never stops simulating technically. // Build raycast layer from colliders. If none exist....then this never stops simulating technically.
@ -297,16 +298,17 @@ namespace SHADE
raycastInfo.continuous = false; raycastInfo.continuous = false;
raycastInfo.layers = raycastLayers; raycastInfo.layers = raycastLayers;
bool terminate = true; bool terminate = true;
int iterationCounter = simInfo.maxSteps;
do do
{ {
raycastInfo.distance = linearVelocity.Length(); raycastInfo.distance = linearVelocity.Length();
raycastInfo.ray.position = bodyPosition; raycastInfo.ray.position = bodyPosition;
raycastInfo.ray.direction = SHVec3::Normalise(linearVelocity); raycastInfo.ray.direction = SHVec3::Normalise(linearVelocity);
terminate = !Raycast(raycastInfo).empty(); terminate = !Raycast(raycastInfo).empty() || iterationCounter == 0;
if (terminate) if (terminate)
break; return;
// Compute world space data // Compute world space data
const SHMatrix R = SHMatrix::Rotate(bodyOrientation); const SHMatrix R = SHMatrix::Rotate(bodyOrientation);
@ -348,7 +350,7 @@ namespace SHADE
const SHQuaternion QV = SHQuaternion{ angularVelocity.x * simInfo.timeStep, angularVelocity.y * simInfo.timeStep, angularVelocity.z * simInfo.timeStep, 0.0f } * 0.5f; const SHQuaternion QV = SHQuaternion{ angularVelocity.x * simInfo.timeStep, angularVelocity.y * simInfo.timeStep, angularVelocity.z * simInfo.timeStep, 0.0f } * 0.5f;
bodyPosition += linearVelocity * simInfo.timeStep; bodyPosition += linearVelocity * simInfo.timeStep;
bodyOrientation += bodyOrientation * QV; bodyOrientation += bodyOrientation * QV * SHQuaternion::FromEuler(ANGULAR_LOCK);
bodyOrientation = SHQuaternion::Normalise(bodyOrientation); bodyOrientation = SHQuaternion::Normalise(bodyOrientation);
// Clear forces after the first frame // Clear forces after the first frame
@ -362,6 +364,8 @@ namespace SHADE
positions.emplace_back(bodyPosition); positions.emplace_back(bodyPosition);
--iterationCounter;
} while (true); } while (true);
} }

View File

@ -50,19 +50,39 @@ namespace SHADE
/** /**
* @brief * @brief
* Used to simulate the motion of a rigid body until it hits something. * Used to simulate the motion of a rigid body, ignoring collision detection and response.
* @param bodyEID
* The EntityID of the Rigid Body to simulate.
* @param force
* The force applied onto the Rigid Body.
* @param forceOffset
* The position to apply the force onto the body relative to it's local Center of Mass.
* @param torque
* The torque to apply onto the Rigid Body.
* @param continuousForce
* If the force should be applied every step throughout the simulation. Defaults to false. <br/>
* True : The force indicated is added to the body every step, therefore it has constant acceleration.
* False: The force is applied only in the first step, therefore it has constant speed.
* @param timeStep
* The timestep for each step of the simulation. Defaults to 0.016s (The default Fixed DT)
* @param maxSteps
* The number of steps to run the simulation for. Defaults to -1.
* < 0 : Runs until the object may hit something. Hit detection is done through raycasting.
* = 0 : Runs only the current step and checks if it may hit something.
* > 0 : Runs for the given number of steps or until it may hit something.
*/ */
struct SimulateBodyInfo struct SimulateBodyInfo
{ {
EntityID bodyEID = MAX_EID; EntityID bodyEID = MAX_EID;
SHVec3 force = SHVec3::Zero; SHVec3 force = SHVec3::Zero;
SHVec3 forceOffset = SHVec3::Zero; SHVec3 forceOffset = SHVec3::Zero;
SHVec3 torque = SHVec3::Zero; SHVec3 torque = SHVec3::Zero;
// Whether or not to clear the force after the first iteration // Whether or not to clear the force after the first iteration
bool continuousForce = false; bool continuousForce = false;
float timeStep = static_cast<float>(SHPhysicsConstants::DEFAULT_FIXED_DT); float timeStep = static_cast<float>(SHPhysicsConstants::DEFAULT_FIXED_DT);
int maxSteps = -1;
}; };