aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h
diff options
context:
space:
mode:
Diffstat (limited to 'APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h')
-rw-r--r--APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h288
1 files changed, 288 insertions, 0 deletions
diff --git a/APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h b/APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h
new file mode 100644
index 00000000..86278a0f
--- /dev/null
+++ b/APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, 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.
+ */
+
+
+#ifndef __PARTICLE_IOS_COMMON_CODE_H__
+#define __PARTICLE_IOS_COMMON_CODE_H__
+
+#include "ParticleIosCommon.h"
+
+
+namespace nvidia
+{
+namespace pxparticleios
+{
+
+#ifdef __CUDACC__
+
+#define SIM_FETCH(name, idx) tex1Dfetch(KERNEL_TEX_REF(name), idx)
+#define SIM_FLOAT4 float4
+#define SIM_INT_AS_FLOAT(x) *(const float*)(&x)
+#define SIM_INJECTOR_ARRAY const InjectorParamsArray&
+#define SIM_FETCH_INJECTOR(injectorArray, injParams, injector) injectorArray.fetchElem(INPLACE_STORAGE_ARGS_VAL, injParams, injector)
+
+PX_CUDA_CALLABLE PX_INLINE float splitFloat4(PxVec3& v3, const SIM_FLOAT4& f4)
+{
+ v3.x = f4.x;
+ v3.y = f4.y;
+ v3.z = f4.z;
+ return f4.w;
+}
+PX_CUDA_CALLABLE PX_INLINE SIM_FLOAT4 combineFloat4(const PxVec3& v3, float w)
+{
+ return make_float4(v3.x, v3.y, v3.z, w);
+}
+
+struct PxInternalParticleFlagGpu
+{
+ enum Enum
+ {
+ //reserved (1<<0),
+ //reserved (1<<1),
+ //reserved (1<<2),
+ //reserved (1<<3),
+ //reserved (1<<4),
+ //reserved (1<<5),
+ eCUDA_NOTIFY_CREATE = (1 << 6),
+ eCUDA_NOTIFY_SET_POSITION = (1 << 7),
+ };
+};
+struct PxParticleFlag
+{
+ enum Enum
+ {
+ eVALID = (1 << 0),
+ eCOLLISION_WITH_STATIC = (1 << 1),
+ eCOLLISION_WITH_DYNAMIC = (1 << 2),
+ eCOLLISION_WITH_DRAIN = (1 << 3),
+ eSPATIAL_DATA_STRUCTURE_OVERFLOW = (1 << 4),
+ };
+};
+struct PxParticleFlagGpu
+{
+ uint16_t api; // PxParticleFlag
+ uint16_t low; // PxInternalParticleFlagGpu
+};
+
+#else
+
+#define SIM_FETCH(name, idx) mem##name[idx]
+#define SIM_FLOAT4 PxVec4
+#define SIM_INT_AS_FLOAT(x) *(const float*)(&x)
+#define SIM_INJECTOR_ARRAY const Px3InjectorParams*
+#define SIM_FETCH_INJECTOR(injectorArray, injParams, injector) { injParams = injectorArray[injector]; }
+
+PX_INLINE float splitFloat4(PxVec3& v3, const SIM_FLOAT4& f4)
+{
+ v3 = f4.getXYZ();
+ return f4.w;
+}
+PX_INLINE SIM_FLOAT4 combineFloat4(const PxVec3& v3, float w)
+{
+ return PxVec4(v3.x, v3.y, v3.z, w);
+}
+
+#endif
+
+
+APEX_CUDA_CALLABLE PX_INLINE float calcParticleBenefit(
+ const Px3InjectorParams& inj, const PxVec3& eyePos,
+ const PxVec3& pos, const PxVec3& vel, float life)
+{
+ float benefit = inj.mLODBias;
+ //distance term
+ float distance = (eyePos - pos).magnitude();
+ benefit += inj.mLODDistanceWeight * (1.0f - PxMin(1.0f, distance / inj.mLODMaxDistance));
+ //velocity term, TODO: clamp velocity
+ float velMag = vel.magnitude();
+ benefit += inj.mLODSpeedWeight * velMag;
+ //life term
+ benefit += inj.mLODLifeWeight * life;
+
+ return PxClamp(benefit, 0.0f, 1.0f);
+}
+
+
+
+INPLACE_TEMPL_VA_ARGS_DEF(typename FieldAccessor)
+APEX_CUDA_CALLABLE PX_INLINE float simulateParticle(
+ INPLACE_STORAGE_ARGS_DEF, SIM_INJECTOR_ARRAY injectorArray,
+ float deltaTime,
+ PxVec3 eyePos,
+ bool isNewParticle,
+ unsigned int srcIdx,
+ unsigned int dstIdx,
+ SIM_FLOAT4* memPositionMass,
+ SIM_FLOAT4* memVelocityLife,
+ SIM_FLOAT4* memCollisionNormalFlags,
+ uint32_t* memUserData,
+ IofxActorIDIntl* memIofxActorIDs,
+ float* memLifeSpan,
+ float* memLifeTime,
+ float* memDensity,
+ unsigned int* memInjector,
+ FieldAccessor& fieldAccessor,
+ unsigned int &injIndex,
+ const GridDensityParams params,
+#ifdef __CUDACC__
+ SIM_FLOAT4* memPxPosition,
+ SIM_FLOAT4* memPxVelocity,
+ SIM_FLOAT4* memPxCollision,
+ float* memPxDensity,
+ unsigned int* memNvFlags
+#else
+ PxVec3& position,
+ PxVec3& velocity,
+ PxVec3& collisionNormal,
+ uint32_t& particleFlags,
+ float& density
+#endif
+)
+{
+ CPU_INPLACE_STORAGE_ARGS_UNUSED
+ PX_UNUSED(memCollisionNormalFlags);
+ PX_UNUSED(memDensity);
+ PX_UNUSED(fieldAccessor);
+ PX_UNUSED(params);
+
+ float mass;
+#ifdef __CUDACC__
+ PxVec3 position;
+ PxVec3 velocity;
+ PxVec3 collisionNormal;
+ uint32_t particleFlags;
+ float density;
+#endif
+
+ //read
+ float lifeSpan = SIM_FETCH(LifeSpan, srcIdx);
+ unsigned int injector = SIM_FETCH(Injector, srcIdx);
+ IofxActorIDIntl iofxActorID = IofxActorIDIntl(SIM_FETCH(IofxActorIDs, srcIdx));
+
+ float lifeTime = lifeSpan;
+ if (!isNewParticle)
+ {
+ lifeTime = SIM_FETCH(LifeTime, srcIdx);
+ lifeTime = PxMax(lifeTime - deltaTime, 0.0f);
+
+#ifndef __CUDACC__
+ mass = memPositionMass[srcIdx].w;
+
+ /* Apply field sampler velocity */
+ fieldAccessor(srcIdx, velocity);
+#endif
+ }
+ else
+ {
+ collisionNormal = PxVec3(0.0f);
+ particleFlags = 0;
+ density = 0.0f;
+ splitFloat4(velocity, SIM_FETCH(VelocityLife, srcIdx));
+#ifdef __CUDACC__
+ }
+ {
+#endif
+ mass = splitFloat4(position, SIM_FETCH(PositionMass, srcIdx));
+ }
+
+#ifdef __CUDACC__
+ if (isNewParticle)
+ {
+ memPxPosition[dstIdx] = combineFloat4(position, 0);
+ memPxVelocity[dstIdx] = combineFloat4(velocity, 0);
+
+ PxParticleFlagGpu flags;
+ flags.api = PxParticleFlag::eVALID;
+ flags.low = PxInternalParticleFlagGpu::eCUDA_NOTIFY_CREATE;
+ memNvFlags[dstIdx] = *((unsigned int*)&flags);
+ }
+ else
+ {
+ const SIM_FLOAT4 pxPosition = SIM_FETCH(PxPosition, srcIdx);
+ const SIM_FLOAT4 pxVelocity = SIM_FETCH(PxVelocity, srcIdx);
+
+ if (memPxDensity)
+ {
+ density = SIM_FETCH(PxDensity, srcIdx);
+ memPxDensity[dstIdx] = density;
+ }
+ splitFloat4(position, pxPosition);
+ splitFloat4(velocity, pxVelocity);
+
+ PxParticleFlagGpu flags;
+ *((uint32_t*)&flags) = SIM_FETCH(NvFlags, srcIdx);
+
+ /* Apply field sampler velocity */
+ fieldAccessor(srcIdx, velocity);
+ memPxVelocity[dstIdx] = combineFloat4(velocity, pxVelocity.w);
+
+ splitFloat4(collisionNormal, SIM_FETCH(PxCollision, srcIdx));
+ particleFlags = flags.api;
+
+ if (dstIdx != srcIdx)
+ {
+ memPxPosition[dstIdx] = pxPosition;
+
+ flags.low |= PxInternalParticleFlagGpu::eCUDA_NOTIFY_SET_POSITION;
+ memNvFlags[dstIdx] = *((uint32_t*)&flags);
+ }
+ }
+#endif
+
+ Px3InjectorParams injParams;
+ SIM_FETCH_INJECTOR(injectorArray, injParams, injector);
+ injIndex = injParams.mLocalIndex;
+ // injParams.mLODBias == FLT_MAX if injector was released!
+ // and IOFX returns IofxActorIDIntl::NO_VOLUME for homeless/dead particles
+ bool validActorID = (injParams.mLODBias < FLT_MAX)
+ && (isNewParticle || (iofxActorID.getVolumeID() != IofxActorIDIntl::NO_VOLUME))
+ && position.isFinite() && velocity.isFinite();
+ if (!validActorID)
+ {
+ iofxActorID.setActorClassID(IofxActorIDIntl::IPX_ACTOR);
+ injIndex = UINT32_MAX;
+ }
+
+ //write
+ memLifeTime[dstIdx] = lifeTime;
+ memPositionMass[dstIdx] = combineFloat4(position, mass);
+ memVelocityLife[dstIdx] = combineFloat4(velocity, lifeTime / lifeSpan);
+
+ const uint32_t collisionFlags = (particleFlags & uint32_t(PxParticleFlag::eCOLLISION_WITH_STATIC | PxParticleFlag::eCOLLISION_WITH_DYNAMIC));
+ memCollisionNormalFlags[dstIdx] = combineFloat4(collisionNormal, SIM_INT_AS_FLOAT(collisionFlags));
+ if (memDensity != 0)
+ {
+ memDensity[dstIdx] = density;
+ }
+
+ if (!validActorID || dstIdx != srcIdx)
+ {
+ memIofxActorIDs[dstIdx] = iofxActorID;
+ }
+ if (dstIdx != srcIdx)
+ {
+ memLifeSpan[dstIdx] = lifeSpan;
+ memInjector[dstIdx] = injector;
+
+ memUserData[dstIdx] = SIM_FETCH(UserData,srcIdx);
+ }
+
+ float benefit = -FLT_MAX;
+ if (validActorID && lifeTime > 0.0f)
+ {
+ benefit = calcParticleBenefit(injParams, eyePos, position, velocity, lifeTime / lifeSpan);
+ }
+ return benefit;
+}
+
+}
+} // namespace nvidia
+
+#endif