bool Gu::checkOverlapOBB_sphereGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eSPHERE);
	const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom);

	return intersectSphereBox(Gu::Sphere(pose.p, sphereGeom.radius), box);
}
static void writeGeom(BatchQueryStream& stream, const PxGeometry& geom)
{
	PxGeometryType::Enum geomType = geom.getType();
	stream.write<PxU32>(PxU32(geomType));
	switch (geomType)
	{
	case PxGeometryType::eCAPSULE:
		stream.write<PxCapsuleGeometry>(static_cast<const PxCapsuleGeometry&>(geom));
		break;
	case PxGeometryType::eSPHERE:
		stream.write<PxSphereGeometry>(static_cast<const PxSphereGeometry&>(geom));
		break;
	case PxGeometryType::eCONVEXMESH:
		stream.write<PxConvexMeshGeometry>(static_cast<const PxConvexMeshGeometry&>(geom));
		break;
	case PxGeometryType::eBOX:
		stream.write<PxBoxGeometry>(static_cast<const PxBoxGeometry&>(geom));
		break;
	case PxGeometryType::ePLANE:
	case PxGeometryType::eTRIANGLEMESH:
	case PxGeometryType::eHEIGHTFIELD:
	case PxGeometryType::eGEOMETRY_COUNT:
	case PxGeometryType::eINVALID:
		PX_ALWAYS_ASSERT_MESSAGE("Unsupported geometry type in writeGeom");
	}
}
// PT: TODO: optimize all these data copies
void Gu::GeometryUnion::set(const PxGeometry& g)
{
	switch(g.getType())
	{
		case PxGeometryType::eBOX:
		{
			reinterpret_cast<PxBoxGeometry&>(mGeometry) = static_cast<const PxBoxGeometry&>(g);
		}
		break;

		case PxGeometryType::eCAPSULE:
		{
			reinterpret_cast<PxCapsuleGeometry&>(mGeometry) = static_cast<const PxCapsuleGeometry&>(g);
		}
		break;

		case PxGeometryType::eSPHERE:
		{
			reinterpret_cast<PxSphereGeometry&>(mGeometry) = static_cast<const PxSphereGeometry&>(g);
			reinterpret_cast<PxCapsuleGeometry&>(mGeometry).halfHeight = 0.0f;		//AM: make sphere geometry also castable as a zero height capsule.
		}
		break;

		case PxGeometryType::ePLANE:
		{
			reinterpret_cast<PxPlaneGeometry&>(mGeometry) = static_cast<const PxPlaneGeometry&>(g);
		}
		break;

		case PxGeometryType::eCONVEXMESH:
		{
			reinterpret_cast<PxConvexMeshGeometry&>(mGeometry) = static_cast<const PxConvexMeshGeometry&>(g);
			reinterpret_cast<PxConvexMeshGeometryLL&>(mGeometry).hullData = &(::getConvexMesh(get<PxConvexMeshGeometryLL>().convexMesh).getHull());
			reinterpret_cast<PxConvexMeshGeometryLL&>(mGeometry).gpuCompatible = ::getConvexMesh(get<PxConvexMeshGeometryLL>().convexMesh).isGpuCompatible();
		}
		break;

		case PxGeometryType::eTRIANGLEMESH:
		{
			reinterpret_cast<PxTriangleMeshGeometry&>(mGeometry) = static_cast<const PxTriangleMeshGeometry&>(g);
			reinterpret_cast<PxTriangleMeshGeometryLL&>(mGeometry).meshData = &(::getTriangleMesh(get<PxTriangleMeshGeometryLL>().triangleMesh));
			reinterpret_cast<PxTriangleMeshGeometryLL&>(mGeometry).materialIndices = (::getTriangleMesh(get<PxTriangleMeshGeometryLL>().triangleMesh).getMaterials());
			reinterpret_cast<PxTriangleMeshGeometryLL&>(mGeometry).materials = MaterialIndicesStruct();
		}
		break;

		case PxGeometryType::eHEIGHTFIELD:
		{
			reinterpret_cast<PxHeightFieldGeometry&>(mGeometry) = static_cast<const PxHeightFieldGeometry&>(g);
			reinterpret_cast<PxHeightFieldGeometryLL&>(mGeometry).heightFieldData = &::getHeightField(get<PxHeightFieldGeometryLL>().heightField).getData();
			reinterpret_cast<PxHeightFieldGeometryLL&>(mGeometry).materials = MaterialIndicesStruct();
		}
		break;

		case PxGeometryType::eGEOMETRY_COUNT:
		case PxGeometryType::eINVALID:
			PX_ALWAYS_ASSERT_MESSAGE("geometry type not handled");
		break;
	}
}
bool Gu::checkOverlapCapsule_sphereGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eSPHERE);
	const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom);

	return intersectSphereCapsule(Gu::Sphere(pose.p, sphereGeom.radius), worldCapsule);
}
Esempio n. 5
0
void RenderPhysX3Debug::addGeometry(const PxGeometry& geom, const PxTransform& tr,  const RendererColor& color, PxU32 renderFlags)
{
	switch(geom.getType())
    {
		case PxGeometryType::eBOX:
		{
			addBox(static_cast<const PxBoxGeometry&>(geom), tr, color, renderFlags);
		}
		break;
		case PxGeometryType::eSPHERE:
		{
			addSphere(static_cast<const PxSphereGeometry&>(geom),  tr, color, renderFlags);
		}
		break;
		case PxGeometryType::eCAPSULE:
		{
			addCapsule(static_cast<const PxCapsuleGeometry&>(geom), tr, color, renderFlags);
		}
		break;
		case PxGeometryType::eCONVEXMESH:
		{
			addConvex(static_cast<const PxConvexMeshGeometry&>(geom), tr, color, renderFlags);
		}
		break;
		case PxGeometryType::ePLANE:
		case PxGeometryType::eTRIANGLEMESH:
		case PxGeometryType::eHEIGHTFIELD:
		default:
		{
			PX_ASSERT(!"Not supported!");
			break;
		}
	}
}
bool Gu::GeometryQuery::sweep(const PxVec3& unitDir,
						  const PxReal distance,
						  const PxGeometry& geom,
						  const PxTransform& pose,
						  PxU32 triangleCount,
						  const Gu::Triangle* triangles,
						  PxSweepHit& sweepHit,
						  PxSceneQueryFlags hintFlags,
						  const PxU32* triangleFlags,
						  const Gu::Triangle* triangleEdgeNormals,
						  const PxU32* cachedIndex)
{
	PX_CHECK_VALID(pose.p);
	PX_CHECK_VALID(pose.q);
	PX_CHECK_VALID(unitDir);
	PX_CHECK_VALID(distance);

	PX_CHECK_AND_RETURN_VAL(distance > 0, "PxGeometryQuery::sweep(): sweep distance must be greater than 0.", false);

	switch (geom.getType())
	{
		case PxGeometryType::eSPHERE :
		{
			const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom);

			PxCapsuleGeometry capsuleGeom;
			capsuleGeom.radius = sphereGeom.radius;
			capsuleGeom.halfHeight = 0.0f;

			return Gu::SweepCapsuleTriangles(	triangleCount, triangles, triangleFlags, capsuleGeom, pose, unitDir, distance,
												cachedIndex, sweepHit.impact, sweepHit.normal, sweepHit.distance, sweepHit.faceIndex);
		}
		break;

		case PxGeometryType::eCAPSULE :
		{
			const PxCapsuleGeometry& capsGeom = static_cast<const PxCapsuleGeometry&>(geom);

			return Gu::SweepCapsuleTriangles(	triangleCount, triangles, triangleFlags, capsGeom, pose, unitDir, distance,
												cachedIndex, sweepHit.impact, sweepHit.normal, sweepHit.distance, sweepHit.faceIndex);
		}
		break;

		case PxGeometryType::eBOX :
		{
			const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom);

			return Gu::SweepBoxTriangles(	triangleCount, triangles, triangleEdgeNormals, triangleFlags, boxGeom, pose, 
											unitDir, distance, sweepHit.impact, sweepHit.normal, sweepHit.distance, sweepHit.faceIndex, cachedIndex);
		}
		break;

		default :
			PX_CHECK_AND_RETURN_VAL(false, "PxGeometryQuery::sweep(): geometry object parameter must be sphere, capsule or box geometry.", false);
		break;
	}

	return false;
}
bool Gu::checkOverlapCapsule_planeGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule)
{
	PX_ASSERT(geom.getType() == PxGeometryType::ePLANE);
	PX_UNUSED(geom);
//	const PxPlaneGeometry& planeGeom = static_cast<const PxPlaneGeometry&>(geom);

	const PxPlane plane = getPlane(pose);
	return intersectPlaneCapsule(worldCapsule, plane);
}
bool Gu::checkOverlapOBB_boxGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eBOX);
	const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom);

	return Gu::intersectOBBOBB(	boxGeom.halfExtents, pose.p, PxMat33(pose.q),
								box.extents, box.center, box.rot,
								true);
}
bool Gu::checkOverlapSphere_capsuleGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE);
	const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom);

	Gu::Capsule capsule;
	getCapsule(capsule, capsuleGeom, pose);
	return intersectSphereCapsule(sphere, capsule);
}
bool Gu::checkOverlapSphere_planeGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere)
{
	PX_ASSERT(geom.getType() == PxGeometryType::ePLANE);
	PX_UNUSED(geom);
//	const PxPlaneGeometry& planeGeom = static_cast<const PxPlaneGeometry&>(geom);

	const PxPlane plane = getPlane(pose);
	return plane.distance(sphere.center) - sphere.radius <= 0.0f;
}
bool Gu::checkOverlapSphere_boxGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eBOX);
	const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom);

	Gu::Box obb;
	buildFrom(obb, pose.p, boxGeom.halfExtents, pose.q);
	return intersectSphereBox(sphere, obb);
}
bool Gu::checkOverlapOBB_planeGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box)
{
	PX_ASSERT(geom.getType() == PxGeometryType::ePLANE);
	PX_UNUSED(geom);
//	const PxPlaneGeometry& planeGeom = static_cast<const PxPlaneGeometry&>(geom);

	const PxPlane plane = getPlane(pose);
	return intersectPlaneBox(plane, box);
}
bool Gu::checkOverlapCapsule_boxGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eBOX);
	const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom);

	Gu::Box box;
	buildFrom(box, pose.p, boxGeom.halfExtents, pose.q);

	return intersectBoxCapsule(box, worldCapsule);
}
bool Gu::checkOverlapOBB_capsuleGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE);
	const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom);

	Gu::Capsule capsule;
	getCapsule(capsule, capsuleGeom, pose);

	return intersectBoxCapsule(box, capsule);
}
	void PhysXMeshCollider::setGeometry(const PxGeometry& geometry)
	{
		PxShape* shape = getInternal()->_getShape();
		if (shape->getGeometryType() != geometry.getType())
		{
			PxShape* newShape = gPhysX().getPhysX()->createShape(geometry, *gPhysX().getDefaultMaterial(), true);
			getInternal()->_setShape(newShape);
		}
		else
			getInternal()->_getShape()->setGeometry(geometry);
	}
