void physx::PxSetGroupsMask(const PxRigidActor& actor, const PxGroupsMask& mask)
{
	PxFilterData tmp;
	PxFilterData fd = convert(mask);

	if (actor.getNbShapes() == 1)
	{
		PxShape* shape = NULL;
		actor.getShapes(&shape, 1);

		// retrieve current group
		tmp = shape->getSimulationFilterData();
		fd.word0 = tmp.word0;

		// set new filter data
		shape->setSimulationFilterData(fd);
	}
	else
	{
		PxShape* shape;
		PxU32 numShapes = actor.getNbShapes();
		shdfnd::InlineArray<PxShape*, 64> shapes;
		if(numShapes > 64)
		{
			shapes.resize(64);
		}
		else
		{
			shapes.resize(numShapes);
		}

		PxU32 iter = 1 + numShapes/64;

		for(PxU32 i=0; i < iter; i++)
		{
			PxU32 offset = i * 64;
			PxU32 size = numShapes - offset;
			if(size > 64)
				size = 64;

			actor.getShapes(shapes.begin(), size, offset);

			for(PxU32 j = size; j--;)
			{
				// retrieve current group mask
				shape = shapes[j];
				// retrieve current group
				tmp = shape->getSimulationFilterData();
				fd.word0 = tmp.word0;

				// set new filter data
				shape->setSimulationFilterData(fd);

			}
		}
	}
}
void physx::PxSetGroup(const PxRigidActor& actor, const PxU16 collisionGroup)
{	
	PX_CHECK_AND_RETURN(collisionGroup < 32,"Collision group must be less than 32");

	PxFilterData fd;
	
	if (actor.getNbShapes() == 1)
	{
		PxShape* shape = NULL;
		actor.getShapes(&shape, 1);

		// retrieve current group mask
		fd = shape->getSimulationFilterData();
		fd.word0 = collisionGroup;
		
		// set new filter data
		shape->setSimulationFilterData(fd);
	}
	else
	{
		PxShape* shape;
		PxU32 numShapes = actor.getNbShapes();
		shdfnd::InlineArray<PxShape*, 64> shapes;
		if(numShapes > 64)
		{
			shapes.resize(64);
		}
		else
		{
			shapes.resize(numShapes);
		}

		PxU32 iter = 1 + numShapes/64;

		for(PxU32 i=0; i < iter; i++)
		{
			PxU32 offset = i * 64;
			PxU32 size = numShapes - offset;
			if(size > 64)
				size = 64;

			actor.getShapes(shapes.begin(), size, offset);

			for(PxU32 j = size; j--;)
			{
				// retrieve current group mask
				shape = shapes[j];
				fd = shape->getSimulationFilterData();
				fd.word0 = collisionGroup;

				// set new filter data
				shape->setSimulationFilterData(fd);
			}
		}
	}
}
void PxScaleRigidActor(PxRigidActor& actor, PxReal scale, bool scaleMassProps)
{
	PX_CHECK_AND_RETURN(scale > 0,
		"PxScaleRigidActor requires that the scale parameter is greater than zero");

	Ps::InlineArray<PxShape*, 64> shapes;
	shapes.resize(actor.getNbShapes());
	actor.getShapes(shapes.begin(), shapes.size());

	for(PxU32 i=0;i<shapes.size();i++)
	{
		shapes[i]->setLocalPose(scalePosition(shapes[i]->getLocalPose(), scale));		
		PxGeometryHolder h = shapes[i]->getGeometry();

		switch(h.getType())
		{
		case PxGeometryType::eSPHERE:	
			h.sphere().radius *= scale;			
			break;
		case PxGeometryType::ePLANE:
			break;
		case PxGeometryType::eCAPSULE:
			h.capsule().halfHeight *= scale;
			h.capsule().radius *= scale;
			break;
		case PxGeometryType::eBOX:
			h.box().halfExtents *= scale;
			break;
		case PxGeometryType::eCONVEXMESH:
			h.convexMesh().scale.scale *= scale;
			break;
		case PxGeometryType::eTRIANGLEMESH:
			h.triangleMesh().scale.scale *= scale;
			break;
		case PxGeometryType::eHEIGHTFIELD:
			h.heightField().heightScale *= scale;
			h.heightField().rowScale *= scale;
			h.heightField().columnScale *= scale;
			break;
		case PxGeometryType::eINVALID:
		case PxGeometryType::eGEOMETRY_COUNT:
		default:
			PX_ASSERT(0);
		}
		shapes[i]->setGeometry(h.any());
	}

	if(!scaleMassProps)
		return;

	PxRigidDynamic* dynamic = (&actor)->is<PxRigidDynamic>();
	if(!dynamic)
		return;

	PxReal scale3 = scale*scale*scale;
	dynamic->setMass(dynamic->getMass()*scale3);
	dynamic->setMassSpaceInertiaTensor(dynamic->getMassSpaceInertiaTensor()*scale3*scale*scale);
	dynamic->setCMassLocalPose(scalePosition(dynamic->getCMassLocalPose(), scale));
}
PxGroupsMask physx::PxGetGroupsMask(const PxRigidActor& actor)
{
	PX_CHECK_AND_RETURN_VAL(actor.getNbShapes() >= 1,"At least one shape must be in actor",PxGroupsMask());

	PxShape* shape = NULL;
	actor.getShapes(&shape, 1);

	PxFilterData fd = shape->getSimulationFilterData();
	
	return convert(fd);
}
PxU16 physx::PxGetGroup(const PxRigidActor& actor)
{
	PX_CHECK_AND_RETURN_NULL(actor.getNbShapes() >= 1,"There must be a shape in actor");

	PxShape* shape = NULL;
	actor.getShapes(&shape, 1);

	PxFilterData fd = shape->getSimulationFilterData();

	return (PxU16)fd.word0;
}
Exemplo n.º 6
0
bool copyStaticProperties(PxRigidActor& to, const PxRigidActor& from,NxMirrorScene::MirrorFilter &mirrorFilter)
{
	physx::shdfnd::InlineArray<PxShape*, 64> shapes;
	shapes.resize(from.getNbShapes());

	PxU32 shapeCount = from.getNbShapes();
	from.getShapes(shapes.begin(), shapeCount);

	physx::shdfnd::InlineArray<PxMaterial*, 64> materials;
	for(PxU32 i = 0; i < shapeCount; i++)
	{
		PxShape* s = shapes[i];

		if ( mirrorFilter.shouldMirror(*s) )
		{
			PxU32 materialCount = s->getNbMaterials();
			materials.resize(materialCount);
			s->getMaterials(materials.begin(), materialCount);
			PxShape* shape = to.createShape(s->getGeometry().any(), materials.begin(), static_cast<physx::PxU16>(materialCount));
			shape->setLocalPose( s->getLocalPose());
			shape->setContactOffset(s->getContactOffset());
			shape->setRestOffset(s->getRestOffset());
			shape->setFlags(s->getFlags());
			shape->setSimulationFilterData(s->getSimulationFilterData());
			shape->setQueryFilterData(s->getQueryFilterData());
			mirrorFilter.reviseMirrorShape(*shape);
		}
	}

	to.setActorFlags(from.getActorFlags());
	to.setOwnerClient(from.getOwnerClient());
	to.setDominanceGroup(from.getDominanceGroup());

	if ( to.getNbShapes() )
	{
		mirrorFilter.reviseMirrorActor(to);
	}

	return to.getNbShapes() != 0;
}
void TCompCharacterController::SetFilterData(PxFilterData& filter)
{
	PxRigidActor *ra = m_pActor->getActor()->isRigidActor();
	m_filter = filter;
	if (ra) {
		const PxU32 numShapes = ra->getNbShapes();
		PxShape **ptr;
		ptr = new PxShape*[numShapes];
		ra->getShapes(ptr, numShapes);
		for (PxU32 i = 0; i < numShapes; i++)
		{
			PxShape* shape = ptr[i];
			shape->setSimulationFilterData(m_filter);
			shape->setQueryFilterData(m_filter);
		}
	}
}
Exemplo n.º 8
0
	bool CreateGeometryFromPhysxActor(PxActor *a, LevelGeometry::Mesh &mesh)
	{
		bool rv = false;

		if (!a)
			return rv;

		PxRigidActor *ra = a->isRigidActor();
		if (!ra)
			return rv;

		GameObject* gameObj = NULL;
		PhysicsCallbackObject* userData = static_cast<PhysicsCallbackObject*>(ra->userData);
		if(userData) gameObj = userData->isGameObject();

		r3dCSHolder block(g_pPhysicsWorld->GetConcurrencyGuard());

		PxU32 nbShapes = ra->getNbShapes();
		for (PxU32 i = 0; i < nbShapes; ++i)
		{
			PxShape *s = 0;
			ra->getShapes(&s, 1, i);
			PxGeometryType::Enum gt = s->getGeometryType();
			switch(gt)
			{
			case PxGeometryType::eTRIANGLEMESH:
				{
					PxTriangleMeshGeometry g;
					s->getTriangleMeshGeometry(g);
					PxTransform t = s->getLocalPose().transform(ra->getGlobalPose());
					rv = CreateGeometryFromPhysxGeometry(g, t, mesh);
					break;
				}
			default:
				r3dArtBug("buildNavigation: Unsupported physx mesh type %d, obj: %s\n", gt, gameObj ? gameObj->Name.c_str() : "<unknown>");
			}
		}
		return rv;
	}
