NVIDIAGameWorks/PhysX

Two issues with scene->Overlap()

PcChip opened this issue · 9 comments

Hello,

Understanding the pictures:

  • I do a raycast where the mouse is, and draw a white sphere of size 1 where it hits (just to see where the mouse is hitting)
  • I'm doing an Overlap() at this exact hit location with sphere radius 3.0f (have also tried 30.0f, and 3000.0f)
  • This is the OverLapSphere code I'm using: https://i.imgur.com/nhzse4v.png (tried with and without custom flags)
  • PhysX 4.1

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

Issue 1:

  • running an Overlap() query very close to the building returns false: https://i.imgur.com/imHRJ3b.png
  • running an Overlap() query ON the edge of the building (mouse raycast hit result) returns true, but still does not include nearby buildings (getNbAnyHits returns 1, getNbTouches returns 0) - https://i.imgur.com/O6gdFzB.png

Issue 2:

  • when switching Visual Studio to Debug mode, Overlap() always returns false!!! Keep in mind that Raycasting against the scene still works perfectly (as evident by the white sphere being drawn) so it seems like my Debug build of PhysX should be working fine?

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!

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

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?

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.

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

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

PcChip commented

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!

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

PcChip commented

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

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);