aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Samples/SampleBase/ParticleEmitter.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Samples/SampleBase/ParticleEmitter.cpp
downloadphysx-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/Samples/SampleBase/ParticleEmitter.cpp')
-rw-r--r--PhysX_3.4/Samples/SampleBase/ParticleEmitter.cpp210
1 files changed, 210 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleBase/ParticleEmitter.cpp b/PhysX_3.4/Samples/SampleBase/ParticleEmitter.cpp
new file mode 100644
index 00000000..8d9d513f
--- /dev/null
+++ b/PhysX_3.4/Samples/SampleBase/ParticleEmitter.cpp
@@ -0,0 +1,210 @@
+// 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 "ParticleEmitterRate.h"
+
+//----------------------------------------------------------------------------//
+
+#if PARTICLE_EMITTER_RANDOMIZE_EMISSION
+PxToolkit::BasicRandom ParticleEmitter::mRandom(42);
+#endif
+
+ParticleEmitter::ParticleEmitter(Shape::Enum shape, PxReal extentX, PxReal extentY, PxReal spacing) :
+ mRandomPos(0.0f),
+ mRandomAngle(0.0f),
+ mVelocity(1.0f),
+ mParticleMass(0.0f),
+ mNumSites(0),
+ mSpacingX(spacing),
+ mLocalPose(PxTransform()),
+ mFrameBody(NULL),
+ mExtentX(extentX),
+ mExtentY(extentY),
+ mShape(shape)
+{
+ PX_ASSERT(spacing > 0.0f);
+ updateDerivedBase();
+}
+
+//----------------------------------------------------------------------------//
+
+ParticleEmitter::~ParticleEmitter()
+{
+
+}
+
+//----------------------------------------------------------------------------//
+
+void ParticleEmitter::updateDerivedBase()
+{
+ PX_ASSERT(mSpacingX > 0.0f);
+ mSpacingY = mSpacingX * PxSqrt(3.0f) * 0.5f;
+ mSpacingZ = mSpacingX;
+
+ mNumX = 2*(int)floor(mExtentX/mSpacingX);
+ mNumY = 2*(int)floor(mExtentY/mSpacingY);
+
+ //SDS: limit minimal dimension to 1
+ if (mNumX == 0)
+ {
+ mNumX = 1;
+ mSpacingX = 0.0f;
+ }
+ if (mNumY == 0)
+ {
+ mNumY = 1;
+ mSpacingY = 0.0f;
+ }
+
+ mNumSites = mNumX * mNumY;
+
+ if (mShape == Shape::eELLIPSE)
+ {
+ if (mNumX > 1)
+ mEllipseRadius2 = 0.5f - 1.0f/(mNumX-1);
+ else
+ mEllipseRadius2 = 0.5f;
+ mEllipseRadius2 *= mEllipseRadius2;
+
+ mEllipseConstX0 = (mNumX-0.5f) * 0.5f;
+ mEllipseConstX1 = 1.0f/mNumX;
+ mEllipseConstY0 = (mNumY-1.0f) * 0.5f;
+ mEllipseConstY1 = PxSqrt(3.0f) * 0.5f / mNumY;
+ }
+ else
+ {
+ mEllipseRadius2 = 0;
+ mEllipseConstX0 = 0;
+ mEllipseConstX1 = 0;
+ mEllipseConstY0 = 0;
+ mEllipseConstY1 = 0;
+ }
+}
+
+//----------------------------------------------------------------------------//
+
+void ParticleEmitter::step(ParticleData& particles, PxReal dt, const PxVec3& externalAcceleration, PxReal maxParticleVelocity)
+{
+ initStep(particles, dt);
+ stepInternal(particles, dt, externalAcceleration, maxParticleVelocity);
+ finalizeStep();
+}
+
+//----------------------------------------------------------------------------//
+
+void ParticleEmitter::initStep(ParticleData& particles, PxReal dt)
+{
+ mLinMomentum = PxVec3(0.0f);
+ mAngMomentum = PxVec3(0.0f);
+
+ // state of frameBody
+ if (mFrameBody)
+ {
+ mBodyAngVel = mFrameBody->getAngularVelocity();
+ mBodyLinVel = mFrameBody->getLinearVelocity();
+ mBodyCenter = mFrameBody->getGlobalPose().p;
+ mGlobalPose = mFrameBody->getGlobalPose() * mLocalPose;
+ }
+ else
+ {
+ mBodyAngVel = PxVec3(0.0f);
+ mBodyLinVel = PxVec3(0.0f);
+ mBodyCenter = PxVec3(0.0f);
+ mGlobalPose = mLocalPose;
+ }
+
+ mAxisX = mGlobalPose.q.getBasisVector0();
+ mAxisY = mGlobalPose.q.getBasisVector1();
+ mAxisZ = mGlobalPose.q.getBasisVector2();
+
+ mBasePos = mGlobalPose.p
+ - mAxisX * (mNumX-0.5f)*0.5f*mSpacingX
+ - mAxisY * (mNumY-1.0f)*0.5f*mSpacingY;
+}
+
+//----------------------------------------------------------------------------//
+
+void ParticleEmitter::finalizeStep()
+{
+ // apply impulse on attached body
+ if (mFrameBody && mParticleMass > 0.0f)
+ {
+ mLinMomentum *= mParticleMass;
+ mAngMomentum *= mParticleMass;
+
+ mFrameBody->addForce(mLinMomentum, PxForceMode::eIMPULSE);
+ mFrameBody->addTorque(mAngMomentum, PxForceMode::eIMPULSE);
+ }
+}
+
+//----------------------------------------------------------------------------//
+
+void ParticleEmitter::computeSiteVelocity(PxVec3& siteVel, const PxVec3& sitePos)
+{
+ //velocity dir noise
+ PxReal noiseXYAngle = randInRange(0.0f, PxTwoPi);
+ PxReal noiseZAngle = randInRange(0.0f, mRandomAngle);
+
+ PxVec3 noiseDirVec = mAxisX * PxCos(noiseXYAngle) + mAxisY * PxSin(noiseXYAngle);
+ noiseDirVec.normalize();
+ noiseDirVec = mAxisZ * PxCos(noiseZAngle) + noiseDirVec * PxSin(noiseZAngle);
+
+ siteVel = noiseDirVec * mVelocity;
+
+ //add emitter repulsion
+ if (mParticleMass > 0.0f)
+ {
+ mLinMomentum -= siteVel;
+ mAngMomentum -= (sitePos - mBodyCenter).cross(siteVel);
+ }
+
+ if (mFrameBody)
+ siteVel += mBodyLinVel + (mBodyAngVel.cross(sitePos - mBodyCenter));
+}
+
+//----------------------------------------------------------------------------//
+
+bool ParticleEmitter::spawnParticle(ParticleData& data,
+ PxU32& num,
+ const PxU32 max,
+ const PxVec3& position,
+ const PxVec3& velocity)
+{
+ PX_ASSERT(PxI32(max) - PxI32(num) <= PxI32(data.maxParticles) - PxI32(data.numParticles));
+ if(num >= max)
+ return false;
+
+ data.positions[data.numParticles] = position;
+ data.velocities[data.numParticles] = velocity;
+ data.numParticles++;
+ num++;
+ return true;
+}
+
+//----------------------------------------------------------------------------//