From 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 Mon Sep 17 00:00:00 2001 From: git perforce import user Date: Tue, 25 Oct 2016 12:29:14 -0600 Subject: Initial commit: PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167] --- .../pxparticleios/include/ParticleIosCommonCode.h | 288 +++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h (limited to 'APEX_1.4/module/pxparticleios/include/ParticleIosCommonCode.h') 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 -- cgit v1.2.3