Exemple #1
0
RaycastHit Scene::raycastClosestShape(const Ray& ray, Enums::ShapesType type, unsigned int group, Real maxDistance, unsigned int hintFlags, RaycastCache cache) const
{

    NxRay inRay;
    Functions::XYZ<Vec3, NxVec3>(ray.mDirection, inRay.dir);
    Functions::XYZ<Vec3, NxVec3>(ray.mOrigin, inRay.orig);

    NxRaycastHit hit;
    NxShape* nxShape = mScene->raycastClosestShape(inRay, NxShapesType(int(type)), hit, group, maxDistance, hintFlags, 0, cache);

    RaycastHit out;
    out.mDistance = hit.distance;
    out.mFaceID = hit.faceID;
    out.mFlags = hit.flags;
    out.mInternalFaceID = hit.internalFaceID;
    out.mMaterialIndex = hit.materialIndex;
    out.mU = hit.u;
    out.mV = hit.v;
    Functions::XYZ<NxVec3, Vec3>(hit.worldImpact, out.mWorldImpact);
    Functions::XYZ<NxVec3, Vec3>(hit.worldNormal, out.mWorldNormal);

    if (nxShape)
    {
        PhysXPointer* shapePointer = pointer_cast(nxShape->userData);
        out.mShape = shapePointer->get<Shape>();
        out.mRigidBody = shapePointer->getParent<RigidBody>();
    }
    else
    {
        out.mShape = 0;
        out.mRigidBody = 0;
    }

    return out;
}
Exemple #2
0
bool Scene::raycastAnyShape(const Ray& ray, Enums::ShapesType type, unsigned int groups, Real maxDistance, RaycastCache cache) const
{
    NxRay inRay;
    Functions::XYZ<Vec3, NxVec3>(ray.mDirection, inRay.dir);
    Functions::XYZ<Vec3, NxVec3>(ray.mOrigin, inRay.orig);

    return mScene->raycastAnyShape(inRay, NxShapesType(int(type)), groups, maxDistance, 0, cache);
}
Exemple #3
0
unsigned int Scene::raycastAllBounds(const Ray& ray, Callback* callback,  Enums::ShapesType type, unsigned int group, Real maxDistance, unsigned int hintFlags) const
{
    NxRay inRay;
    Functions::XYZ<Vec3, NxVec3>(ray.mDirection, inRay.dir);
    Functions::XYZ<Vec3, NxVec3>(ray.mOrigin, inRay.orig);

    PhysXRaycastReport report(callback);
    return mScene->raycastAllBounds(inRay, report, NxShapesType(int(type)), group, maxDistance, hintFlags);
}
Exemple #4
0
bool Scene::raycastAnyBounds(const Ray& ray, Enums::ShapesType type, int4 groupsMask, Real maxDistance) const
{
    NxRay inRay;
    Functions::XYZ<Vec3, NxVec3>(ray.mDirection, inRay.dir);
    Functions::XYZ<Vec3, NxVec3>(ray.mOrigin, inRay.orig);
    NxGroupsMask mask;

    mask.bits0 = groupsMask.w;
    mask.bits1 = groupsMask.x;
    mask.bits2 = groupsMask.y;
    mask.bits3 = groupsMask.z;

    return mScene->raycastAnyBounds(inRay, NxShapesType(int(type)), -1, maxDistance, &mask);
}
Exemple #5
0
unsigned int Scene::raycastAllBounds(const Ray& ray, Callback* callback, Enums::ShapesType type, int4 groupsMask, Real maxDistance, unsigned int hintFlags) const
{
    NxRay inRay;
    Functions::XYZ<Vec3, NxVec3>(ray.mDirection, inRay.dir);
    Functions::XYZ<Vec3, NxVec3>(ray.mOrigin, inRay.orig);
    NxGroupsMask mask;

    mask.bits0 = groupsMask.w;
    mask.bits1 = groupsMask.x;
    mask.bits2 = groupsMask.y;
    mask.bits3 = groupsMask.z;

    PhysXRaycastReport report(callback);
    return mScene->raycastAllBounds(inRay, report, NxShapesType(int(type)), -1, maxDistance, hintFlags, &mask);
}
bool FindTouchedGeometry(
	void* user_data,
	const NxExtendedBounds3& worldBounds,		// ### we should also accept other volumes

	TriArray& world_triangles,
	TriArray* world_edge_normals,
	IntArray& edge_flags,
	IntArray& geom_stream,

	NxU32 group_flags,
	bool static_shapes, bool dynamic_shapes, const NxGroupsMask* groupsMask)
	{
	NX_ASSERT(user_data);
	NxScene* scene = (NxScene*)user_data;

	NxExtendedVec3 Origin;	// Will be TouchedGeom::mOffset
	worldBounds.getCenter(Origin);

	// Reserve a stack buffer big enough to hold all shapes in the world. This is a lazy approach that is
	// acceptable here since the total number of shapes is limited to 64K anyway, which would "only" consume
	// 256 Kb on the stack (hence, stack overflow is unlikely).
	// ### TODO: the new callback mechanism would allow us to use less memory here
//	NxU32 total = scene->getNbStaticShapes() + scene->getNbDynamicShapes();
	NxU32 total = scene->getTotalNbShapes();
	NxShape** buffer = (NxShape**)NxAlloca(total*sizeof(NxShape*));

	// Find touched *boxes* i.e. touched objects' AABBs in the world
	// We collide against dynamic shapes too, to get back dynamic boxes/etc
	// TODO: add active groups in interface!

	NxU32 Flags = 0;
	if(static_shapes)	Flags |= NX_STATIC_SHAPES;
	if(dynamic_shapes)	Flags |= NX_DYNAMIC_SHAPES;

	// ### this one is dangerous
	NxBounds3 tmpBounds;	// LOSS OF ACCURACY
	tmpBounds.min.x = (float)worldBounds.min.x;
	tmpBounds.min.y = (float)worldBounds.min.y;
	tmpBounds.min.z = (float)worldBounds.min.z;
	tmpBounds.max.x = (float)worldBounds.max.x;
	tmpBounds.max.y = (float)worldBounds.max.y;
	tmpBounds.max.z = (float)worldBounds.max.z;
	NxU32 nbTouchedBoxes = scene->overlapAABBShapes(tmpBounds, NxShapesType(Flags), total, buffer, NULL, group_flags, groupsMask);

	// Early exit if no AABBs found
	if(!nbTouchedBoxes)	return false;
	NX_ASSERT(nbTouchedBoxes<=total);	// Else we just trashed some stack memory

	// Loop through touched world AABBs
	NxShape** touched = buffer;
	while(nbTouchedBoxes--)
		{
		// Get current shape
		NxShape* shape = *touched++;

		// Filtering

		// Discard all CCT shapes, i.e. kinematic actors we created ourselves. We don't need to collide with them since they're surrounded
		// by the real CCT volume - and collisions with those are handled elsewhere. We use the userData field for filtering because that's
		// really our only valid option (filtering groups are already used by clients and we don't have control over them, clients might
		// create other kinematic actors that we may want to keep here, etc, etc)
		if(size_t(shape->userData)=='CCTS')
			continue;

		// Discard if not collidable
		// PT: this shouldn't be possible at this point since:
		// - the SF flag is only used for compounds
		// - the AF flag is already tested in scene query
		// - we shouldn't get compound shapes here
		if(shape->getFlag(NX_SF_DISABLE_COLLISION))
			continue;

		// Ubi (EA) : Discarding Triggers :
		if ( shape->getFlag(NX_TRIGGER_ENABLE) )
			continue;

		// PT: here you might want to disable kinematic objects.

		// Output shape to stream
		NxShapeType type = shape->getType();
				if(type==NX_SHAPE_SPHERE)		outputSphereToStream((NxSphereShape*)shape, shape, geom_stream, Origin);
		else	if(type==NX_SHAPE_CAPSULE)		outputCapsuleToStream((NxCapsuleShape*)shape, shape, geom_stream, Origin);
		else	if(type==NX_SHAPE_BOX)			outputBoxToStream((NxBoxShape*)shape, shape, geom_stream, Origin);
		else	if(type==NX_SHAPE_MESH)			outputMeshToStream((NxTriangleMeshShape*)shape, shape, geom_stream, world_triangles, world_edge_normals, edge_flags, Origin, tmpBounds);
		else	if(type==NX_SHAPE_HEIGHTFIELD)	outputHeightFieldToStream((NxHeightFieldShape*)shape, shape, geom_stream, world_triangles, world_edge_normals, edge_flags, Origin, tmpBounds);
		else	if(type==NX_SHAPE_CONVEX)		outputConvexToStream((NxConvexShape*)shape, shape, geom_stream, world_triangles, world_edge_normals, edge_flags, Origin, tmpBounds);
		}

	return true;
	}