aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/LowLevelParticles/src/PtDynamicHelper.h
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/Source/LowLevelParticles/src/PtDynamicHelper.h
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/Source/LowLevelParticles/src/PtDynamicHelper.h')
-rw-r--r--PhysX_3.4/Source/LowLevelParticles/src/PtDynamicHelper.h320
1 files changed, 320 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/LowLevelParticles/src/PtDynamicHelper.h b/PhysX_3.4/Source/LowLevelParticles/src/PtDynamicHelper.h
new file mode 100644
index 00000000..5578a6c6
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevelParticles/src/PtDynamicHelper.h
@@ -0,0 +1,320 @@
+// 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.
+#ifndef PT_DYNAMIC_HELPER_H
+#define PT_DYNAMIC_HELPER_H
+
+#include "PxPhysXConfig.h"
+#if PX_USE_PARTICLE_SYSTEM_API
+
+#include "PtDynamicsKernels.h"
+#include "PtSpatialHash.h"
+#include "PtDynamicsTempBuffers.h"
+
+namespace physx
+{
+
+namespace Pt
+{
+
+//-------------------------------------------------------------------------------------------------------------------//
+
+PX_FORCE_INLINE void updateParticlesPrePass(const SphUpdateType::Enum updateType, PxVec3* forceBuf, Particle* particles,
+ PxU32 numParticles, const DynamicsParameters& params)
+{
+ if(updateType == SphUpdateType::DENSITY)
+ {
+ for(PxU32 i = 0; i < numParticles; ++i)
+ {
+ Pt::Particle& particle = particles[i];
+
+ // Initialize particle densities with self density value
+ particle.density = params.selfDensity;
+ forceBuf[i] = PxVec3(0);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------------------------------------------------//
+
+PX_FORCE_INLINE void updateParticlesPostPass(const SphUpdateType::Enum updateType, PxVec3* forceBuf,
+ Particle* particles, PxU32 numParticles, const DynamicsParameters& params)
+{
+ if(updateType == SphUpdateType::FORCE)
+ {
+ for(PxU32 i = 0; i < numParticles; ++i)
+ {
+ Particle& particle = particles[i];
+
+ forceBuf[i] *= params.scaleToWorld * (1.0f / particle.density);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------------------------------------------------//
+
+/*!
+Given a cell hash table, find neighboring cells and compute particle interactions.
+*/
+void updateCellsSubpacket(SphUpdateType::Enum updateType, PxVec3* __restrict forceBuf, Particle* __restrict particles,
+ const ParticleCell* __restrict cells, const PxU32* __restrict particleIndices,
+ const PxU32 numCellHashBuckets, const DynamicsParameters& params,
+ DynamicsTempBuffers& tempBuffers)
+{
+ PX_ASSERT(particles);
+ PX_ASSERT(cells);
+ PX_ASSERT(particleIndices);
+
+ const ParticleCell* neighborCells[13];
+
+ for(PxU32 c = 0; c < numCellHashBuckets; c++)
+ {
+ const ParticleCell& cell = cells[c];
+
+ if(cell.numParticles == PX_INVALID_U32)
+ continue;
+
+ GridCellVector coords(cell.coords);
+
+ //
+ // To process each pair of neighboring cells only once, a special neighborhood layout can be
+ // used. Thus, we do not need to consider all 26 neighbors of a cell but only half of them.
+ // Going through the list of cells, a cell X might not be aware of a neighboring cell Y with
+ // this layout, however, since cell Y in turn is aware of cell X the pair will still be processed
+ // at the end.
+ //
+
+ // Complete back plane
+ PxU32 cellIdx;
+
+ PxI16 neighbor[13][3] = { { -1, -1, -1 },
+ { 0, -1, -1 },
+ { 1, -1, -1 },
+ { -1, 0, -1 },
+ { 0, 0, -1 },
+ { 1, 0, -1 },
+ { -1, 1, -1 },
+ { 0, 1, -1 },
+ { 1, 1, -1 },
+ { 1, 0, 0 },
+ { -1, 1, 0 },
+ { 0, 1, 0 },
+ { 1, 1, 0 } };
+
+ for(PxU32 n = 0; n < 13; n++)
+ {
+ neighborCells[n] = SpatialHash::findConstCell(
+ cellIdx, GridCellVector(coords.x + neighbor[n][0], coords.y + neighbor[n][1], coords.z + neighbor[n][2]),
+ cells, numCellHashBuckets);
+ }
+
+ // Compute interaction between particles inside the current cell
+ // These calls still produce a lot of LHS. Going from two way to one way updates didn't help. TODO, more
+ // investigation.
+ for(PxU32 p = 1; p < cell.numParticles; p++)
+ {
+ updateParticleGroupPair(forceBuf, forceBuf, particles, particles,
+ particleIndices + cell.firstParticle + p - 1, 1,
+ particleIndices + cell.firstParticle + p, cell.numParticles - p, true,
+ updateType == SphUpdateType::DENSITY, params, tempBuffers.simdPositionsSubpacket,
+ tempBuffers.indexStream);
+ }
+
+ // Compute interaction between particles of current cell and neighboring cells
+ PxU32 srcIndexCount = 0;
+
+ for(PxU32 n = 0; n < 13; n++)
+ {
+ if(!neighborCells[n])
+ continue;
+
+ const ParticleCell* nCell = neighborCells[n];
+
+ for(PxU32 i = nCell->firstParticle, end = nCell->firstParticle + nCell->numParticles; i < end; i++)
+ tempBuffers.mergedIndices[srcIndexCount++] = particleIndices[i];
+ }
+
+ if(srcIndexCount > 0)
+ {
+ updateParticleGroupPair(forceBuf, forceBuf, particles, particles, particleIndices + cell.firstParticle,
+ cell.numParticles, tempBuffers.mergedIndices, srcIndexCount, true,
+ updateType == SphUpdateType::DENSITY, params, tempBuffers.simdPositionsSubpacket,
+ tempBuffers.indexStream);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------------------------------------------------//
+
+/*!
+Given two subpackets, i.e., their cell hash tables and particle arrays, find for each cell of the first subpacket
+the neighboring cells within the second subpacket and compute particle interactions for these neighboring cells.
+*/
+void updateCellsSubpacketPair(SphUpdateType::Enum updateType, PxVec3* __restrict forceBufA, PxVec3* __restrict forceBufB,
+ Particle* __restrict particlesSpA, Particle* __restrict particlesSpB,
+ const ParticleCell* __restrict cellsSpA, const ParticleCell* __restrict cellsSpB,
+ const PxU32* __restrict particleIndicesSpA, const PxU32* __restrict particleIndicesSpB,
+ const PxU32 numCellHashBucketsA, const PxU32 numCellHashBucketsB, bool twoWayUpdate,
+ const DynamicsParameters& params, DynamicsTempBuffers& tempBuffers, bool swapAB)
+{
+ PX_ASSERT(particlesSpA);
+ PX_ASSERT(particlesSpB);
+ PX_ASSERT(cellsSpA);
+ PX_ASSERT(cellsSpB);
+ PX_ASSERT(particleIndicesSpA);
+ PX_ASSERT(particleIndicesSpB);
+
+ const ParticleCell* __restrict srcCell;
+ const ParticleCell* __restrict dstCell;
+ const PxU32* __restrict dstIndices;
+ PxU32 srcBuckets, dstBuckets;
+
+ if(swapAB)
+ {
+ srcCell = cellsSpB;
+ srcBuckets = numCellHashBucketsB;
+
+ dstCell = cellsSpA;
+ dstIndices = particleIndicesSpA;
+ dstBuckets = numCellHashBucketsA;
+ }
+ else
+ {
+ srcCell = cellsSpA;
+ srcBuckets = numCellHashBucketsA;
+
+ dstCell = cellsSpB;
+ dstIndices = particleIndicesSpB;
+ dstBuckets = numCellHashBucketsB;
+ }
+
+ const ParticleCell* neighborCells[27];
+
+ // For the cells of the subpacket A find neighboring cells in the subpacket B.
+ const ParticleCell* pcell_end = srcCell + srcBuckets;
+ for(const ParticleCell* pcell = srcCell; pcell < pcell_end; pcell++)
+ {
+ if(pcell->numParticles != PX_INVALID_U32)
+ {
+ GridCellVector coords(pcell->coords);
+
+ //
+ // Check the 26 neighboring cells plus the cell with the same coordinates but inside the other subpacket
+ //
+
+ // Back plane
+ PxU32 cellIdx;
+ PxI16 neighbor[27][3] = { { -1, -1, -1 },
+ { 0, -1, -1 },
+ { 1, -1, -1 },
+ { -1, 0, -1 },
+ { 0, 0, -1 },
+ { 1, 0, -1 },
+ { -1, 1, -1 },
+ { 0, 1, -1 },
+ { 1, 1, -1 },
+ { -1, -1, 0 },
+ { 0, -1, 0 },
+ { 1, -1, 0 },
+ { -1, 0, 0 },
+ { 0, 0, 0 },
+ { 1, 0, 0 },
+ { -1, 1, 0 },
+ { 0, 1, 0 },
+ { 1, 1, 0 },
+ { -1, -1, 1 },
+ { 0, -1, 1 },
+ { 1, -1, 1 },
+ { -1, 0, 1 },
+ { 0, 0, 1 },
+ { 1, 0, 1 },
+ { -1, 1, 1 },
+ { 0, 1, 1 },
+ { 1, 1, 1 } };
+
+ for(PxU32 n = 0; n < 27; n++)
+ {
+ neighborCells[n] = SpatialHash::findConstCell(
+ cellIdx,
+ GridCellVector(coords.x + neighbor[n][0], coords.y + neighbor[n][1], coords.z + neighbor[n][2]),
+ dstCell, dstBuckets);
+ }
+
+ // Compute interaction between particles of current cell and neighboring cells
+ PxU32 indexCount = 0;
+
+ for(PxU32 n = 0; n < 27; n++)
+ {
+ if(!neighborCells[n])
+ continue;
+
+ const ParticleCell* nCell = neighborCells[n];
+
+ for(PxU32 i = nCell->firstParticle, end = nCell->firstParticle + nCell->numParticles; i < end; i++)
+ tempBuffers.mergedIndices[indexCount++] = dstIndices[i];
+ }
+
+ if(indexCount > 0)
+ {
+
+ if(swapAB)
+ {
+ updateParticleGroupPair(forceBufA, forceBufB, particlesSpA, particlesSpB, tempBuffers.mergedIndices,
+ indexCount, particleIndicesSpB + pcell->firstParticle, pcell->numParticles,
+ twoWayUpdate, updateType == SphUpdateType::DENSITY, params,
+ tempBuffers.simdPositionsSubpacket, tempBuffers.indexStream);
+ }
+ else
+ {
+ updateParticleGroupPair(forceBufA, forceBufB, particlesSpA, particlesSpB,
+ particleIndicesSpA + pcell->firstParticle, pcell->numParticles,
+ tempBuffers.mergedIndices, indexCount, twoWayUpdate,
+ updateType == SphUpdateType::DENSITY, params,
+ tempBuffers.simdPositionsSubpacket, tempBuffers.indexStream);
+ }
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------------------------------------------------//
+
+PX_FORCE_INLINE void normalizeParticleDensity(Particle& particle, const PxF32 selfDensity,
+ const PxF32 densityNormalizationFactor)
+{
+ // normalize density
+ particle.density = (particle.density - selfDensity) * densityNormalizationFactor;
+}
+
+//-------------------------------------------------------------------------------------------------------------------//
+
+} // namespace Pt
+} // namespace physx
+
+#endif // PX_USE_PARTICLE_SYSTEM_API
+#endif // PT_DYNAMIC_HELPER_H