Esempio n. 1
0
static PxReal computeInternalRadius(PxShape* shape, const PxVec3& dir, /*PxVec3& offset,*/ const PxVec3& centerOffset)
{
	const PxBounds3 bounds = shape->getWorldBounds();
	const PxReal diagonal = (bounds.maximum - bounds.minimum).magnitude();
	const PxReal offsetFromOrigin = diagonal * 2.0f;

	PxTransform pose = PxShapeExt::getGlobalPose(*shape);

	PxReal internalRadius = 0.0f;
	const PxReal length = offsetFromOrigin*2.0f;

	// PT: we do a switch here anyway since the code is not *exactly* the same all the time
	{
		switch(shape->getGeometryType())
		{
			case PxGeometryType::eBOX:
			case PxGeometryType::eCAPSULE:
			{
				pose.p = PxVec3(0);
				const PxVec3 virtualOrigin = pose.p + dir * offsetFromOrigin;

				PxRaycastHit hit;
				PxU32 nbHits = shape->raycast(virtualOrigin, -dir, length, (PxSceneQueryFlags)0xffffffff, 1, &hit, false, &pose);
				PX_ASSERT(nbHits);

				internalRadius = offsetFromOrigin - hit.distance;
	//			offset = PxVec3(0.0f);
			}
			break;

			case PxGeometryType::eSPHERE:
			{
				PxSphereGeometry geometry;
				bool status = shape->getSphereGeometry(geometry);
				PX_ASSERT(status);

				internalRadius = geometry.radius;
	//			offset = PxVec3(0.0f);
			}
			break;

			case PxGeometryType::eCONVEXMESH:
			{
	/*PxVec3 saved = pose.p;
				pose.p = PxVec3(0);

	//			pose.p = geometry.convexMesh->getCenterOfMass();
	//			const PxVec3 virtualOrigin = pose.p + dir * offsetFromOrigin;

	//			const PxVec3 localCenter = computeCenter(geometry.convexMesh);
	//			const PxVec3 localCenter = geometry.convexMesh->getCenterOfMass();
	//			const PxVec3 virtualOrigin = pose.rotate(localCenter) + dir * offsetFromOrigin;
				const PxVec3 localCenter = pose.rotate(geometry.convexMesh->getCenterOfMass());
				const PxVec3 virtualOrigin = localCenter + dir * offsetFromOrigin;

				PxRaycastHit hit;
				PxU32 nbHits = Gu::raycast_convexMesh(geometry, pose, virtualOrigin, -dir, length, 0xffffffff, 1, &hit);
				PX_ASSERT(nbHits);
				internalRadius = offsetFromOrigin - hit.distance;

				pose.p = localCenter;

	PxVec3 shapeCenter = getShapeCenter(shape);
	offset = shapeCenter - saved;*/


				PxVec3 shapeCenter = getShapeCenter(shape, centerOffset);
				shapeCenter -= pose.p;
				pose.p = PxVec3(0);

				const PxVec3 virtualOrigin = shapeCenter + dir * offsetFromOrigin;
				PxRaycastHit hit;
				PxU32 nbHits = shape->raycast(virtualOrigin, -dir, length, (PxSceneQueryFlags)0xffffffff, 1, &hit, false, &pose);
				PX_ASSERT(nbHits);

				internalRadius = offsetFromOrigin - hit.distance;
	//			offset = shapeCenter;
			}
			break;
		}
	}
	return internalRadius;
}
Esempio n. 2
0
double Gui::getDistanceBetwShapes(CircleShape shape1, CircleShape shape2) {
	Vector2f shape1Center = getShapeCenter(shape1);
	Vector2f shape2Center = getShapeCenter(shape2);
	return sqrt(pow(shape1Center.x - shape2Center.x, 2) + pow(shape1Center.y - shape2Center.y, 2));
}
Esempio n. 3
0
bool doRaycastCCD(PxShape* shape, PxTransform& newPose, PxVec3& newShapeCenter, const PxVec3& ccdWitness, const PxVec3& ccdWitnessOffset)
{
	PxRigidDynamic* dyna = canDoCCD(shape);
	if(!dyna)
		return true;

	bool updateCCDWitness = true;

	const PxVec3 offset = newPose.p - newShapeCenter;
//printf("CCD0: %f | %f | %f\n", newShapeCenter.x, newShapeCenter.y, newShapeCenter.z);
	const PxVec3& origin = ccdWitness;
//			const PxVec3& dest = newPose.p;
	const PxVec3& dest = newShapeCenter;

	PxVec3 dir = dest - origin;
	const PxReal length = dir.magnitude();
	if(length!=0.0f)
	{
		dir /= length;

		// Compute internal radius
//		PxVec3 localCenter;
		const PxReal internalRadius = computeInternalRadius(shape, dir, /*localCenter,*/ ccdWitnessOffset);

		// Compute distance to impact
		PxRaycastHit hit;
//		if(internalRadius!=0.0f && CCDRaycast(shape->getActor().getActiveScene(), origin + localCenter, dir, length, hit))
		if(internalRadius!=0.0f && CCDRaycast(shape->getActor().getScene(), origin, dir, length, hit))
		{
#ifdef RAYCAST_CCD_PRINT_DEBUG
			static int count=0;
			printf("CCD hit %d\n", count++);
#endif
			updateCCDWitness = false;
			const PxReal radiusLimit = internalRadius * 0.75f;
			if(hit.distance>radiusLimit)
			{
//				newPose.p = origin + dir * (hit.distance - radiusLimit);
				newShapeCenter = origin + dir * (hit.distance - radiusLimit);
#ifdef RAYCAST_CCD_PRINT_DEBUG
				printf("  Path0: %f | %f\n", hit.distance, radiusLimit);
#endif
			}
			else
			{
//				newPose.p = origin;
				newShapeCenter = origin;
//				newShapeCenter = origin + hit.normal * (radiusLimit - hit.distance);
#ifdef RAYCAST_CCD_PRINT_DEBUG
				printf("  Path1: %f\n", hit.distance);
#endif
			}

			{
				newPose.p = offset + newShapeCenter;
//newPose.p.y += 10.0f;
//printf("%f | %f | %f\n", newPose.p.x, newPose.p.y, newPose.p.z);

//				dyna->setGlobalPose(newPose);

				// newPose = actorGlobalPose * shapeLocalPose
				// newPose * inverse(shapeLocalPose) = actorGlobalPose

				const PxTransform shapeLocalPose = shape->getLocalPose();
				const PxTransform inverseShapeLocalPose = shapeLocalPose.getInverse();
				PxTransform newGlobalPose = newPose * inverseShapeLocalPose;
				dyna->setGlobalPose(newGlobalPose);
//dyna->setGlobalPose(newPose);
//printf("%f | %f | %f\n", newGlobalPose.p.x, newGlobalPose.p.y, newGlobalPose.p.z);
//printf("%f | %f | %f\n", shapeLocalPose.p.x, shapeLocalPose.p.y, shapeLocalPose.p.z);

/*PX_INLINE PxTransform PxShapeExt::getGlobalPose(const PxShape& shape)
{
PxRigidActor& ra = shape.getActor();

return ra.getGlobalPose() * shape.getLocalPose();
}*/
const PxVec3 testShapeCenter = getShapeCenter(shape, ccdWitnessOffset);
float d = (testShapeCenter - newShapeCenter).magnitude();
//printf("%f\n", d);
//printf("CCD1: %f | %f | %f\n", testShapeCenter.x, testShapeCenter.y, testShapeCenter.z);

//dyna->clearForce(PxForceMode::eFORCE);
//dyna->clearForce(PxForceMode::eIMPULSE);
//dyna->setLinearVelocity(PxVec3(0));	// PT: this helps the CCT but stops small objects dead, which doesn't look great

			}
		}
	}
	return updateCCDWitness;
}
Esempio n. 4
0
Vector2f Gui::getDirectionVector(CircleShape shape1, CircleShape shape2) {
	Vector2f shape1Center = getShapeCenter(shape1);
	Vector2f shape2Center = getShapeCenter(shape2);
	return Vector2f(shape2Center.x - shape1Center.x, shape2Center.y - shape1Center.y);
}