Esempio n. 16
0
PxU32 physx::PxMeshQuery::findOverlapTriangleMesh(
	const PxGeometry& geom, const PxTransform& geomPose,
	const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshPose,
	PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow)
{
	PX_SIMD_GUARD;
	switch(geom.getType())
	{
		case PxGeometryType::eBOX:
		{
			const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom);

			Box box;
			buildFrom(box, geomPose.p, boxGeom.halfExtents, geomPose.q);

			TriangleMesh* tm = static_cast<TriangleMesh*>(meshGeom.triangleMesh);
			return findOverlapOBBMesh(box, tm->getCollisionModel(), meshPose, meshGeom.scale, results, maxResults, startIndex, overflow);
		}

		case PxGeometryType::eCAPSULE:
		{
			const PxCapsuleGeometry& capsGeom = static_cast<const PxCapsuleGeometry&>(geom);

			Capsule capsule;
			getCapsule(capsule, capsGeom, geomPose);

			TriangleMesh* tm = static_cast<TriangleMesh*>(meshGeom.triangleMesh);
			return findOverlapCapsuleMesh(
				capsule, tm->getCollisionModel(), meshPose, meshGeom.scale, results, maxResults, startIndex, overflow);
		}

		case PxGeometryType::eSPHERE:
		{
			const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom);

			TriangleMesh* tm = static_cast<TriangleMesh*>(meshGeom.triangleMesh);
			return findOverlapSphereMesh(Sphere(geomPose.p, sphereGeom.radius), tm->getCollisionModel(), meshPose, meshGeom.scale, results, maxResults, startIndex, overflow);
		}
		case PxGeometryType::ePLANE:
		case PxGeometryType::eCONVEXMESH:
		case PxGeometryType::eTRIANGLEMESH:
		case PxGeometryType::eHEIGHTFIELD:
		case PxGeometryType::eGEOMETRY_COUNT:
		case PxGeometryType::eINVALID:
		default:
		{
			overflow = false;
			PX_CHECK_MSG(false, "findOverlapTriangleMesh: Only box, capsule and sphere geometries are supported.");
			return false;
		}
	}
}
bool Gu::checkOverlapCapsule_capsuleGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE);
	const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom);

	Gu::Capsule thisWorldCapsule;
	getCapsule(thisWorldCapsule, capsuleGeom, pose);

	PxReal s,t;
	PxReal squareDist = Gu::distanceSegmentSegmentSquared(thisWorldCapsule, worldCapsule, &s, &t);
	PxReal totRad = thisWorldCapsule.radius + worldCapsule.radius;
	return squareDist <= totRad*totRad;	// PT: objects are defined as closed, so we return 'true' in case of equality
}
static bool FindOverlappedTriangleNormal(const UWorld* World, const PxGeometry& Geom, const PxTransform& QueryTM, const PxShape* PShape, const PxTransform& PShapeWorldPose, FVector& OutNormal, float Inflation, bool bCanDrawOverlaps = false)
{
	bool bSuccess = false;

	if (CanFindOverlappedTriangle(PShape))
	{
		if (Inflation <= 0.f)
		{
			bSuccess = FindOverlappedTriangleNormal_Internal(World, Geom, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps);
		}
		else
		{
			// Try a slightly inflated test if possible.
			switch (Geom.getType())
			{
				case PxGeometryType::eCAPSULE:
				{
					const PxCapsuleGeometry* InCapsule = static_cast<const PxCapsuleGeometry*>(&Geom);
					PxCapsuleGeometry InflatedCapsule(InCapsule->radius + Inflation, InCapsule->halfHeight); // don't inflate halfHeight, radius is added all around.
					bSuccess = FindOverlappedTriangleNormal_Internal(World, InflatedCapsule, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps);
					break;
				}

				case PxGeometryType::eBOX:
				{
					const PxBoxGeometry* InBox = static_cast<const PxBoxGeometry*>(&Geom);
					PxBoxGeometry InflatedBox(InBox->halfExtents + PxVec3(Inflation));
					bSuccess = FindOverlappedTriangleNormal_Internal(World, InflatedBox, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps);
					break;
				}

				case PxGeometryType::eSPHERE:
				{
					const PxSphereGeometry* InSphere = static_cast<const PxSphereGeometry*>(&Geom);
					PxSphereGeometry InflatedSphere(InSphere->radius + Inflation);
					bSuccess = FindOverlappedTriangleNormal_Internal(World, InflatedSphere, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps);
					break;
				}

				default:
				{
					// No inflation possible
					break;
				}
			}
		}
	}

	return bSuccess;
}
Esempio n. 19
0
PxU32 physx::Gu::MeshQuery::findOverlapTriangleMesh(	const PxGeometry& geom0, const PxTransform& pose0,
												const PxTriangleMeshGeometry& geom1, const PxTransform& pose1,
												PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow)
{
	switch(geom0.getType())
	{
		case PxGeometryType::eBOX :
		{
			const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom0);

			Gu::Box box;
			buildFrom(box, pose0.p, boxGeom.halfExtents, pose0.q);

			Gu::TriangleMesh* tm = static_cast<Gu::TriangleMesh*>(geom1.triangleMesh);
			return Gu::findOverlapOBBMesh(box, tm->getOpcodeModel(), pose1, geom1.scale, results, maxResults, startIndex, overflow);
		}
		break;

		case PxGeometryType::eCAPSULE :
		{
			const PxCapsuleGeometry& capsGeom = static_cast<const PxCapsuleGeometry&>(geom0);

			Gu::Capsule worldCapsule;	// PT: TODO: fix this wrong name
			Gu::getWorldCapsule(worldCapsule, capsGeom, pose0);
			
			Gu::TriangleMesh* tm = static_cast<Gu::TriangleMesh*>(geom1.triangleMesh);
			return Gu::findOverlapCapsuleMesh(worldCapsule, tm->getOpcodeModel(), pose1, geom1.scale, results, maxResults, startIndex, overflow);
		}
		break;

		case PxGeometryType::eSPHERE :
		{
			const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom0);

			Gu::TriangleMesh* tm = static_cast<Gu::TriangleMesh*>(geom1.triangleMesh);
			return Gu::findOverlapSphereMesh(Gu::Sphere(pose0.p, sphereGeom.radius), tm->getOpcodeModel(), pose1, geom1.scale, results, maxResults, startIndex, overflow);
		}
		break;

		default :
			PX_CHECK_AND_RETURN_VAL(false, "findOverlapTriangleMesh: Only box, capsule and sphere geometries are supported.", false);
		break;
	}

	return 0;
}
Esempio n. 20
0
PxU32 physx::Gu::MeshQuery::findOverlapHeightField(const PxGeometry& geom0, const PxTransform& pose0,
											const PxHeightFieldGeometry& geom1, const PxTransform& pose1,
											PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow)
{
	const PxTransform localPose0 = pose1.transformInv(pose0);

	switch(geom0.getType())
	{
		case PxGeometryType::eBOX :
		{
			const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom0);

			const bool isAABB = ((localPose0.q.x == 0.0f) && (localPose0.q.y == 0.0f) && (localPose0.q.z == 0.0f));
			
			PxBounds3 bounds;
			if (isAABB)
				bounds = PxBounds3::centerExtents(localPose0.p, boxGeom.halfExtents);
			else
				bounds = PxBounds3::poseExtent(localPose0, boxGeom.halfExtents); // box.halfExtents is really extent

			Gu::HeightFieldUtil hfUtil(geom1);
			HfTrianglesEntityReport2 entityReport(results, maxResults, startIndex, hfUtil, localPose0.p, boxGeom.halfExtents, localPose0.q, isAABB);

			// PT: TODO: add a helper to expose this number?
/*			const PxU32 maxNbOverlapRows = static_cast<PxU32>( Ps::ceil(((bounds.getDimensions().x * (1.0f / geom1.rowScale)) + 1.0f)) );
			const PxU32 maxNbOverlapCols = static_cast<PxU32>( Ps::ceil(((bounds.getDimensions().z * (1.0f / geom1.columnScale)) + 1.0f)) );

			PxU32 maxNbTriangles = (maxNbOverlapCols * maxNbOverlapRows) << 1;  // maximum number of height field triangles overlapping the local AABB
			maxNbTriangles = PxMax(maxNbTriangles, (PxU32)8);  // No matter how small the AABB is, it can always have its center at the shared point of 4 cells*/

			hfUtil.overlapAABBTriangles(pose1, bounds, 0, &entityReport);
			overflow = entityReport.mOverflow;
			return entityReport.mNbResults;
		}
		break;

		case PxGeometryType::eCAPSULE :
		case PxGeometryType::eSPHERE :
		default :
			PX_CHECK_AND_RETURN_VAL(false, "findOverlapHeightField: Only box queries are supported.", false);
		break;
	}

	return 0;
}
void PvdSceneQueryCollector::overlapMultiple(const PxGeometry& geometry, const PxTransform& pose, const PxOverlapHit* hit, PxU32 hitsNum, const PxQueryFilterData& fd)
{
	Ps::Mutex::ScopedLock lock(mMutex);

	PvdOverlap overlapQuery;
	pushBackT(mGeometries[mInUse], PxGeometryHolder(geometry), overlapQuery.mGeometries, getArrayName(mGeometries[mInUse]));	// PT: TODO: optimize this. We memcopy once to the stack, then again to the array....

	const PxGeometryType::Enum type = geometry.getType();
	if(type==PxGeometryType::eBOX)				overlapQuery.mType = pose.q.isIdentity() ? QueryID::QUERY_OVERLAP_AABB_ALL_OBJECTS : QueryID::QUERY_OVERLAP_OBB_ALL_OBJECTS;
	else if(type==PxGeometryType::eSPHERE)		overlapQuery.mType = QueryID::QUERY_OVERLAP_SPHERE_ALL_OBJECTS;
	else if(type==PxGeometryType::eCAPSULE)		overlapQuery.mType = QueryID::QUERY_OVERLAP_CAPSULE_ALL_OBJECTS;
	else if(type==PxGeometryType::eCONVEXMESH)	overlapQuery.mType = QueryID::QUERY_OVERLAP_CONVEX_ALL_OBJECTS;
	else										PX_ASSERT(0);
	overlapQuery.mPose			= pose;
	overlapQuery.mFilterData	= fd.data;

	accumulate(overlapQuery, mAccumulatedOverlapQueries, getArrayName(mPvdSqHits), mPvdSqHits, hit, hitsNum, fd);
}
bool Gu::checkOverlapSphere_convexGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eCONVEXMESH);
	const PxConvexMeshGeometry& cvGeom = static_cast<const PxConvexMeshGeometry&>(geom);

	GU_FETCH_CONVEX_DATA(cvGeom);

	// PT: TODO: why do we bother doing this first test?
	//TODO: Support scaling
	if(cvGeom.scale.isIdentity())
	{
		// Test if sphere center is inside convex
		PxVec3 sphereCenter = pose.transformInv(sphere.center);
		if(convexHullContains(cm->getHull(), sphereCenter))
			return true;
	}

	return intersectSphereConvex(sphere, *cm, cvGeom.scale, pose, NULL);
}
bool Gu::checkOverlapOBB_convexGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eCONVEXMESH);
	const PxConvexMeshGeometry& cvGeom = static_cast<const PxConvexMeshGeometry&>(geom);

	GU_FETCH_CONVEX_DATA(cvGeom);	

	// PT: TODO: why do we bother doing this first test?
	//TODO: Support scaling
	if(cvGeom.scale.isIdentity())
	{
		const PxVec3 boxCenter = pose.transformInv(box.center);
		if(convexHullContains(cm->getHull(), boxCenter))
			return true;
	}

	// PT: ### USELESS CONVERSION - PxBoxGeometry & PxTransform are not necessary here
	return intersectBoxConvex(PxBoxGeometry(box.extents), PxTransform(box.center, PxQuat(box.rot)), *cm, cvGeom.scale, pose, NULL);
}
void PvdSceneQueryCollector::sweep(const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, PxReal distance, const PxSweepHit* hit, PxU32 hitsNum, const PxQueryFilterData& fd, bool multipleHits)
{
	Ps::Mutex::ScopedLock lock(mMutex);

	PvdSweep sweepQuery;
	pushBackT(mGeometries[mInUse], PxGeometryHolder(geometry), sweepQuery.mGeometries, getArrayName(mGeometries[mInUse]));	// PT: TODO: optimize this. We memcopy once to the stack, then again to the array....
	pushBackT(mPoses, pose, sweepQuery.mPoses, getArrayName(mPoses));
	pushBackT(mFilterData, fd.data, sweepQuery.mFilterData, getArrayName(mFilterData));

	const PxGeometryType::Enum type = geometry.getType();	// PT: TODO: QueryID::QUERY_LINEAR_xxx_SWEEP_ALL_OBJECTS are never used!
	if(type==PxGeometryType::eBOX)												sweepQuery.mType = QueryID::QUERY_LINEAR_OBB_SWEEP_CLOSEST_OBJECT;
	else if(type==PxGeometryType::eSPHERE || type==PxGeometryType::eCAPSULE)	sweepQuery.mType = QueryID::QUERY_LINEAR_CAPSULE_SWEEP_CLOSEST_OBJECT;
	else if(type==PxGeometryType::eCONVEXMESH)									sweepQuery.mType = QueryID::QUERY_LINEAR_CONVEX_SWEEP_CLOSEST_OBJECT;
	else																		PX_ASSERT(0);
	sweepQuery.mUnitDir		= unitDir;
	sweepQuery.mDistance	= distance;
	clampNbHits(hitsNum, fd, multipleHits);

	accumulate(sweepQuery, mAccumulatedSweepQueries, getArrayName(mPvdSqHits), mPvdSqHits, hit, hitsNum, fd);
}
Esempio n. 25
0
	float CEntity::getLogicPivotOffset(const PxGeometry& geometry) {
		switch( geometry.getType() ) {
			case PxGeometryType::eBOX:
				// Devolver la altura media de la caja
				return static_cast<const PxBoxGeometry*>(&geometry)->halfExtents.y;
				break;

			case PxGeometryType::eSPHERE:
				// Devolver el radio de la esfera
				return static_cast<const PxSphereGeometry*>(&geometry)->radius;
				break;

			case PxGeometryType::eCAPSULE:
				// Devolver el radio de la cupula mas la mitad de la altura
				return static_cast<const PxCapsuleGeometry*>(&geometry)->halfHeight;
				break;
		}

		return 0;
	}
