Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rigidbody_set_kind in async mode #135

Open
volcoma opened this issue Mar 17, 2024 · 1 comment
Open

rigidbody_set_kind in async mode #135

volcoma opened this issue Mar 17, 2024 · 1 comment

Comments

@volcoma
Copy link

volcoma commented Mar 17, 2024

So i have this code here experimenting with the new set_kind function. As stated in the documentation before i update the kind
i also update the mass and intertia, making sure they are fine.
But after the call to the rigidbody_set_kind i get an asset for the mass telling me it's not in the valid range.
I set it before the call to set_kind having these check there passing and everything is valid.
I suspect the entity changes are not processed before the set_kind message is

void rigidbody_assert_supports_kind(entt::registry &registry, entt::entity entity, rigidbody_kind kind) {
    if (kind == rigidbody_kind::rb_dynamic) {
        auto &mass = registry.get<edyn::mass>(entity);
        EDYN_ASSERT(mass > EDYN_EPSILON && mass < large_scalar, "Dynamic rigid body must have non-zero mass.");
        auto &inertia = registry.get<edyn::inertia>(entity);
        EDYN_ASSERT(inertia != matrix3x3_zero, "Dynamic rigid body must have non-zero inertia.");
    }
}
void update_rigidbody_mass(entt::entity entity, entt::registry& registry, const rigidbody_def& def)
{
    if(def.kind == rigidbody_kind::rb_dynamic)
    {
        EDYN_ASSERT(def.mass > EDYN_EPSILON && def.mass < large_scalar, "Dynamic rigid body must have non-zero mass.");
        registry.emplace_or_replace<mass>(entity, def.mass);
        registry.emplace_or_replace<mass_inv>(entity, scalar(1) / def.mass);
    }
    else
    {
        registry.emplace_or_replace<mass>(entity, EDYN_SCALAR_MAX);
        registry.emplace_or_replace<mass_inv>(entity, scalar(0));
    }

// I even added those 2 as well
    registry.patch<mass>(entity);
    registry.patch<mass_inv>(entity);

}

void recreate_phyisics_body(physics_component& rigidbody, bool force = false)
{
    bool is_kind_dirty = rigidbody.is_property_dirty(physics_property::kind);
    bool needs_recreation = force; // || rigidbody.is_property_dirty(physics_property::kind);

    if(needs_recreation)
    {
        recreate_phyisics_entity(rigidbody);
    }

    auto owner = rigidbody.get_owner();
    auto& body = owner.get<edyn::rigidbody>();
    auto internal_entity = body.internal;
    auto entity = internal_entity.entity();
    auto& registry = *internal_entity.registry();

    update_def_mass(rigidbody, body.def);
    update_def_shape(rigidbody, body.def);
    update_def_material(rigidbody, body.def);
    update_def_gravity(rigidbody, body.def);
    update_def_kind(rigidbody, body.def);
    update_def_inertia(rigidbody, body.def);

    if(needs_recreation)
    {
        edyn::make_rigidbody(entity, registry, body.def);
    }
    else
    {
        if(rigidbody.is_property_dirty(physics_property::mass) || is_kind_dirty)
        {
            edyn::update_rigidbody_mass(entity, registry, body.def);
            edyn::update_rigidbody_inertia(entity, registry, body.def);
        }
        if(rigidbody.is_property_dirty(physics_property::gravity) || is_kind_dirty)
        {
            edyn::update_rigidbody_gravity(entity, registry, body.def);
        }
        if(rigidbody.is_property_dirty(physics_property::material) || is_kind_dirty)
        {
            edyn::update_rigidbody_material(entity, registry, body.def);
        }
        if(rigidbody.is_property_dirty(physics_property::shape) || is_kind_dirty)
        {
            edyn::update_rigidbody_shape(entity, registry, body.def);
            edyn::update_rigidbody_inertia(entity, registry, body.def);
        }
        if(is_kind_dirty)
        {
            edyn::update_rigidbody_kind(entity, registry, body.def);
        }

        if(body.def.kind == edyn::rigidbody_kind::rb_dynamic)
        {
            if(rigidbody.is_any_property_dirty())
            {
                edyn::wake_up_entity(registry, entity);
            }
        }
    }

    rigidbody.set_dirty(system_id, false);
}
@xissburg
Copy link
Owner

This commit should fix it 4c5795e
Also, you should be using edyn::set_rigibody_mass and edyn::set_rigidbody_inertiaand you can also now destroy a rigid body while preserving the entity usingedyn::clear_rigidbody`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants