NVIDIAGameWorks / PhysX

NVIDIA PhysX SDK
Other
3.11k stars 793 forks source link

Two issues with scene->Overlap() #617

Closed PcChip closed 1 year ago

PcChip commented 1 year ago

Hello,

Understanding the pictures:

I'm having two separate issues with Overlap():

Issue 1:

Issue 2:

I'm sure I'm just doing something silly, but can't for the life of me figure out what!
I've also tried changing the filter flags using every combination I can think of with no success
Thank you for any advice you might have!

PierreTerdiman commented 1 year ago

This is wrong and has been made invalid in PhysX 5 (wouldn't compile): image

PcChip commented 1 year ago

thank you so much!

I actually got that from here: https://forums.developer.nvidia.com/t/need-help-with-configuring-scene-overlap-query/166860/4 , reading a comment from you: https://i.imgur.com/n6Qx3TQ.png

which led me to this line: https://github.com/NVIDIAGameWorks/PhysX/blob/4.1/physx/samples/samplenorthpole/SampleNorthPoleCCT.cpp#L52 (line 52)

can you let me know the correct way to prepare a sphere for this?

PierreTerdiman commented 1 year ago

The line you point out in SampleNorthPole looks correct. Yours does not. Just do:

PxSphereGeometry overlapShape(sphereSize); The way you wrote it, only the PxGeometry part of the temporary PxSphereGeometry object is used, and effectively you are using a random radius.

PcChip commented 1 year ago

I do appreciate your time, have a wonderful day and a happy new year!

PierreTerdiman commented 1 year ago

You're welcome. Ping me again if this does not solve your issues.

PcChip commented 1 year ago

Hi @PierreTerdiman ,

That did solve half of my problem, the distance now works as expected - thanks!

However I'm still having an issue of Overlap() only returning one result

I've tried: PxQueryFilterData filterData = PxQueryFilterData(PxQueryFlag::eSTATIC | PxQueryFlag::eDYNAMIC);
PxQueryFilterData filterData = PxQueryFilterData(PxQueryFlag::eANY_HIT | PxQueryFlag::eSTATIC | PxQueryFlag::eDYNAMIC);

with both, hits.getNbAnyHits() always returns 1, and hits.getNbTouches() always returns 0, even when there are multiple objects around (it does sometimes swap between them though)

How can I make it get a list of ALL overlaps?

Thanks!

PierreTerdiman commented 1 year ago

Could you share your code? Or try PxSceneQueryExt::overlapMultiple ?

PcChip commented 1 year ago

Could you share your code? Or try PxSceneQueryExt::overlapMultiple ?

Hi Pierre,

Sure, here's the code in question - note that I believe physx is set up and running correctly as raycasts work perfectly

Let me know if you need any other parts - I will also try PxSceneQueryExt::overlapMultiple()

std::vector<entt::entity> te2PhysicsModule::overlapSphere(glm::vec3 sphereLocation, float sphereSize)
{
    std::vector<entt::entity> results;

    PxSphereGeometry overlapShape(sphereSize);
    PxTransform shapePose = PxTransform(PxVec3(sphereLocation.x, sphereLocation.y, sphereLocation.z));
    PxOverlapBuffer hits;

    PxQueryFilterData filterData = PxQueryFilterData(PxQueryFlag::eSTATIC | PxQueryFlag::eDYNAMIC);

    bool status = m_PxScene->overlap(overlapShape, shapePose, hits, filterData);
    if (status)
    {
        LOG("status was true, hits.getNbAnyHits() = " << hits.getNbAnyHits() << ", hits.getNbTouches() = " << hits.getNbTouches() << "\n");
        for (int i = 0; i < hits.getNbAnyHits(); i++)
        {
            entt::entity thisEntity = (entt::entity)(uint32_t)hits.getAnyHit(i).actor->userData;
            results.push_back(thisEntity);

            cmp_gameObject* gameObject = tryGetEntityComponent(cmp_gameObject, thisEntity);
            if (gameObject != nullptr)
            {
                LOG(" - overLapSphere found: " << gameObject->name << "\n");
            }
        }
    }
    else
    {
        LOG("status was false, hits.getNbAnyHits() = " << hits.getNbAnyHits() << ", hits.getNbTouches() = " << hits.getNbTouches() << "\n");
    }

    return results;
}
PcChip commented 1 year ago

Hi Pierre,

I figured it out - for some reason the Overlap() documentation was confusing to me I suppose, but after re-reading the Raycast() documentation I saw that I needed to provide a buffer

https://i.imgur.com/28Pwjq5.png

Working as expected now!

To anyone reading this having the same problem, this resolved it for me:

const PxU32 bufferSize = 64;
PxOverlapHit overlapBuffer[bufferSize];
PxOverlapBuffer hits(overlapBuffer, bufferSize);