void TCompCharacterController::SetCollisions(bool new_collisions)
{
	PxRigidActor *ra = m_pActor->getActor()->isRigidActor();
	if (ra) {
		const PxU32 numShapes = ra->getNbShapes();
		PxShape **ptr;
		ptr = new PxShape*[numShapes];
		ra->getShapes(ptr, numShapes);
		for (PxU32 i = 0; i < numShapes; i++)
		{
			PxShape* shape = ptr[i];
			if (!new_collisions) {
				m_filter.word1 &= ~ItLightensFilter::eCOLLISION;
				m_filter.word1 &= ~ItLightensFilter::eCAN_TRIGGER;	//for test only
			}
			else {
				m_filter.word1 |= ItLightensFilter::eCOLLISION;
				m_filter.word1 |= ItLightensFilter::eCAN_TRIGGER;		//for test only
			}
			shape->setSimulationFilterData(m_filter);
			shape->setQueryFilterData(m_filter);
		}
	}
}
Exemplo n.º 10
0
bool UWorld::ComponentSweepMulti(TArray<struct FHitResult>& OutHits, class UPrimitiveComponent* PrimComp, const FVector& Start, const FVector& End, const FRotator& Rot, const struct FComponentQueryParams& Params) const
{
	if(GetPhysicsScene() == NULL)
	{
		return false;
	}

	if(PrimComp == NULL)
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentSweepMulti : No PrimComp"));
		return false;
	}

	// if target is skeletalmeshcomponent and do not support singlebody physics
	if ( !PrimComp->ShouldTrackOverlaps() )
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentSweepMulti : (%s) Does not support skeletalmesh with Physics Asset and destructibles."), *PrimComp->GetPathName());
		return false;
	}

	ECollisionChannel TraceChannel = PrimComp->GetCollisionObjectType();

#if WITH_PHYSX
	// if extent is 0, do line trace
	if (PrimComp->IsZeroExtent())
	{
		return RaycastMulti(this, OutHits, Start, End, TraceChannel, Params, FCollisionResponseParams(PrimComp->GetCollisionResponseToChannels()));
	}

	PxRigidActor* PRigidActor = PrimComp->BodyInstance.GetPxRigidActor();
	if(PRigidActor == NULL)
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentSweepMulti : (%s) No physics data"), *PrimComp->GetPathName());
		return false;
	}
	PxScene * const PScene = PRigidActor->getScene();

	OutHits.Empty();

	// Get all the shapes from the actor
	TArray<PxShape*, TInlineAllocator<8>> PShapes;
	{
		SCOPED_SCENE_READ_LOCK(PScene);
		PShapes.AddZeroed(PRigidActor->getNbShapes());
		PRigidActor->getShapes(PShapes.GetData(), PShapes.Num());
	}

	// calculate the test global pose of the actor
	PxTransform PGlobalStartPose = U2PTransform(FTransform(Start));
	PxTransform PGlobalEndPose = U2PTransform(FTransform(End));

	bool bHaveBlockingHit = false;
	PxQuat PGeomRot = U2PQuat(Rot.Quaternion());

	// Iterate over each shape
	SCENE_LOCK_READ(PScene);
	for(int32 ShapeIdx=0; ShapeIdx<PShapes.Num(); ShapeIdx++)
	{
		PxShape* PShape = PShapes[ShapeIdx];
		check(PShape);

		TArray<struct FHitResult> Hits;

		// Calc shape global pose
		PxTransform PLocalShape = PShape->getLocalPose();
		PxTransform PShapeGlobalStartPose = PGlobalStartPose.transform(PLocalShape);
		PxTransform PShapeGlobalEndPose = PGlobalEndPose.transform(PLocalShape);
		// consider localshape rotation for shape rotation
		PxQuat PShapeRot = PGeomRot * PLocalShape.q;

		GET_GEOMETRY_FROM_SHAPE(PGeom, PShape);

		if(PGeom != NULL)
		{
			SCENE_UNLOCK_READ(PScene);
			if (GeomSweepMulti(this, *PGeom, PShapeRot, Hits, P2UVector(PShapeGlobalStartPose.p), P2UVector(PShapeGlobalEndPose.p), TraceChannel, Params, FCollisionResponseParams(PrimComp->GetCollisionResponseToChannels())))
			{
				bHaveBlockingHit = true;
			}

			OutHits.Append(Hits);
			SCENE_LOCK_READ(PScene);
		}
	}
	SCENE_UNLOCK_READ(PScene);

	return bHaveBlockingHit;
