diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysX/src/buffering/ScbParticleSystem.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysX/src/buffering/ScbParticleSystem.cpp')
| -rw-r--r-- | PhysX_3.4/Source/PhysX/src/buffering/ScbParticleSystem.cpp | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysX/src/buffering/ScbParticleSystem.cpp b/PhysX_3.4/Source/PhysX/src/buffering/ScbParticleSystem.cpp new file mode 100644 index 00000000..078f3a24 --- /dev/null +++ b/PhysX_3.4/Source/PhysX/src/buffering/ScbParticleSystem.cpp @@ -0,0 +1,311 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "PxPhysXConfig.h" + +#if PX_USE_PARTICLE_SYSTEM_API + +#include "ScbParticleSystem.h" + +using namespace physx; + +//----------------------------------------------------------------------------// + +// lazy allocate. doesn't reset hasUpdates +void Scb::ParticleSystem::ForceUpdates::initialize(PxU32 maxParticles) +{ + PX_ASSERT((map == NULL) == (values == NULL)); + if (values) + return; + + values = reinterpret_cast<PxVec3*>(PX_ALLOC(maxParticles*sizeof(PxVec3), "PxVec3")); + map = PX_NEW(Cm::BitMap)(); + map->resizeAndClear(maxParticles); +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::ForceUpdates::destroy() +{ + PX_ASSERT((map == NULL) == (values == NULL)); + + if (map) + { + PX_DELETE(map); + map = NULL; + PX_FREE(values); + values = NULL; + } + hasUpdates = false; +} + +//----------------------------------------------------------------------------// + +Scb::ParticleSystem::ParticleSystem(const PxActorType::Enum& actorType, PxU32 maxParticles, bool perParticleRestOffset) +: mParticleSystem(actorType, maxParticles, perParticleRestOffset) +, mReadParticleFluidData(NULL) +{ + setScbType(ScbType::PARTICLE_SYSTEM); +} + +//----------------------------------------------------------------------------// + +Scb::ParticleSystem::~ParticleSystem() +{ + if (mReadParticleFluidData) + PX_DELETE_AND_RESET(mReadParticleFluidData); +} + +//----------------------------------------------------------------------------// + +bool Scb::ParticleSystem::createParticles(const PxParticleCreationData& creationData) +{ + if (isBuffering()) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, + "Particle operations are not allowed while simulation is running."); + return false; + } + else + { + LOCK_PARTICLE_USER_BUFFERS("PxParticleBase::createParticles()") + + bool ret = mParticleSystem.createParticles(creationData); + + return ret; + } +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::releaseParticles(PxU32 numParticles, const PxStrideIterator<const PxU32>& indexBuffer) +{ + LOCK_PARTICLE_USER_BUFFERS("PxParticleBase::releaseParticles()") + + if (numParticles == 0) + return; + + if (isBuffering()) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, + "Particle operations are not allowed while simulation is running."); + return; + } + else + { + mParticleSystem.releaseParticles(numParticles, indexBuffer); + } + + if (mForceUpdatesAcc.hasUpdates) + for (PxU32 i=0; i < numParticles; i++) + mForceUpdatesAcc.clear(indexBuffer[i]); + + if (mForceUpdatesVel.hasUpdates) + for (PxU32 i=0; i < numParticles; i++) + mForceUpdatesVel.clear(indexBuffer[i]); +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::releaseParticles() +{ + LOCK_PARTICLE_USER_BUFFERS("PxParticleBase::releaseParticles()") + + if (isBuffering()) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, + "Particle operations are not allowed while simulation is running."); + return; + } + else + { + mParticleSystem.releaseParticles(); + } + + mForceUpdatesAcc.clear(); + mForceUpdatesVel.clear(); +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::setPositions(PxU32 numParticles, const PxStrideIterator<const PxU32>& indexBuffer, + const PxStrideIterator<const PxVec3>& positionBuffer) +{ + LOCK_PARTICLE_USER_BUFFERS("PxParticleBase::setPositions()") + + if (isBuffering()) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, + "Particle operations are not allowed while simulation is running."); + return; + } + else + { + mParticleSystem.setPositions(numParticles, indexBuffer, positionBuffer); + } +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::setVelocities(PxU32 numParticles, const PxStrideIterator<const PxU32>& indexBuffer, + const PxStrideIterator<const PxVec3>& velocityBuffer) +{ + LOCK_PARTICLE_USER_BUFFERS("PxParticleBase::setVelocities()") + + if (isBuffering()) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, + "Particle operations are not allowed while simulation is running."); + return; + } + else + { + mParticleSystem.setVelocities(numParticles, indexBuffer, velocityBuffer); + } +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::setRestOffsets(PxU32 numParticles, const PxStrideIterator<const PxU32>& indexBuffer, + const PxStrideIterator<const PxF32>& restOffsetBuffer) +{ + LOCK_PARTICLE_USER_BUFFERS("PxParticleBase::setRestOffsets()") + + if (isBuffering()) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, + "Particle operations are not allowed while simulation is running."); + return; + } + else + { + mParticleSystem.setRestOffsets(numParticles, indexBuffer, restOffsetBuffer); + } +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::addForces(PxU32 numParticles, const PxStrideIterator<const PxU32>& indexBuffer, + const PxStrideIterator<const PxVec3>& forceBuffer, PxForceMode::Enum forceMode) +{ + if (isBuffering()) + { + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, + "Particle operations are not allowed while simulation is running."); + return; + } + + PX_ASSERT(numParticles > 0); + PX_ASSERT(indexBuffer.ptr() && indexBuffer.stride() > 0); + + PxReal particleMass = getParticleMass(); + bool isAcceleration = false; + PxReal unitMult = 0.0; + switch(forceMode) + { + case PxForceMode::eFORCE: //!< parameter has unit of mass * distance/ time^2, i.e. a force + unitMult = 1.0f / particleMass; + isAcceleration = true; + break; + case PxForceMode::eIMPULSE: //!< parameter has unit of mass * distance /time + unitMult = 1.0f / particleMass; + isAcceleration = false; + break; + case PxForceMode::eVELOCITY_CHANGE: //!< parameter has unit of distance / time, i.e. the effect is mass independent: a velocity change. + unitMult = 1.0f; + isAcceleration = false; + break; + case PxForceMode::eACCELERATION: //!< parameter has unit of distance/ time^2, i.e. an acceleration. It gets treated just like a force except the mass is not divided out before integration. + unitMult = 1.0f; + isAcceleration = true; + break; + } + + ForceUpdates& forceUpdates = isAcceleration ? mForceUpdatesAcc : mForceUpdatesVel; + forceUpdates.initialize(mParticleSystem.getMaxParticles()); + + for (PxU32 i=0; i < numParticles; i++) + forceUpdates.add(indexBuffer[i], forceBuffer[i] * unitMult); +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::submitForceUpdates(PxReal timeStep) +{ + LOCK_PARTICLE_USER_BUFFERS("PxParticleBase: Apply forces") + + if (mForceUpdatesAcc.hasUpdates) + { + mParticleSystem.addDeltaVelocities(*mForceUpdatesAcc.map, mForceUpdatesAcc.values, timeStep); + mForceUpdatesAcc.clear(); + } + + if (mForceUpdatesVel.hasUpdates) + { + mParticleSystem.addDeltaVelocities(*mForceUpdatesVel.map, mForceUpdatesVel.values, 1.0f); + mForceUpdatesVel.clear(); + } +} + +//----------------------------------------------------------------------------// + +void Scb::ParticleSystem::syncState() +{ + LOCK_PARTICLE_USER_BUFFERS("PxScene::fetchResults()") + + PxU32 flags = getBufferFlags(); + if (flags) // Optimization to avoid all the if-statements below if possible + { + const Buf& buffer = *getParticleSystemBuffer(); + + flush<Buf::BF_Stiffness>(buffer); + flush<Buf::BF_Viscosity>(buffer); + flush<Buf::BF_Damping>(buffer); + flush<Buf::BF_ExternalAcceleration>(buffer); + flush<Buf::BF_ProjectionPlane>(buffer); + flush<Buf::BF_ParticleMass>(buffer); + flush<Buf::BF_Restitution>(buffer); + flush<Buf::BF_DynamicFriction>(buffer); + flush<Buf::BF_StaticFriction>(buffer); + + if (flags & Buf::BF_ResetFiltering) + mParticleSystem.resetFiltering(); + + flush<Buf::BF_SimulationFilterData>(buffer); + flush<Buf::BF_Flags>(buffer); + + Actor::syncState(); + } + + postSyncState(); +} + +//----------------------------------------------------------------------------// + +#endif // PX_USE_PARTICLE_SYSTEM_API |