void Gu::GeometryUnion::set(const PxGeometry& g)
{
	switch(g.getType())
	{
	case PxGeometryType::eBOX :
		reinterpret_cast<PxBoxGeometry&>(geometry) = static_cast<const PxBoxGeometry&>(g);
		break;
	case PxGeometryType::eCAPSULE :
		reinterpret_cast<PxCapsuleGeometry&>(geometry) = static_cast<const PxCapsuleGeometry&>(g);
		break;
	case PxGeometryType::eSPHERE :
		reinterpret_cast<PxSphereGeometry&>(geometry) = static_cast<const PxSphereGeometry&>(g);
		reinterpret_cast<PxCapsuleGeometry&>(geometry).halfHeight = 0.0f;		//AM: make sphere geometry also castable as a zero height capsule.
		break;
	case PxGeometryType::ePLANE :
		reinterpret_cast<PxPlaneGeometry&>(geometry) = static_cast<const PxPlaneGeometry&>(g);
		break;
	case PxGeometryType::eCONVEXMESH :
		{
			reinterpret_cast<PxConvexMeshGeometry&>(geometry) = static_cast<const PxConvexMeshGeometry&>(g);
			reinterpret_cast<PxConvexMeshGeometryLL&>(geometry).hullData = &(Gu::getConvexMesh(get<PxConvexMeshGeometryLL>().convexMesh).getHull());
		}
		break;
	case PxGeometryType::eTRIANGLEMESH :
		{
			reinterpret_cast<PxTriangleMeshGeometry&>(geometry) = static_cast<const PxTriangleMeshGeometry&>(g);
			reinterpret_cast<PxTriangleMeshGeometryLL&>(geometry).meshData = &(Gu::getTriangleMesh(get<PxTriangleMeshGeometryLL>().triangleMesh).mesh.mData);
		}
		break;
	case PxGeometryType::eHEIGHTFIELD :
		{
			reinterpret_cast<PxHeightFieldGeometry&>(geometry) = static_cast<const PxHeightFieldGeometry&>(g);
			reinterpret_cast<PxHeightFieldGeometryLL&>(geometry).heightFieldData = &Gu::getHeightField(get<PxHeightFieldGeometryLL>().heightField).getData();
		}
		break;
	default :
		PX_ASSERT(0 && "geometry type not handled");
		break;
	}
}
bool sweepConvex_CapsuleGeom(	const PxGeometry& geom, const PxTransform& pose, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose,
								const PxVec3& unitDir, const PxReal distance, PxSweepHit& sweepHit, PxHitFlags hintFlags, const PxReal inflation)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE);
	const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom);

	Capsule capsule;
	getCapsule(capsule, capsuleGeom, pose);

	if(sweepCapsule_ConvexGeom(convexGeom, convexPose, capsule, -unitDir, distance, sweepHit, hintFlags, inflation))
	{
		// do not write to position if it has not been set (initialOverlap)
		if (sweepHit.flags & PxHitFlag::ePOSITION)
		{
			sweepHit.position += unitDir * sweepHit.distance;
		}
		sweepHit.normal = -sweepHit.normal;
		sweepHit.faceIndex = 0xffffffff;
		return true;
	}
	return false;
}
bool sweepConvex_BoxGeom(	const PxGeometry& geom, const PxTransform& pose, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose,
							const PxVec3& unitDir, const PxReal distance, PxSweepHit& sweepHit, PxHitFlags hintFlags, const PxReal inflation)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eBOX);
	const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom);

	Box box;
	buildFrom1(box, pose.p, boxGeom.halfExtents, pose.q);

	//pxPrintf("sweepConvex begin\n");
	if(sweepBox_ConvexGeom(convexGeom, convexPose, box, -unitDir, distance, sweepHit, hintFlags, inflation))
	{
		// do not write to position if it has not been set (initialOverlap)
		if (sweepHit.flags & PxHitFlag::ePOSITION)
		{
			sweepHit.position += unitDir * sweepHit.distance;
		}
		sweepHit.normal = -sweepHit.normal;
		sweepHit.faceIndex = 0xffffffff;
		return true;
	}
	return false;
}
bool Gu::checkOverlapCapsule_convexGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule)
{
	PX_ASSERT(geom.getType() == PxGeometryType::eCONVEXMESH);
	const PxConvexMeshGeometry& cvGeom = static_cast<const PxConvexMeshGeometry&>(geom);


	GU_FETCH_CONVEX_DATA(cvGeom);

	// PT: TODO: why do we bother doing this first test?
	//TODO: Support scaling
	if(cvGeom.scale.isIdentity())
	{
		// Test if capsule center is inside convex
		PxVec3 capsuleCenter = (worldCapsule.p0 + worldCapsule.p1) * 0.5f;
		capsuleCenter = pose.transformInv(capsuleCenter);
		if(convexHullContains(cm->getHull(),capsuleCenter))
			return true;
	}
	PxCapsuleGeometry cg;
	cg.radius = worldCapsule.radius;
	PxTransform capsuleTransform = getCapsuleTransform(worldCapsule, cg.halfHeight);

	return intersectCapsuleConvex(cg, capsuleTransform, *cm, cvGeom.scale, pose, NULL);
}
bool Gu::GeometryQuery::overlap(const PxGeometry& geom0, const PxTransform& pose0,
								const PxGeometry& geom1, const PxTransform& pose1)
{
	PX_CHECK_VALID(pose0.p);
	PX_CHECK_VALID(pose0.q);
	PX_CHECK_VALID(pose1.p);
	PX_CHECK_VALID(pose1.q);

	if(geom0.getType() > geom1.getType())
	{
		Gu::GeomOverlapFunc overlapFunc = Gu::gGeomOverlapMethodTable[geom1.getType()][geom0.getType()];
		PX_ASSERT(overlapFunc);
		return overlapFunc(geom1, pose1, geom0, pose0, NULL);
	}
	else
	{
		Gu::GeomOverlapFunc overlapFunc = Gu::gGeomOverlapMethodTable[geom0.getType()][geom1.getType()];
		PX_ASSERT(overlapFunc);
		return overlapFunc(geom0, pose0, geom1, pose1, NULL);
	}
}