#endif //WITH_PHYSX
	return false;
}
Exemplo n.º 11
0
bool UWorld::ComponentSweepSingle(struct FHitResult& OutHit,class UPrimitiveComponent* PrimComp, const FVector& Start, const FVector& End, const FRotator& Rot, const struct FComponentQueryParams& Params) const
{
	OutHit.TraceStart = Start;
	OutHit.TraceEnd = End;

	if(GetPhysicsScene() == NULL)
	{
		return false;
	}

	if(PrimComp == NULL)
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentSweepSingle : No PrimComp"));
		return false;
	}

	// if target is skeletalmeshcomponent and do not support singlebody physics
	if ( !PrimComp->ShouldTrackOverlaps() )
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentSweepSingle : (%s) Does not support skeletalmesh with Physics Asset and destructibles."), *PrimComp->GetPathName());
		return false;
	}

	ECollisionChannel TraceChannel = PrimComp->GetCollisionObjectType();
#if WITH_PHYSX
	// if extent is 0, do line trace
	if (PrimComp->IsZeroExtent())
	{
		return RaycastSingle(this, OutHit, Start, End, TraceChannel, Params, FCollisionResponseParams(PrimComp->GetCollisionResponseToChannels()));
	}

	PxRigidActor* PRigidActor = PrimComp->BodyInstance.GetPxRigidActor();
	if(PRigidActor == NULL)
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentSweepMulti : (%s) No physics data"), *PrimComp->GetPathName());
		return false;
	}

	// Get all the shapes from the actor
	TArray<PxShape*, TInlineAllocator<8>> PShapes;
	PShapes.AddZeroed(PRigidActor->getNbShapes());
	int32 NumShapes = PRigidActor->getShapes(PShapes.GetData(), PShapes.Num());

	// calculate the test global pose of the actor
	PxTransform PGlobalStartPose = U2PTransform(FTransform(Start));
	PxTransform PGlobalEndPose = U2PTransform(FTransform(End));

	bool bHaveBlockingHit = false;
	PxQuat PGeomRot = U2PQuat(Rot.Quaternion());

	// Iterate over each shape
	for(int32 ShapeIdx=0; ShapeIdx<PShapes.Num(); ShapeIdx++)
	{
		PxShape* PShape = PShapes[ShapeIdx];
		check(PShape);

		// Calc shape global pose
		PxTransform PLocalShape = PShape->getLocalPose();
		PxTransform PShapeGlobalStartPose = PGlobalStartPose.transform(PLocalShape);
		PxTransform PShapeGlobalEndPose = PGlobalEndPose.transform(PLocalShape);
		// consider localshape rotation for shape rotation
		PxQuat PShapeRot = PGeomRot * PLocalShape.q;

		GET_GEOMETRY_FROM_SHAPE(PGeom, PShape);

		if(PGeom != NULL)
		{
			// @todo UE4, this might not be the best behavior. If we're looking for the most closest, this have to change to save the result, and find the closest one or 
			// any other options, right now if anything hits first, it will return
			if (GeomSweepSingle(this, *PGeom, PShapeRot, OutHit, P2UVector(PShapeGlobalStartPose.p), P2UVector(PShapeGlobalEndPose.p), TraceChannel, Params, FCollisionResponseParams(PrimComp->GetCollisionResponseToChannels())))
			{
				bHaveBlockingHit = true;
				break;
			}
		}
	}

	return bHaveBlockingHit;
