How to fix rigid "bodies" using Physx

Asked

Viewed 169 times

7

How can I fix two rigid or dynamic "bodies" in a way that where one goes the other goes together as fixed as possible with Physx.

I’m using the class PxFixedJoint but I didn’t like it.

PxFixedJoint

As you can see in the print above, there is a "belly" curve in the formation of cubes. I have researched but found nothing concrete. I wanted a solution to fix the objects to each other but with the minimum of curve (so to speak).

Below an excerpt of the code.

// C++
// Função responsável por criar o joint
void HEntity::createFixedJoint(HEntity* target)
{
    physx::PxPhysics* physics = HEngine::getInstance()->getPhysicsContext()->getPhysics();
    physx::PxRigidActor* _target = target->getPhysicsBody();

    physx::PxVec3 pos_a = m_pPhysicsBody->getGlobalPose().p;
    physx::PxVec3 pos_b = _target->getGlobalPose().p;
    physx::PxVec3 offset = (pos_a - pos_b).abs() / 2;

    physx::PxFixedJoint* joint = physx::PxFixedJointCreate(*physics, m_pPhysicsBody, physx::PxTransform(-offset), _target, physx::PxTransform(offset));

    joint->setConstraintFlag(physx::PxConstraintFlag::eVISUALIZATION, true);
    joint->setConstraintFlag(physx::PxConstraintFlag::eCOLLISION_ENABLED, false);

    m_lpJoints.push_back(joint);
}

How I’m using Lua Script to extend/extend my application, below an excerpt from the Lua that creates the cubes.

-- Lua
-- Função responsável por criar os cubos em serie
function createJointCubes()
    local parent = scene:getObjectByName("Object.2") -- Cubo já presente na cena
    local last_obj = nil;

    for i = 1, 12 do
        local obj = HGameObject:new()
        obj:setName("Object_Phy." .. i)
        obj:setMesh(HEngine.importWavefront(imports[2]))

        if last_obj == nil then
            obj:setWorldPosition(parent:getWorldPosition()+HVec3(2, 0, 0))
        else
            obj:setWorldPosition(last_obj:getWorldPosition()+HVec3(2, 0, 0))
        end

        obj:createPhysicsBody()

        if last_obj == nil then
            obj:createFixedJoint(parent)
        else
            obj:createFixedJoint(last_obj)
        end

        scene:addObject(obj)
        last_obj = obj
    end
end


  • Can’t be sure from the screenshot you posted, but this curvature is not the result of gravity applied to the "chain" formed by the cubes? If not, you have come to try to increase a little the distance between the cubes in each joint? (because maybe the problem is due to the collision between the cubes) Also, to make it easier to receive help, you could publish a minimum example of code in which the problem is easily reproducible.

  • 1

    @Luiz Vieira, I have already added more information to the question. I put so that the cubes do not collide with each other. There are some games that use a vehicle construction system using blocks with physics, that each block has a different mass that alters the physics of the vehicle in the game. And yet this curvature doesn’t seem to happen.

  • 1

    Cool. But in the scene, the left cube seems to be higher up on the Y (or Z) axis, right? Seriously, are you sure it’s not because of gravity? Another thing, I don’t know how grouping works in this library (I always used Bullet or embedded in game Engines), but maybe you avoid the "belly" using sub-structure instead of joint. Like, make a next cube be "son" of the previous one. Thus, the properties of the mass remain, without the interference of the movable joint.

  • About the left cube being higher up, I did it on purpose. I did it just to see if the problem with the curvature would occur. What would be this sub-structure you said?. Meanwhile I’m researching to find a solution.

  • You told me to make a cube be "son" of the previous, great idea. But I’m scouring the API of PhysX and I’m not finding a way to make that kind of connection.

  • So. This is why "belly" occurs. Think of the final structure as a chain. If you hold it by the tips, gravity causes the middle items to form a catenary. To avoid this, turn off gravity or do not use joints, modeling the object uniquely or grouping them together. Like I said, I don’t know how to do Physx, but there must be a way. :)

  • 1

    Hi Walberti. I’m glad you solved it! But instead of having edited the question to put the solution, it would have been better if you had added an answer yourself and accepted it (so the question stops appearing as unanswered). Why don’t you do it? Add an answer with your solution, and edit the question to remove it from it. :)

  • @Luiz Vieira, it may seem like a joke, but the day I went to edit to put the solution, I looked for the button to answer my own question, but I did not find.

  • No problem. Oh, thanks for putting as an answer. It looks much better. :)

Show 5 more comments

1 answer

4


RESOLVED

Well, after doing a lot of research, I ended up finding a solution in the documentation of PhysX.

What I did was "parenting" (making "son") the object I wanted (which in this case is static) to a rigidbody object (object affected by physics) multiplying the transformation of the "father" object by that of the "son".

Then I used the method attachShape to add the physical "son" Hape to the list of physical "father" shapes and, updated the mass and inertia.

// C++
// Acada frame ("Parentando")
m_FilhoWorldTransform =  m_pPai->getWorldTransform() * m_FilhoWorldTransform;
// ...
// Adicionando shape "filho" ao rigidbody "Pai"
m_pPai->getRigidBody()->attachShape(m_Filho->getShape());
// ...
// Atualizando massa e inércia
physx::PxU32 mass_count = 2; // Numero de shapes/massas
physx::PxReal* masses = new physx::PxReal[2];
masses[0] = pai_mass;
masses[1] = filho_mass;

physx::PxRigidBodyExt::setMassAndUpdateInertia(*parent->getRigidDynamic(), masses, mass_count);
delete masses;

And look at the result. There is no longer "belly". Physics works correctly, it is as if the cubes are part of the object "Father".

Resultado

Browser other questions tagged

You are not signed in. Login or sign up in order to post.