physics: parented rigid body is detached only temporarlily during simulation to not modify real hierarchy system
This commit is contained in:
@@ -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();
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
@@ -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(
|
||||
@@ -1223,11 +1229,12 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,6 +1242,12 @@ namespace wi::physics
|
||||
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);
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user