#endif //WITH_PHYSX
	return false;
}
Exemplo n.º 12
0
bool UWorld::ComponentOverlapTest(class UPrimitiveComponent* PrimComp, const FVector& Pos, const FRotator& Rot, const struct FComponentQueryParams& Params) const
{
	if(GetPhysicsScene() == NULL)
	{
		return false;
	}

	if(PrimComp == NULL)
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentOverlapMulti : No PrimComp"));
		return false;
	}

	// if target is skeletalmeshcomponent and do not support singlebody physics, we don't support this yet
	// talk to @JG, SP, LH
	if ( !PrimComp->ShouldTrackOverlaps() )
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentOverlapMulti : (%s) Does not support skeletalmesh with Physics Asset and destructibles."), *PrimComp->GetPathName());
		return false;
	}
#if WITH_PHYSX
	ECollisionChannel TraceChannel = PrimComp->GetCollisionObjectType();

	PxRigidActor* PRigidActor = PrimComp->BodyInstance.GetPxRigidActor();
	if(PRigidActor == NULL)
	{
		UE_LOG(LogCollision, Log, TEXT("ComponentOverlapMulti : (%s) No physics data"), *PrimComp->GetPathName());
		return false;
	}

	// calculate the test global pose of the actor
	PxTransform PTestGlobalPose = U2PTransform(FTransform(Rot, Pos));

	// Get all the shapes from the actor
	TArray<PxShape*, TInlineAllocator<8>> PShapes;
	PShapes.AddZeroed(PRigidActor->getNbShapes());
	int32 NumShapes = PRigidActor->getShapes(PShapes.GetData(), PShapes.Num());

	// Iterate over each shape
	for(int32 ShapeIdx=0; ShapeIdx<PShapes.Num(); ShapeIdx++)
	{
		PxShape* PShape = PShapes[ShapeIdx];
		check(PShape);
		// Calc shape global pose
		PxTransform PLocalPose = PShape->getLocalPose();
		PxTransform PShapeGlobalPose = PTestGlobalPose.transform(PLocalPose);

		GET_GEOMETRY_FROM_SHAPE(PGeom, PShape);

		if(PGeom != NULL)
		{
			if( GeomOverlapTest(this, *PGeom, PShapeGlobalPose, TraceChannel, Params, FCollisionResponseParams(PrimComp->GetCollisionResponseToChannels())))
			{
				// in this test, it only matters true or false. 
				// if we found first true, we don't care next test anymore. 
				return true;
			}
		}
	}

#endif //WITH_PHYSX
	return false;
}