Exemplo n.º 1
0
void Update()
{
	NxMat34 mat34;
	NxMat33 mat;
	NxQuat quat(0.0f,NxVec3(0,1,0));  
	mat.fromQuat(quat);
	NxBox worldBox;
	worldBox.extents	= NxVec3(2, 2, 2);
	worldBox.rot		= mat;

	NxSphere	worldSphere;
	NxBounds3	worldBounds;
	NxCapsule	worldCapsule;
	worldCapsule.radius = 2.0f;

	NxU32 nbPlanes = 2;
	NxPlane worldPlanes[2];
	worldPlanes[0].set(NxVec3(-2,0,2), NxVec3(0,0,1));
	worldPlanes[1].set(NxVec3(-2,0,2), NxVec3(1,0,0));

	NxU32 nbDynamicShapes	= gScene->getNbDynamicShapes();
	NxU32 nbStaticShapes	= gScene->getNbStaticShapes();
	NxU32 nbShapes = 0;
	NxShapesType type;

	int i = 0;
	for (i = 0; i < 3; ++ i)
	{
		if (i == 0)
		{
			nbShapes = nbDynamicShapes;
			type	 = NX_DYNAMIC_SHAPES;
			switch(gOverlapType)
			{
			case OVERLAP_AABB:
			case OVERLAP_CHECK_AABB:
				worldBounds.set(gMIN, gMAX);
				break;
			case OVERLAP_OBB:
			case OVERLAP_CHECK_OBB:
				worldBox.center = gBoxCenter;
				break;
			case OVERLAP_CAPSULE:
			case OVERLAP_CHECK_CAPSULE:
				worldCapsule = NxCapsule(gCapsuleSegment, gCapsuleRadius);
				break;
			case OVERLAP_SPHERE:
			case OVERLAP_CHECK_SPHERE:
				worldSphere = NxSphere(gSphereCenter, gSphereRadius);
				break;
			}
		}
		else if (i == 1)
		{
			nbShapes = nbStaticShapes;
			type	 = NX_STATIC_SHAPES;
			switch(gOverlapType)
			{
			case OVERLAP_AABB:
			case OVERLAP_CHECK_AABB:
				worldBounds.set(gMIN+NxVec3(-6.0f,0,0),gMAX+NxVec3(-6.0f,0,0));
				break;
			case OVERLAP_OBB:
			case OVERLAP_CHECK_OBB:
				worldBox.center = gBoxCenter+NxVec3(-6,0,0);
				break;
			case OVERLAP_CAPSULE:
			case OVERLAP_CHECK_CAPSULE:
				worldCapsule.p0.x = gCapsuleSegment.p0.x - 6.0f;
				worldCapsule.p1.x = gCapsuleSegment.p1.x - 6.0f;
				break;
			case OVERLAP_SPHERE:
			case OVERLAP_CHECK_SPHERE:
				worldSphere = NxSphere(gSphereCenter + NxVec3(-6,0,0), gSphereRadius);
				break;
			}
		}
		else if (i == 2)
		{
			nbShapes = nbStaticShapes + nbDynamicShapes;
			type	 = NX_ALL_SHAPES;
			switch(gOverlapType)
			{
			case OVERLAP_AABB:
			case OVERLAP_CHECK_AABB:
				worldBounds.set(gMIN+NxVec3(6.0f,0,0),gMAX+NxVec3(6.0f,0,0));
				break;
			case OVERLAP_OBB:
			case OVERLAP_CHECK_OBB:
				worldBox.center = gBoxCenter+NxVec3(6,0,0);
				break;
			case OVERLAP_CAPSULE:
			case OVERLAP_CHECK_CAPSULE:
				worldCapsule.p0.x = gCapsuleSegment.p0.x + 6.0f;
				worldCapsule.p1.x = gCapsuleSegment.p1.x + 6.0f;
				break;
			case OVERLAP_SPHERE:
			case OVERLAP_CHECK_SPHERE:
				worldSphere = NxSphere(gSphereCenter + NxVec3(6,0,0), gSphereRadius);
				break;
			}
		}

		NxShape** shapes = (NxShape**)NxAlloca(nbShapes*sizeof(NxShape*));
		for (NxU32 j = 0; j < nbShapes; j++)  shapes[j] = NULL;
		NxU32 activeGroups = 0xffffffff;
		NxGroupsMask* groupsMask = NULL;
		bool bResult	= true;
		float linewidth = 1.0f;
		switch(gOverlapType)
		{
		case OVERLAP_AABB:
			gScene->overlapAABBShapes(worldBounds, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask, true);
			NxCreateBox(worldBox, worldBounds, mat34);
			DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			break;
		case OVERLAP_CHECK_AABB:
			bResult = gScene->checkOverlapAABB(worldBounds, type, activeGroups, groupsMask);
			NxCreateBox(worldBox, worldBounds, mat34);
			if (bResult == true)
				DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			else
				DrawWireBox(worldBox, NxVec3(0,1,0), linewidth);
			break;
		case OVERLAP_OBB:
			gScene->overlapOBBShapes(worldBox, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			break;
		case OVERLAP_CHECK_OBB:
			if (gScene->checkOverlapOBB(worldBox, type, activeGroups, groupsMask) == true)
				DrawWireBox(worldBox, NxVec3(1,0,0), linewidth);
			else
				DrawWireBox(worldBox, NxVec3(0,1,0), linewidth);
			break;
		case OVERLAP_CAPSULE:
			gScene->overlapCapsuleShapes(worldCapsule, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawWireCapsule(worldCapsule, NxVec3(1,0,0));
			break;
		case OVERLAP_CHECK_CAPSULE:
			if (gScene->checkOverlapCapsule(worldCapsule, type,activeGroups, groupsMask) == true)
				DrawWireCapsule(worldCapsule, NxVec3(1,0,0));
			else
				DrawWireCapsule(worldCapsule, NxVec3(0,1,0));
			break;
		case OVERLAP_SPHERE:
			gScene->overlapSphereShapes(worldSphere, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawWireSphere(&worldSphere, NxVec3(1,0,0));
			break;
		case OVERLAP_CHECK_SPHERE:
			if (gScene->checkOverlapSphere(worldSphere, type,activeGroups, groupsMask) == true)
				DrawWireSphere(&worldSphere, NxVec3(1,0,0));
			else
				DrawWireSphere(&worldSphere, NxVec3(0,1,0));
			break;
		case OVERLAP_CULL:
			gScene->cullShapes(nbPlanes, worldPlanes, type, nbShapes, shapes, &gShapeReport, activeGroups, groupsMask);
			DrawLine(NxVec3(-20,0,2), NxVec3(-2,0,2),NxVec3(1,0,0), linewidth);
			DrawLine(NxVec3(-2,0,-20), NxVec3(-2,0,2),NxVec3(1,0,0), linewidth);
			break;
		}
	}
}
void SampleCollision::setup()
{

	SetTitleString(getName());
#ifdef __PPCGEKKO__
	SetHelpString("    a: create rigid bodies");
#else	
	SetHelpString("    b: create rigid bodies");
#endif	

	gShadows = false;

	// Create objects in the scene

	if (!InitCooking(gAllocator, &gErrorStream)) 
	{
		printf("\nError: Unable to initialize the cooking library, exiting the sample.\n\n");
		return;
	}

	// Load ASE file
	CookASE("fluidSample.ase", gScene, NxVec3(1,10,0));
	CookASE("coolFlow.ase", gScene, NxVec3(1,6,-0), NxVec3(1,0.2,1));
	CloseCooking();

	// Add a box shaped drain.
	NxActorDesc boxDrainActor;
	NxBoxShapeDesc boxDrainShape;
	boxDrainActor.shapes.pushBack(&boxDrainShape);
	boxDrainShape.dimensions.set(40,1,40);
	boxDrainShape.shapeFlags |= NX_SF_FLUID_DRAIN;
	boxDrainActor.globalPose.t.set(0, 0, 0);
	gScene->createActor(boxDrainActor);

	//Pre cook hotspots
	NxBounds3 precookAABB;
	precookAABB.set(NxVec3(-20,-20,-20), NxVec3(20,20,20));
//	gScene->cookFluidMeshHotspot(precookAABB, PACKET_SIZE_MULTIPLIER, REST_PARTICLES_PER_METER, KERNEL_RADIUS_MULTIPLIER, MOTION_LIMIT_MULTIPLIER, COLLISION_DISTANCE_MULTIPLIER );


	//Create a set of initial particles
	ParticleSDK*	initParticles = new ParticleSDK[MAX_PARTICLES];
	unsigned initParticlesNum = 0;

	NxVec3 fluidPos(0, 11.6, 0);
	float distance = 0.1f;
	unsigned sideNum = 16;	
	float rad = sideNum*distance*0.5f;
	for (unsigned i=0; i<sideNum; i++)
		for (unsigned j=0; j<sideNum; j++)
			for (unsigned k=0; k<sideNum; k++)
			{
				NxVec3 p = NxVec3(i*distance,j*distance,k*distance);
				if (p.distance(NxVec3(rad,rad,rad)) < rad)
				{
					p += fluidPos;
					ParticleSDK& newParticle = initParticles[initParticlesNum++];
					newParticle.position = p;
					newParticle.velocity = NxVec3(0,0,0);
				}
			}
	//Setup structure to pass initial particles.
	NxParticleData initParticleData;
	initParticleData.numParticlesPtr		= &initParticlesNum;
	initParticleData.bufferPos				= &initParticles[0].position.x;
	initParticleData.bufferPosByteStride	= sizeof(ParticleSDK);
	initParticleData.bufferVel				= &initParticles[0].velocity.x;
	initParticleData.bufferVelByteStride	= sizeof(ParticleSDK);

	//Setup fluid descriptor
	NxFluidDesc fluidDesc;
	fluidDesc.maxParticles                  	= initParticlesNum;
	fluidDesc.kernelRadiusMultiplier			= KERNEL_RADIUS_MULTIPLIER;
	fluidDesc.restParticlesPerMeter				= REST_PARTICLES_PER_METER;
	fluidDesc.collisionDistanceMultiplier   	= COLLISION_DISTANCE_MULTIPLIER;
	fluidDesc.stiffness							= 50.0f;
	fluidDesc.viscosity							= 22.0f;
	fluidDesc.damping							= 0.0f;
	fluidDesc.restitutionForStaticShapes		= 0.4f;
	fluidDesc.dynamicFrictionForStaticShapes	= 0.03f;
	fluidDesc.simulationMethod					= NX_F_SPH; //NX_F_NO_PARTICLE_INTERACTION;

	if (!gHardwareSimulation)
		fluidDesc.flags &= ~NX_FF_HARDWARE;

	fluidDesc.initialParticleData			= initParticleData;

	//Create user fluid.
	//- create NxFluid in NxScene
	//- setup the buffers to read from data from the SDK
	//- set NxFluid::userData field to MyFluid instance
	bool trackUserData = false;
	bool provideCollisionNormals = false;
	MyFluid* fluid = new MyFluid(gScene, fluidDesc, trackUserData, provideCollisionNormals, NxVec3(0.2f,0.3f,0.7f), 0.03f);
	assert(fluid);
	gMyFluids.pushBack(fluid);

	delete[] initParticles;

	gCameraPos.set(23, 14, 23);
	gCameraForward = fluidPos - NxVec3(0, 3, 0) - gCameraPos;
	gCameraForward.normalize();

}