Skip to content

Commit

Permalink
physics: parented rigid body is detached only temporarlily during sim…
Browse files Browse the repository at this point in the history
…ulation to not modify real hierarchy system
  • Loading branch information
turanszkij committed Jan 23, 2025
1 parent 010e794 commit 7161d98
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 16 deletions.
43 changes: 29 additions & 14 deletions WickedEngine/wiPhysics_Jolt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ namespace wi::physics
BodyID bodyID;
Entity entity = INVALID_ENTITY;

// Things for parented objects:
XMFLOAT4X4 parentMatrix = wi::math::IDENTITY_MATRIX;
XMFLOAT4X4 parentMatrixInverse = wi::math::IDENTITY_MATRIX;

// Interpolation state:
Vec3 prev_position = Vec3::sZero();
Quat prev_rotation = Quat::sIdentity();
Expand Down Expand Up @@ -317,12 +321,21 @@ namespace wi::physics
wi::scene::Scene& scene,
Entity entity,
wi::scene::RigidBodyPhysicsComponent& physicscomponent,
const wi::scene::TransformComponent& transform,
const wi::scene::TransformComponent& _transform,
const wi::scene::MeshComponent* mesh
)
{
ShapeSettings::ShapeResult shape_result;

TransformComponent transform = _transform;

scene.locker.lock();
XMMATRIX parentMatrix = scene.ComputeParentMatrixRecursive(entity);
scene.locker.unlock();

XMStoreFloat4x4(&transform.world, parentMatrix * transform.GetLocalMatrix());
transform.ApplyTransform();

// The default convex radius caused issues when creating small box shape, etc, so I decrease it:
const float convexRadius = 0.001f;

Expand Down Expand Up @@ -422,6 +435,8 @@ namespace wi::physics
RigidBody& physicsobject = GetRigidBody(physicscomponent);
physicsobject.physics_scene = scene.physics_scene;
physicsobject.entity = entity;
XMStoreFloat4x4(&physicsobject.parentMatrix, parentMatrix);
XMStoreFloat4x4(&physicsobject.parentMatrixInverse, XMMatrixInverse(nullptr, parentMatrix));
PhysicsScene& physics_scene = GetPhysicsScene(scene);

physicsobject.shape = shape_result.Get();
Expand Down Expand Up @@ -471,15 +486,6 @@ namespace wi::physics
wi::backlog::post("AddRigidBody failed: body couldn't be created! This could mean that there are too many physics objects.", wi::backlog::LogLevel::Error);
return;
}

if (motionType == EMotionType::Dynamic)
{
// We must detach dynamic objects, because their physics object is created in world space
// and attachment would apply double transformation to the transform
scene.locker.lock();
scene.Component_Detach(entity);
scene.locker.unlock();
}
}
}
void AddSoftBody(
Expand Down Expand Up @@ -1223,18 +1229,25 @@ namespace wi::physics

if (currentMotionType == EMotionType::Dynamic)
{
// We must detach dynamic objects, because their physics object is created in world space
// and attachment would apply double transformation to the transform
// Changed to dynamic, remember attachment matrices at this point:
scene.locker.lock();
scene.Component_Detach(entity);
XMMATRIX parentMatrix = scene.ComputeParentMatrixRecursive(entity);
scene.locker.unlock();
XMStoreFloat4x4(&physicsobject.parentMatrix, parentMatrix);
XMStoreFloat4x4(&physicsobject.parentMatrixInverse, XMMatrixInverse(nullptr, parentMatrix));
}
}

TransformComponent* transform = scene.transforms.GetComponent(entity);
if (transform == nullptr)
return;

if (currentMotionType == EMotionType::Dynamic)
{
// Detaching object manually before the physics simulation:
transform->MatrixTransform(physicsobject.parentMatrix);
}

if (physics_scene.activate_all_rigid_bodies)
{
body_interface.ActivateBody(physicsobject.bodyID);
Expand Down Expand Up @@ -1596,7 +1609,9 @@ namespace wi::physics

transform->translation_local = cast(position);
transform->rotation_local = cast(rotation);
transform->SetDirty();

// Back to local space of parent:
transform->MatrixTransform(physicsobject.parentMatrixInverse);
});

wi::jobsystem::Dispatch(ctx, (uint32_t)scene.softbodies.GetCount(), 1, [&scene, &physics_scene](wi::jobsystem::JobArgs args) {
Expand Down
9 changes: 9 additions & 0 deletions WickedEngine/wiScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7360,6 +7360,15 @@ namespace wi::scene
}


XMMATRIX Scene::ComputeEntityMatrixRecursive(wi::ecs::Entity entity) const
{
const TransformComponent* transform = transforms.GetComponent(entity);
if (transform == nullptr)
return XMMatrixIdentity();

return transform->GetLocalMatrix() * ComputeParentMatrixRecursive(entity);
}

XMMATRIX Scene::ComputeParentMatrixRecursive(Entity entity) const
{
XMMATRIX parentMatrix = XMMatrixIdentity();
Expand Down
5 changes: 4 additions & 1 deletion WickedEngine/wiScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ namespace wi::scene
using CapsuleIntersectionResult = SphereIntersectionResult;
CapsuleIntersectionResult Intersects(const wi::primitive::Capsule& capsule, uint32_t filterMask = wi::enums::FILTER_OPAQUE, uint32_t layerMask = ~0, uint32_t lod = 0) const;

// Goes through the hierarchy backwards and computes entity's world space matrix:
XMMATRIX ComputeEntityMatrixRecursive(wi::ecs::Entity entity) const;

// Goes through the hierarchy backwards and computes parent's world space matrix:
XMMATRIX ComputeParentMatrixRecursive(wi::ecs::Entity entity) const;

Expand All @@ -542,7 +545,7 @@ namespace wi::scene
// returns entity ID of the new animation or INVALID_ENTITY if retargeting was not successful
wi::ecs::Entity RetargetAnimation(wi::ecs::Entity dst, wi::ecs::Entity src, bool bake_data, const Scene* src_scene = nullptr);

// If you don't know which armature the bone is contained int, this function can be used to find the first such armature and return the bone's rest matrix
// If you don't know which armature the bone is contained in, this function can be used to find the first such armature and return the bone's rest matrix
// If not found, and entity has a transform, it returns transform matrix
// Otherwise, returns identity matrix
XMMATRIX GetRestPose(wi::ecs::Entity entity) const;
Expand Down
2 changes: 1 addition & 1 deletion WickedEngine/wiVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 662;
const int revision = 663;

const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);

Expand Down

0 comments on commit 7161d98

Please sign in to comment.