예제 #1
0
NxFluid* CreateFluid(const NxVec3& pos, NxU32 sideNum, NxReal distance, NxScene* scene)
{
    // Create a set of particles
    gParticleBufferNum = 0;
    NxReal rad = sideNum*distance*0.5f;
    for (NxU32 i = 0; i < sideNum; i++)
    {
        for (NxU32 j = 0; j < sideNum; j++)
        {
            for (NxU32 k = 0; k < sideNum; k++)
            {
                NxVec3 p = NxVec3(i*distance, j*distance, k*distance);
                if (p.distance(NxVec3(rad, rad, rad)) < rad)
                {
                    p += pos - NxVec3(rad, rad, rad);
                    gParticleBuffer[gParticleBufferNum++] = p;
                }
            }
        }
    }
    // 先需要初始化大量粒子的参数
    // Set structure to pass particles, and receive them after every simulation step
    NxParticleData particles;
    //particles.maxParticles			= gParticleBufferCap;
    particles.numParticlesPtr = &gParticleBufferNum;
    particles.bufferPos = &gParticleBuffer[0].x;
    particles.bufferPosByteStride = sizeof(NxVec3);

    // 然后初始化流体的各项参数
    // Create a fluid descriptor
    NxFluidDesc fluidDesc;
    fluidDesc.maxParticles = gParticleBufferCap;
    fluidDesc.kernelRadiusMultiplier = KERNEL_RADIUS_MULTIPLIER;
    fluidDesc.restParticlesPerMeter = REST_PARTICLES_PER_METER;
    fluidDesc.motionLimitMultiplier = MOTION_LIMIT_MULTIPLIER;
    fluidDesc.packetSizeMultiplier = PACKET_SIZE_MULTIPLIER;
    fluidDesc.stiffness = 50;
    fluidDesc.viscosity = 22;
    fluidDesc.restDensity = 1000;
    fluidDesc.damping = 0;
    fluidDesc.restitutionForStaticShapes = 0.4;
    fluidDesc.dynamicFrictionForStaticShapes = 0.3;
    fluidDesc.collisionResponseCoefficient = 0.5f;
    fluidDesc.collisionDistanceMultiplier = 0.1f;
    fluidDesc.simulationMethod = NX_F_SPH; //NX_F_NO_PARTICLE_INTERACTION;
    // 将流体需要的粒子与上述初始化的粒子关联起来
    fluidDesc.initialParticleData = particles;
    fluidDesc.particlesWriteData = particles;
    fluidDesc.flags &= ~NX_FF_HARDWARE;
    fluidDesc.flags |= NX_FF_COLLISION_TWOWAY;

    NxFluid* fl = gScene->createFluid(fluidDesc);
    assert(fl != NULL);
    return fl;
}
예제 #2
0
NxFluid* CreateFluid(const NxVec3& pos, NxU32 sideNum, NxReal distance, NxScene* scene)
{
	float rad = sideNum*distance*0.5;
	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 += pos;
					if(gParticleBufferNum< MAX_PARTICLES)
						gParticleBuffer[gParticleBufferNum++] = p;
				}
			}

	NxParticleData particles;

	//particles.maxParticles			= gParticleBufferCap;
	particles.numParticlesPtr		= &gParticleBufferNum;
	particles.bufferPos				= &gParticleBuffer[0].x;
	particles.bufferPosByteStride	= sizeof(NxVec3);

	//Create a fluid descriptor
	NxFluidDesc fluidDesc;
	fluidDesc.maxParticles = MAX_PARTICLES;
	fluidDesc.flags |= NX_FF_COLLISION_TWOWAY;
	fluidDesc.simulationMethod	= NX_F_SPH;
	fluidDesc.restParticlesPerMeter			= 5.0f;
	fluidDesc.motionLimitMultiplier			= 10.0f;
	fluidDesc.restDensity					= 1000.0f;
	fluidDesc.kernelRadiusMultiplier		= 1.6f;
	fluidDesc.stiffness						= 10.0f;
	fluidDesc.viscosity						= 50.0f;
	fluidDesc.damping						= 0.5f;
	fluidDesc.packetSizeMultiplier			= 16;
	fluidDesc.name                          = "fluid";

	fluidDesc.kernelRadiusMultiplier		= KERNEL_RADIUS_MULTIPLIER;
	fluidDesc.restParticlesPerMeter			= REST_PARTICLES_PER_METER;
	fluidDesc.motionLimitMultiplier			= MOTION_LIMIT_MULTIPLIER;
	fluidDesc.packetSizeMultiplier			= PACKET_SIZE_MULTIPLIER;
	fluidDesc.stiffness						= 40;  // 50
	fluidDesc.viscosity						= 22;
	fluidDesc.restDensity					= 1000;
	fluidDesc.damping						= 0;
// There are some API changes since 280 version, Fluid collision coefficients have been renamed, 
// E.g. NxFluidDesc::dynamicCollisionAdhesion is named NxFluidDesc::dynamicFrictionForDynamicShapes. 
#if NX_SDK_VERSION_NUMBER < 280
	fluidDesc.staticCollisionRestitution = 0.162f;
	fluidDesc.staticCollisionAdhesion = 0.146f;
	fluidDesc.dynamicCollisionRestitution = 0.5f;
	fluidDesc.dynamicCollisionAdhesion = 0.5f;
#else 
	fluidDesc.restitutionForStaticShapes = 0.162f;
	fluidDesc.dynamicFrictionForStaticShapes  = 0.146f;
	fluidDesc.restitutionForDynamicShapes = 0.5f;
	fluidDesc.dynamicFrictionForDynamicShapes = 0.5f;
#endif
	fluidDesc.simulationMethod				= NX_F_SPH;  //NX_F_NO_PARTICLE_INTERACTION;

	fluidDesc.initialParticleData			= particles;
	fluidDesc.particlesWriteData			= particles;

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

    fluid = gScene->createFluid(fluidDesc);
	if(!fluid)
	{
		fluidDesc.flags &= ~NX_FF_HARDWARE;
		bHardwareFluid = false;
		fluid = gScene->createFluid(fluidDesc);
	}
	
	assert(fluid != NULL);
	return fluid;
}
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();

}