DanielChappuis / reactphysics3d

Open source C++ physics engine library in 3D

Home Page:http://www.reactphysics3d.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

0.10.0 - Raycasting gives incorrect results for HeightFieldShape when scaling factor is applied

JoeRosselli opened this issue · comments

Hi,

I'm updating from version 0.9.0 to 0.10.0 and I've noticed some behavior change with regards to HeightFieldShapes and raycasting.

Essentially, I have a HeightFieldShape and a CapsuleShape in a physics world, attached to rigid bodies, with the HeightFieldShape representing the ground, the CapsuleShape representing a player object, and the way I detect whether there's a body under the player is to raycast from above the CapsuleShape, through it, to a distance below it, looking for a collision with another body (in addition to the collision with the CapsuleShape itself).

In 0.9.0 my logic worked fine when there was either a HeightFieldShape or a BoxShape beneath the capsule. It would detect either.

However, in 0.10.0, using the same code (besides syncing to the height field interface changes), the raycasting still works fine for detecting BoxShapes underneath the capsule, but now no longer returns any hits for HeightFieldShapes.

The odd part is that the physics/collision still seems to work fine. I can drop my CapsuleShape onto the HeightFieldShape and it collides with it, I can apply forces to the capsule and it collides and interacts with the HeightFieldShape correctly. It's just that manually raycasting via PhysicsWorld::raycast is no longer able to return any hit for the HeightFieldShape below the CapsuleShape.

I get no errors through the messages mechanism when creating the HeightField object. I get no errors or interesting logs if I turn on a rp3d logger.

If I turn on debug rendering, and render collision shapes, the shape of the HeightFieldShape and CapsuleShape look correct. If I turn on contact point rendering, the contact between the HeightFieldShape and the CapsuleShape looks correct.

I can create rigid bodies with BoxShapes at any location/scale/orientation and raycasting seems to work fine when my CapsuleShape is on top of them; it's only when my CapsuleShape is on top of a HeightFieldShape, in 0.10.0, that although physics collisions seems correct, raycasting no longer detects the shape below.

My only suspicion is that it's related to the interface change where the height field axis parameter was removed (for my usage Y axis is upwards, I was providing '1' for that parameter before). However, if physics collisions work correctly, and the debug render output looks correct, I'm not sure how something could be configured incorrectly on my end.

Any ideas? Thanks!

Hi, I'm looking into this again and I'm still seeing lots of significant issues with height maps in 0.10.0.

For reference, I'm using a right handed coordinate system with positive Y upwards, positive X rightwards, positive Z out of the screen.

I've widdled it down to a minimum repro that seems to highlight some issues. I'm creating an extremely simple height map shape that's flat with 4 data points, and then raycasting downwards through it, from high up, from two positions:

struct HitReceiver : public reactphysics3d::RaycastCallback
{
    reactphysics3d::decimal notifyRaycastHit(const reactphysics3d::RaycastInfo& raycastInfo) override
    {
        std::cout << "Raycast Hit: " << raycastInfo.worldPoint.x << "," << raycastInfo.worldPoint.y << "," << raycastInfo.worldPoint.z << std::endl;
        return 1.0f;
    }
};

void Physics::CreateTestBody()
{
    auto* pBody = m_pPhysicsWorld->createRigidBody(reactphysics3d::Transform());
    pBody->setType(reactphysics3d::BodyType::STATIC);
    pBody->setIsDebugEnabled(true);

    std::vector<double> data {
        5.0, 5.0, 5.0, 5.0
    };

    std::vector<reactphysics3d::Message> heightFieldMessages;

    auto* pHeightField = m_physicsCommon.createHeightField(
        2,
        2,
        data.data(),
        reactphysics3d::HeightField::HeightDataType::HEIGHT_DOUBLE_TYPE,
        heightFieldMessages
    );

    auto* pCollisionShape = m_physicsCommon.createHeightFieldShape(
        pHeightField,
        reactphysics3d::Vector3(1.0f, 1.0f, 1.0f)
    );

    pBody->addCollider(pCollisionShape, reactphysics3d::Transform());

    const auto ray1 = reactphysics3d::Ray(reactphysics3d::Vector3(0.0f, 100.0f, 0.0f),
                                          reactphysics3d::Vector3(0.0f, -100.0f, 0.0f));

    const auto ray2 = reactphysics3d::Ray(reactphysics3d::Vector3(2.0f, 100.0f, 2.0f),
                                          reactphysics3d::Vector3(2.0f, -100.0f, 2.0f));

    HitReceiver raycastReceiver{};
    m_pPhysicsWorld->raycast(ray1, &raycastReceiver);
    m_pPhysicsWorld->raycast(ray2, &raycastReceiver);
}

The output from the above code is:

Raycast Hit: 0,0,0

The first ray hits and the second doesn't. As the height map shape in this example is a 2x2 grid with no scaling, I think this is correct; it's 1 unit wide, so the first raycast that's centered at {0,y,0} would hit it, and the other that's centered at {2,y,2} would miss it.

Now, where the issue I was originally reporting seems to come from can be seen by changing the scaling field in createHeightFieldShape from {1.0f, 1.0f, 1.0f} to, say, {10.0f, 1.0f, 10.0f}. In this case, the height map should be the same height, just 10 times longer in the X and Z directions.

In that case, the output from the above code is:

Raycast Hit: 0,0,0
Raycast Hit: 0.2,0,0.2

This seems obviously broken. The second ray is shooting straight downwards from {2, 100, 2), yet the collision with the shape is reported as {0.2, 0, 0.2} when I'd expect {2, 0, 2}. You see similar errors, worse than this, depending on the height map data and where you're raycasting.

If I turn on debug render output, the height map shape looks correct in being 10 times longer in the x and z axes. I can drop bodies on it and collisions work fine. However, as shown above, if I raycast down into it, it starts giving weird, incorrect, values.


As another test, if I keep all the code the same but replace the collision shape from a height map shape to a box shape:

auto* pCollisionShape = m_physicsCommon.createBoxShape(reactphysics3d::Vector3(1,5,1));

Then I get:

Raycast Hit: 0,5,0

Which seems fine, and if I extend the x/z dimensions by 10 units:

auto* pCollisionShape = m_physicsCommon.createBoxShape(reactphysics3d::Vector3(10,5,10));

I get:

Raycast Hit: 0,5,0
Raycast Hit: 2,5,2

Which also seems fine.

The problem seems to specifically revolve around specifying non-identity values for the scaling factor when creating a height field shape.

--

I'm also potentially seeing some weird behavior with how rp3d positions height map collision shapes. Naively, I'd assume that if the height data values were 5,5,5,5, and the shape was placed at the origin with no other transforms, then hits with it would be reported as being at a Y position of 5, not 0. I know that in 0.9.0 it vertically centered the shape around its position with regards to its vertical height, so maybe that's where it's coming from but I'm suspicious that something is broken here too. But I need the above issue solved before I can investigate down this line more. Now that axis is no longer a parameter when creating height field shapes, does it just always internally assume Y axis?

This issue should now be fixed in release of version v0.10.1. Thanks again for reporting this issue.