NxFluid* CreateFluid() { // Create fluid NxFluidDesc fluidDesc; fluidDesc.setToDefault(); fluidDesc.kernelRadiusMultiplier = 2.0f; fluidDesc.restParticlesPerMeter = 5.0f; fluidDesc.motionLimitMultiplier = 3.0f; fluidDesc.packetSizeMultiplier = 8; fluidDesc.collisionDistanceMultiplier = 0.1; fluidDesc.stiffness = 50.0f; fluidDesc.viscosity = 40.0f; fluidDesc.restDensity = 1000.0f; fluidDesc.damping = 0.0f; // 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; fluidDesc.maxParticles = MAX_PARTICLES; gParticles = new NxVec3[fluidDesc.maxParticles]; fluidDesc.particlesWriteData.bufferPos = &gParticles[0].x; fluidDesc.particlesWriteData.bufferPosByteStride = sizeof(NxVec3); fluidDesc.particlesWriteData.bufferVel = 0; fluidDesc.particlesWriteData.bufferVelByteStride = 0; //fluidDesc.particlesWriteData.maxParticles = fluidDesc.maxParticles; fluidDesc.particlesWriteData.numParticlesPtr = &gNumParticles; if(!bHardwareFluid) fluidDesc.flags &= ~NX_FF_HARDWARE; NxFluid* mFluid = gScene->createFluid(fluidDesc); if(!mFluid) { fluidDesc.flags &= ~NX_FF_HARDWARE; bHardwareFluid = false; mFluid = gScene->createFluid(fluidDesc); } return mFluid; }
std::shared_ptr<Fluid> PhysicsLib::createFluid(FluidType fluidType, int maxParticles, float fluidStaticRestitution, float fluidStaticAdhesion, float fluidDynamicRestitution, float fluidDynamicAdhesion, float fluidDamping, float fluidStiffness, float fluidViscosity, float fluidKernelRadiusMultiplier, float fluidRestParticlesPerMeter, float fluidRestDensity, float fluidMotionLimit, int fluidPacketSizeMultiplier, int collGroup) { Fluid *fluid = 0; if(data->scene) { NxFluidDesc fluidDesc; fluidDesc.setToDefault(); fluidDesc.flags |= NX_FF_DISABLE_GRAVITY; fluidDesc.maxParticles = maxParticles; fluidDesc.kernelRadiusMultiplier = fluidKernelRadiusMultiplier; fluidDesc.restParticlesPerMeter = fluidRestParticlesPerMeter; fluidDesc.stiffness = fluidStiffness; fluidDesc.viscosity = fluidViscosity; fluidDesc.restDensity = fluidRestDensity; fluidDesc.damping = fluidDamping; fluidDesc.restitutionForStaticShapes = fluidStaticRestitution; fluidDesc.dynamicFrictionForStaticShapes = fluidStaticAdhesion; fluidDesc.restitutionForDynamicShapes = fluidDynamicRestitution; fluidDesc.dynamicFrictionForDynamicShapes = fluidDynamicAdhesion; fluidDesc.collisionGroup = collGroup; fluidDesc.packetSizeMultiplier = /*8*/ fluidPacketSizeMultiplier; // Optimize this //fluidDesc.motionLimitMultiplier = 3.f * fluidDesc.kernelRadiusMultiplier; fluidDesc.motionLimitMultiplier = fluidMotionLimit * fluidDesc.restParticlesPerMeter; if(fluidType == FLUID_TYPE_SIMPLE) fluidDesc.simulationMethod = NX_F_NO_PARTICLE_INTERACTION; else { //fluidDesc.simulationMethod = NX_F_SPH; fluidDesc.simulationMethod = NX_F_MIXED_MODE; } fluid = new Fluid(*data->scene, fluidDesc, data->runningInHardware); if(!fluid->isValid()) { delete fluid; fluid = 0; } } return std::shared_ptr<Fluid> (fluid); }
//----------------------------------------------------------------------- void PhysXFluidExternPropertyWindow::_initProperties(void) { // Set the (internationalized) property names PRNL_PHYSX_REST_PARTICLE_PER_METER = _("Rest particle per meter"); PRNL_PHYSX_REST_DENSITY = _("Rest density"); PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER = _("Kernel radius multiplier"); PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER = _("Motion limit multiplier"); PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER = _("Collision dist. multiplier"); PRNL_PHYSX_PACKET_SIZE_MULTIPLIER = _("Packet size multiplier"); PRNL_PHYSX_STIFFNESS = _("Stiffness"); PRNL_PHYSX_VISCOSITY = _("Viscosity"); PRNL_PHYSX_SURFACE_TENSION = _("Surface tension"); PRNL_PHYSX_DAMPING = _("Damping"); PRNL_PHYSX_EXTERNAL_ACCELERATION = _("External acceleration"); PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES = _("Restitution static shapes"); PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES = _("Dyn. friction static shapes"); PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES = _("Static friction static shapes"); PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES = _("Attraction static shapes"); PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES = _("Restitution dynamic shapes"); PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES = _("Dyn. friction dyn. shapes"); PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES = _("Static friction dyn. shapes"); PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES = _("Attraction dynamic shapes"); PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT = _("Collision response coeff."); PRNL_PHYSX_SIMULATION_METHOD = _("Simulation method"); PRNL_PHYSX_COLLISION_METHOD = _("Collision method"); PRNL_PHYSX_FLAG_VISUALIZATION = _("Visualisation"); PRNL_PHYSX_FLAG_DISABLE_GRAVITY = _("Disable gravity"); PRNL_PHYSX_FLAG_COLLISION_TWOWAY = _("Collision twoway"); PRNL_PHYSX_FLAG_FLUID_ENABLED = _("Fluid enabled"); PRNL_PHYSX_FLAG_HARDWARE = _("Hardware"); PRNL_PHYSX_FLAG_PRIORITY_MODE = _("Priority mode"); PRNL_PHYSX_FLAG_PROJECT_TO_PLANE = _("Project to plane"); PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT = _("Strict cooking format"); PHYSX_INTERCOLLISION = _("Intercollision"); PHYSX_NOINTERCOLLISION = _("Non-intercollision"); PHYSX_MIX_INTERCOLLISION = _("Mixed intercollision"); PHYSX_STATIC = _("Static"); PHYSX_DYNAMIC = _("Dynamic"); mHelpHtml = wxT("ExternPhysXFluid.html"); NxFluidDesc fluidDesc; fluidDesc.setToDefault(); // Rest particle per meter: NxReal Append(wxFloatProperty(PRNL_PHYSX_REST_PARTICLE_PER_METER, PRNL_PHYSX_REST_PARTICLE_PER_METER, fluidDesc.restParticlesPerMeter)); SetPropertyEditor(PRNL_PHYSX_REST_PARTICLE_PER_METER, wxPG_EDITOR(SpinCtrl)); // Rest density: NxReal Append(wxFloatProperty(PRNL_PHYSX_REST_DENSITY, PRNL_PHYSX_REST_DENSITY, fluidDesc.restDensity)); SetPropertyEditor(PRNL_PHYSX_REST_DENSITY, wxPG_EDITOR(SpinCtrl)); // Kernel radius multiplier: NxReal Append(wxFloatProperty(PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, fluidDesc.kernelRadiusMultiplier)); SetPropertyEditor(PRNL_PHYSX_KERNEL_RADIUS_MULTIPLIER, wxPG_EDITOR(SpinCtrl)); // Motion limit multiplier: NxReal Append(wxFloatProperty(PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, fluidDesc.motionLimitMultiplier)); SetPropertyEditor(PRNL_PHYSX_MOTION_LIMIT_MULTIPLIER, wxPG_EDITOR(SpinCtrl)); // Collision distance multiplier: NxReal Append(wxFloatProperty(PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, fluidDesc.collisionDistanceMultiplier)); SetPropertyEditor(PRNL_PHYSX_COLLISION_DISTANCE_MULTIPLIER, wxPG_EDITOR(SpinCtrl)); // Packet size multiplier: NxU32 Append(wxUIntProperty(PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, fluidDesc.packetSizeMultiplier)); SetPropertyEditor(PRNL_PHYSX_PACKET_SIZE_MULTIPLIER, wxPG_EDITOR(SpinCtrl)); // Stiffness: NxReal Append(wxFloatProperty(PRNL_PHYSX_STIFFNESS, PRNL_PHYSX_STIFFNESS, fluidDesc.stiffness)); SetPropertyEditor(PRNL_PHYSX_STIFFNESS, wxPG_EDITOR(SpinCtrl)); // Viscosity: NxReal Append(wxFloatProperty(PRNL_PHYSX_VISCOSITY, PRNL_PHYSX_VISCOSITY, fluidDesc.viscosity)); SetPropertyEditor(PRNL_PHYSX_VISCOSITY, wxPG_EDITOR(SpinCtrl)); // Surface tension: NxReal Append(wxFloatProperty(PRNL_PHYSX_SURFACE_TENSION, PRNL_PHYSX_SURFACE_TENSION, fluidDesc.surfaceTension)); SetPropertyEditor(PRNL_PHYSX_SURFACE_TENSION, wxPG_EDITOR(SpinCtrl)); // Damping: NxReal Append(wxFloatProperty(PRNL_PHYSX_DAMPING, PRNL_PHYSX_DAMPING, fluidDesc.damping)); SetPropertyEditor(PRNL_PHYSX_DAMPING, wxPG_EDITOR(SpinCtrl)); // External acceleration: NxVec3 appendVector3(PRNL_PHYSX_EXTERNAL_ACCELERATION, PRNL_PHYSX_EXTERNAL_ACCELERATION, ParticleUniverse::PhysXMath::convert(fluidDesc.externalAcceleration)); // Restitution for static shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, fluidDesc.restitutionForStaticShapes)); SetPropertyEditor(PRNL_PHYSX_RESTITUTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Dynamic friction for static shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, fluidDesc.dynamicFrictionForStaticShapes)); SetPropertyEditor(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Static friction for static shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, fluidDesc.staticFrictionForStaticShapes)); SetPropertyEditor(PRNL_PHYSX_STATIC_FRICTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Attraction for static shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, fluidDesc.attractionForStaticShapes)); SetPropertyEditor(PRNL_PHYSX_ATTRACTION_FOR_STATIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Restitution for dynamic shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, fluidDesc.restitutionForDynamicShapes)); SetPropertyEditor(PRNL_PHYSX_RESTITUTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Dynamic friction for dynamic shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, fluidDesc.dynamicFrictionForDynamicShapes)); SetPropertyEditor(PRNL_PHYSX_DYNAMIC_FRICTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Static friction for dynamic shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, fluidDesc.staticFrictionForDynamicShapes)); SetPropertyEditor(PRNL_PHYSX_STATIC_FRICTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Attraction for dynamic shapes: NxReal Append(wxFloatProperty(PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, fluidDesc.attractionForDynamicShapes)); SetPropertyEditor(PRNL_PHYSX_ATTRACTION_FOR_DYNAMIC_SHAPES, wxPG_EDITOR(SpinCtrl)); // Collision response coefficient: NxReal Append(wxFloatProperty(PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, fluidDesc.collisionResponseCoefficient)); SetPropertyEditor(PRNL_PHYSX_COLLISION_RESPONSE_COEFFICIENT, wxPG_EDITOR(SpinCtrl)); // Collision group: NxCollisionGroup Append(wxUIntProperty(PRNL_PHYSX_COLLISION_GROUP, PRNL_PHYSX_COLLISION_GROUP, fluidDesc.collisionGroup)); SetPropertyEditor(PRNL_PHYSX_COLLISION_GROUP, wxPG_EDITOR(SpinCtrl)); // Simulation method: List wxArrayString simulationMethod; simulationMethod.Add(PHYSX_INTERCOLLISION); simulationMethod.Add(PHYSX_NOINTERCOLLISION); simulationMethod.Add(PHYSX_MIX_INTERCOLLISION); wxPGId pid = Append(wxEnumProperty(PRNL_PHYSX_SIMULATION_METHOD, PRNL_PHYSX_SIMULATION_METHOD, simulationMethod)); // Collision method: List wxArrayString collisionMethod; collisionMethod.Add(PHYSX_STATIC); collisionMethod.Add(PHYSX_DYNAMIC); wxPGId pid2 = Append(wxEnumProperty(PRNL_PHYSX_COLLISION_METHOD, PRNL_PHYSX_COLLISION_METHOD, collisionMethod)); // Visualisation: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_VISUALIZATION, PRNL_PHYSX_FLAG_VISUALIZATION, fluidDesc.flags & NX_FF_VISUALIZATION)); // Disable gravity: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_DISABLE_GRAVITY, PRNL_PHYSX_FLAG_DISABLE_GRAVITY, fluidDesc.flags & NX_FF_DISABLE_GRAVITY)); // Collision twoway: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_COLLISION_TWOWAY, PRNL_PHYSX_FLAG_COLLISION_TWOWAY, fluidDesc.flags & NX_FF_COLLISION_TWOWAY)); // Fluid enabled: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_FLUID_ENABLED, PRNL_PHYSX_FLAG_FLUID_ENABLED, fluidDesc.flags & NX_FF_ENABLED)); // Hardware: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_HARDWARE, PRNL_PHYSX_FLAG_HARDWARE, fluidDesc.flags & NX_FF_HARDWARE)); // Priority mode: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_PRIORITY_MODE, PRNL_PHYSX_FLAG_PRIORITY_MODE, fluidDesc.flags & NX_FF_PRIORITY_MODE)); // Project to plane: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_PROJECT_TO_PLANE, PRNL_PHYSX_FLAG_PROJECT_TO_PLANE, fluidDesc.flags & NX_FF_PROJECT_TO_PLANE)); // Strict cooking format: bool Append(wxBoolProperty(PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT, PRNL_PHYSX_FLAG_STRICT_COOKING_FORMAT, fluidDesc.flags & NX_FF_FORCE_STRICT_COOKING_FORMAT)); }
NxPhysicsFluid::NxPhysicsFluid( NxPhysicsActor * Actor, const NxParticleDesc & Desc ) { LogMsg("Creating fluid ...."); //Create a set of initial particles ParticleSDK * initParticles = new ParticleSDK[ Desc.NumParticles ]; unsigned initParticlesNum = 0; //Setup structure to pass initial particles. NxParticleData initParticleData; initParticlesNum = 0; 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.setToDefault(); fluidDesc.maxParticles = Desc.NumParticles; fluidDesc.kernelRadiusMultiplier = 2.0f; fluidDesc.restParticlesPerMeter = 10.0f; fluidDesc.motionLimitMultiplier = 3.0f; fluidDesc.packetSizeMultiplier = 8; fluidDesc.collisionDistanceMultiplier = 0.12; fluidDesc.stiffness = 50.0f; fluidDesc.viscosity = 40.0f; fluidDesc.restDensity = 1000.0f; // Target density for the fluid (water is about 1000). fluidDesc.damping = 0.0f; //Must be between 0 and 1. // //A value of 0 causes the colliding particle to get a zero velocity component in the //direction of the surface normal of the static shape at the collision location; i.e. //it will not bounce. // //A value of 1 causes a particle's velocity component in the direction of the surface normal to invert; //i.e. the particle bounces off the surface with the same velocity magnitude as it had before collision. //(Caution: values near 1 may have a negative impact on stability) fluidDesc.restitutionForStaticShapes = 1.0f; //Must be between 0 and 1. // //A value of 1 will cause the particle to lose its velocity tangential to //the surface normal of the shape at the collision location; i.e. it will not slide //along the surface. // //A value of 0 will preserve the particle's velocity in the tangential surface //direction; i.e. it will slide without resistance on the surface. fluidDesc.dynamicFrictionForStaticShapes= 1.0f; //brief Defines the restitution coefficient used for collisions of the fluid particles with dynamic shapes. //Must be between 0 and 1. //(Caution: values near 1 may have a negative impact on stability) fluidDesc.restitutionForDynamicShapes = 0.2f; fluidDesc.restitutionForStaticShapes = 0.5f; fluidDesc.dynamicFrictionForStaticShapes = 0.05f; fluidDesc.staticFrictionForStaticShapes = 0.05f; fluidDesc.attractionForStaticShapes = 0.0f; fluidDesc.restitutionForDynamicShapes = 0.5f; fluidDesc.dynamicFrictionForDynamicShapes = 0.5f; fluidDesc.staticFrictionForDynamicShapes = 0.5f; fluidDesc.attractionForDynamicShapes = 0.0f; fluidDesc.collisionResponseCoefficient = 0.2f; fluidDesc.collisionMethod = NX_F_STATIC|NX_F_DYNAMIC; fluidDesc.simulationMethod = NX_F_NO_PARTICLE_INTERACTION;//NX_F_NO_PARTICLE_INTERACTION;//NX_F_MIXED_MODE;// ; //NX_F_MIXED_MODE : has too much presure ! //brief Acceleration (m/s^2) applied to all particles at all time steps. Useful to simulate smoke or fire. //This acceleration is additive to the scene gravity. The scene gravity can be turned off //for the fluid, using the flag NX_FF_DISABLE_GRAVITY. //@see NxFluid.getExternalAcceleration() NxFluid.setExternalAcceleration() fluidDesc.externalAcceleration = NxVec3( 0,1,0 ); //fluidDesc.flags &= ~NX_FF_VISUALIZATION; // visualize or not fluidDesc.flags |= NX_FF_HARDWARE; if (!NxScene3DPhysicsManager::getSingleton().HasPhysxHardwareAcceleration()){ fluidDesc.flags &= ~NX_FF_HARDWARE; LogMsg("Fluids created in software mode."); }else{ LogMsg("Fluids created in Hardware mode."); } fluidDesc.initialParticleData = initParticleData; //Add initial particles to fluid creation. //AxisAlignedBox aabBounds; //aabBounds.setInfinite(); //ParticleBase->setBounds( aabBounds ); bool trackUserData = false; bool provideCollisionNormals = false; float particlesize = 0.001f; // 0.03 f NxVec3 particleColor = NxVec3(0.4f,0.5f,0.9f); Actor->GetNxActor()->raiseActorFlag( NX_AF_FLUID_DISABLE_COLLISION ); mFluid = new MyFluid( &Actor->GetNxActor()->getScene(), fluidDesc, trackUserData, provideCollisionNormals, particleColor , particlesize); LogMsg("Creating fluid done"); //assert( Fluid ); delete[] initParticles; }