aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/module/forcefield/include/ForceFieldFSCommon.h
diff options
context:
space:
mode:
authorsschirm <[email protected]>2016-12-23 14:20:36 +0100
committersschirm <[email protected]>2016-12-23 14:56:17 +0100
commitef6937e69e8ee3f409cf9d460d5ad300a65d5924 (patch)
tree710426e8daa605551ce3f34b581897011101c30f /APEX_1.4/module/forcefield/include/ForceFieldFSCommon.h
parentInitial commit: (diff)
downloadphysx-3.4-ef6937e69e8ee3f409cf9d460d5ad300a65d5924.tar.xz
physx-3.4-ef6937e69e8ee3f409cf9d460d5ad300a65d5924.zip
PhysX 3.4 / APEX 1.4 release candidate @21506124
Diffstat (limited to 'APEX_1.4/module/forcefield/include/ForceFieldFSCommon.h')
-rw-r--r--APEX_1.4/module/forcefield/include/ForceFieldFSCommon.h554
1 files changed, 0 insertions, 554 deletions
diff --git a/APEX_1.4/module/forcefield/include/ForceFieldFSCommon.h b/APEX_1.4/module/forcefield/include/ForceFieldFSCommon.h
deleted file mode 100644
index f2811f6d..00000000
--- a/APEX_1.4/module/forcefield/include/ForceFieldFSCommon.h
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * 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 __FORCEFIELD_FS_COMMON_SRC_H__
-#define __FORCEFIELD_FS_COMMON_SRC_H__
-
-#include "../../fieldsampler/include/FieldSamplerCommon.h"
-#include "SimplexNoise.h"
-#include "TableLookup.h"
-#include "PxMat33.h"
-
-namespace nvidia
-{
-namespace apex
-{
-
-template <> struct InplaceTypeTraits<TableLookup>
-{
- template <int _inplace_offset_, typename R, typename RA>
- APEX_CUDA_CALLABLE PX_INLINE static void reflectType(R& r, RA ra, TableLookup& t)
- {
- InplaceTypeHelper::reflectType<APEX_OFFSETOF(TableLookup, xVals) + _inplace_offset_>(r, ra, t.xVals, InplaceTypeMemberDefaultTraits());
- InplaceTypeHelper::reflectType<APEX_OFFSETOF(TableLookup, yVals) + _inplace_offset_>(r, ra, t.yVals, InplaceTypeMemberDefaultTraits());
- InplaceTypeHelper::reflectType<APEX_OFFSETOF(TableLookup, x1) + _inplace_offset_>(r, ra, t.x1, InplaceTypeMemberDefaultTraits());
- InplaceTypeHelper::reflectType<APEX_OFFSETOF(TableLookup, x2) + _inplace_offset_>(r, ra, t.x2, InplaceTypeMemberDefaultTraits());
- InplaceTypeHelper::reflectType<APEX_OFFSETOF(TableLookup, multiplier) + _inplace_offset_>(r, ra, t.multiplier, InplaceTypeMemberDefaultTraits());
- }
-};
-
-}
-namespace forcefield
-{
-
-struct ForceFieldShapeType
-{
- enum Enum
- {
- SPHERE = 0,
- CAPSULE,
- CYLINDER,
- CONE,
- BOX,
- NONE,
- };
-};
-
-struct ForceFieldFalloffType
-{
- enum Enum
- {
- LINEAR = 0,
- STEEP,
- SCURVE,
- CUSTOM,
- NONE,
- };
-};
-
-struct ForceFieldCoordinateSystemType
-{
- enum Enum
- {
- CARTESIAN = 0,
- SPHERICAL,
- CYLINDRICAL,
- TOROIDAL,
- };
-};
-
-struct ForceFieldKernelType
-{
- enum Enum
- {
- RADIAL = 0,
- GENERIC
- };
-};
-
-//struct ForceFieldShapeDesc
-#define INPLACE_TYPE_STRUCT_NAME ForceFieldShapeDesc
-#define INPLACE_TYPE_STRUCT_FIELDS \
- INPLACE_TYPE_FIELD(InplaceEnum<ForceFieldShapeType::Enum>, type) \
- INPLACE_TYPE_FIELD(PxMat44, forceFieldToShape) \
- INPLACE_TYPE_FIELD(PxVec3, dimensions)
-#include INPLACE_TYPE_BUILD()
-
-
-//struct NoiseParams
-#define INPLACE_TYPE_STRUCT_NAME NoiseParams
-#define INPLACE_TYPE_STRUCT_FIELDS \
- INPLACE_TYPE_FIELD(float, strength) \
- INPLACE_TYPE_FIELD(float, spaceScale) \
- INPLACE_TYPE_FIELD(float, timeScale) \
- INPLACE_TYPE_FIELD(uint32_t, octaves)
-#include INPLACE_TYPE_BUILD()
-
-//struct ForceFieldCoordinateSystem
-#define INPLACE_TYPE_STRUCT_NAME ForceFieldCoordinateSystem
-#define INPLACE_TYPE_STRUCT_FIELDS \
- INPLACE_TYPE_FIELD(InplaceEnum<ForceFieldCoordinateSystemType::Enum>, type) \
- INPLACE_TYPE_FIELD(float, torusRadius)
-#include INPLACE_TYPE_BUILD()
-
-//struct ForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_NAME ForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_FIELDS \
- INPLACE_TYPE_FIELD(PxMat44, pose) \
- INPLACE_TYPE_FIELD(float, strength) \
- INPLACE_TYPE_FIELD(ForceFieldShapeDesc, includeShape)
-#include INPLACE_TYPE_BUILD()
-
-//struct GenericForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_NAME GenericForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_BASE ForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_FIELDS \
- INPLACE_TYPE_FIELD(ForceFieldCoordinateSystem, cs) \
- INPLACE_TYPE_FIELD(PxVec3, constant) \
- INPLACE_TYPE_FIELD(PxMat33, positionMultiplier) \
- INPLACE_TYPE_FIELD(PxVec3, positionTarget) \
- INPLACE_TYPE_FIELD(PxMat33, velocityMultiplier) \
- INPLACE_TYPE_FIELD(PxVec3, velocityTarget) \
- INPLACE_TYPE_FIELD(PxVec3, noise) \
- INPLACE_TYPE_FIELD(PxVec3, falloffLinear) \
- INPLACE_TYPE_FIELD(PxVec3, falloffQuadratic)
-#include INPLACE_TYPE_BUILD()
-
-//struct RadialForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_NAME RadialForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_BASE ForceFieldFSKernelParams
-#define INPLACE_TYPE_STRUCT_FIELDS \
- INPLACE_TYPE_FIELD(float, radius) \
- INPLACE_TYPE_FIELD(TableLookup, falloffTable) \
- INPLACE_TYPE_FIELD(NoiseParams, noiseParams)
-#include INPLACE_TYPE_BUILD()
-
-APEX_CUDA_CALLABLE PX_INLINE bool isPosInShape(const ForceFieldShapeDesc& shapeParams, const PxVec3& pos)
-{
- // Sphere: x = radius
- // Capsule: x = radius, y = height
- // Cylinder: x = radius, y = height
- // Cone: x = top radius, y = height, z = bottom radius
- // Box: x,y,z = half-dimensions
-
- // transform position from force field coordinates to local shape coordinates
- PxVec3 shapePos = shapeParams.forceFieldToShape.transform(pos);
-
- switch (shapeParams.type)
- {
- case ForceFieldShapeType::SPHERE:
- {
- return (shapePos.magnitude() <= shapeParams.dimensions.x);
- }
- case ForceFieldShapeType::CAPSULE:
- {
- float halfHeight = shapeParams.dimensions.y / 2.0f;
-
- // check if y-position is within height of cylinder
- if (shapePos.y >= -halfHeight && shapePos.y <= halfHeight)
- {
- // check if x and z positions is inside radius height of cylinder
- if (PxSqrt(shapePos.x * shapePos.x + shapePos.z * shapePos.z) <= shapeParams.dimensions.x)
- {
- return true;
- }
- }
-
- // check if position falls inside top sphere in capsule
- PxVec3 spherePos = shapePos - PxVec3(0, halfHeight, 0);
- if (spherePos.magnitude() <= shapeParams.dimensions.x)
- {
- return true;
- }
-
- // check if position falls inside bottom sphere in capsule
- spherePos = shapePos + PxVec3(0, halfHeight, 0);
- if (spherePos.magnitude() <= shapeParams.dimensions.x)
- {
- return true;
- }
-
- return false;
- }
- case ForceFieldShapeType::CYLINDER:
- {
- float halfHeight = shapeParams.dimensions.y / 2.0f;
-
- // check if y-position is within height of cylinder
- if (shapePos.y >= -halfHeight && shapePos.y <= halfHeight)
- {
- // check if x and z positions is inside radius height of cylinder
- if (PxSqrt(shapePos.x * shapePos.x + shapePos.z * shapePos.z) <= shapeParams.dimensions.x)
- {
- return true;
- }
- }
- return false;
- }
- case ForceFieldShapeType::CONE:
- {
- float halfHeight = shapeParams.dimensions.y / 2.0f;
-
- // check if y-position is within height of cone
- if (shapePos.y >= -halfHeight && shapePos.y <= halfHeight)
- {
- // cone can be normal or inverted
- float smallerBase;
- float heightFromSmallerBase;
- float radiusDiff;
- if (shapeParams.dimensions.x > shapeParams.dimensions.z)
- {
- smallerBase = shapeParams.dimensions.z;
- heightFromSmallerBase = shapePos.y + halfHeight;
- radiusDiff = shapeParams.dimensions.x - shapeParams.dimensions.z;
- }
- else
- {
- smallerBase = shapeParams.dimensions.x;
- heightFromSmallerBase = halfHeight - shapePos.y;
- radiusDiff = shapeParams.dimensions.z - shapeParams.dimensions.x;
- }
-
- // compute radius at y-position along height of cone
- float radiusAlongCone = smallerBase + (heightFromSmallerBase / shapeParams.dimensions.y) * radiusDiff;
-
- // check if x and z positions is inside radius at a specific height of cone
- if (PxSqrt(shapePos.x * shapePos.x + shapePos.z * shapePos.z) <= radiusAlongCone)
- {
- return true;
- }
- }
- return false;
- }
- case ForceFieldShapeType::BOX:
- {
- return (PxAbs(shapePos.x) <= shapeParams.dimensions.x &&
- PxAbs(shapePos.y) <= shapeParams.dimensions.y &&
- PxAbs(shapePos.z) <= shapeParams.dimensions.z);
- }
- default:
- {
- return false;
- }
- }
-}
-
-APEX_CUDA_CALLABLE PX_INLINE PxVec3 getNoise(const NoiseParams& params, const PxVec3& pos, const uint32_t& totalElapsedMS)
-{
- PxVec3 point = params.spaceScale * pos;
- float time = (params.timeScale * 1e-3f) * totalElapsedMS;
-
- PxVec4 dFx;
- dFx.setZero();
- PxVec4 dFy;
- dFy.setZero();
- PxVec4 dFz;
- dFz.setZero();
- int seed = 0;
- float amp = 1.0f;
- for (uint32_t i = 0; i < params.octaves; ++i)
- {
- dFx += amp * SimplexNoise::eval4D(point.x, point.y, point.z, time, ++seed);
- dFy += amp * SimplexNoise::eval4D(point.x, point.y, point.z, time, ++seed);
- dFz += amp * SimplexNoise::eval4D(point.x, point.y, point.z, time, ++seed);
-
- point *= 2;
- time *= 2;
- amp *= 0.5f;
- }
-
- //get rotor
- PxVec3 rot;
- rot.x = dFz.y - dFy.z;
- rot.y = dFx.z - dFz.x;
- rot.z = dFy.x - dFx.y;
-
- return params.strength * rot;
-}
-
-APEX_CUDA_CALLABLE PX_INLINE PxVec3 executeForceFieldMainFS(const RadialForceFieldFSKernelParams& params, const PxVec3& pos, const uint32_t& totalElapsedMS)
-{
- // bring pos to force field coordinate system
- PxVec3 localPos = params.pose.inverseRT().transform(pos);
-
- if (isPosInShape(params.includeShape, localPos))
- {
- PxVec3 result = localPos.getNormalized();
- result = result * params.strength;
-
- // apply falloff
- result = result * params.falloffTable.lookupTableValue(localPos.magnitude() / params.radius);
-
- // apply noise
- result = result + getNoise(params.noiseParams, localPos, totalElapsedMS);
-
- // rotate result back to world coordinate system
- return params.pose.rotate(result);
- }
-
- return PxVec3(0, 0, 0);
-}
-
-// function to compute the Scalar falloff for the cylinderical, toroidal, cartesian and generic
-// force fields so that the falloff does not make the direction of the force vector change.
-APEX_CUDA_CALLABLE PX_INLINE float falloff(PxVec3 val, PxVec3 linearff, PxVec3 quadraticff)
-{
- float magnitude = val.magnitude();
- float v = (linearff.x * magnitude + quadraticff.x * magnitude * magnitude) +
- (linearff.y * magnitude + quadraticff.y * magnitude * magnitude) +
- (linearff.z * magnitude + quadraticff.z * magnitude * magnitude);
- v += 1.0f;
- //PX_ASSERT(v>0);
- return 1.0f/v;
-}
-
-APEX_CUDA_CALLABLE PX_INLINE PxVec3 genericEvalLinearKernel(const PxVec3& localPos, const PxVec3& localVel, const GenericForceFieldFSKernelParams& params)
-{
- const bool useFalloff = params.falloffLinear.magnitudeSquared() +
- params.falloffQuadratic.magnitudeSquared() != 0;
-
- const bool useVelMul = !(params.velocityMultiplier.column0.isZero() &&
- params.velocityMultiplier.column1.isZero() &&
- params.velocityMultiplier.column2.isZero());
-
- const bool usePosMul = !(params.positionMultiplier.column0.isZero() &&
- params.positionMultiplier.column1.isZero() &&
- params.positionMultiplier.column2.isZero());
-
-
- PxVec3 ffPosErr;
- PxMat33 tangentFrame;
- PxVec3 ffForce = params.constant;
- switch(params.cs.type)
- {
- case ForceFieldCoordinateSystemType::CARTESIAN:
- {
- ffPosErr = params.positionTarget - (localPos);
- }
- break;
- case ForceFieldCoordinateSystemType::SPHERICAL:
- {
- const float& r = localPos.x;
- ffPosErr = PxVec3(params.positionTarget.x - r, 0, 0);
- }
- break;
- case ForceFieldCoordinateSystemType::CYLINDRICAL:
- {
- const float& r = localPos.x;
- ffPosErr = PxVec3(params.positionTarget.x - r, params.positionTarget.y - localPos.y, 0);
- }
- break;
- case ForceFieldCoordinateSystemType::TOROIDAL:
- {
- float r = 0.0f;
- PxVec3 t0;
- PxVec3 circleDir(localPos.x, 0.0f, localPos.z);
- float l2 = circleDir.magnitudeSquared();
- if(l2<1e-4f*1e-4f)
- {
- circleDir = PxVec3(0);
- }
- else
- {
- circleDir /= PxSqrt(l2); // Normalize circleDir
- PxVec3 circlePoint = circleDir * params.cs.torusRadius;
- t0 = localPos - circlePoint;
- l2 = t0.magnitudeSquared();
- if(l2<1e-4f*1e-4f)
- {
- circleDir = PxVec3(0);
- t0 = PxVec3(0);
- }
- else
- {
- r = PxSqrt(l2);
- t0 /= r; // Normalize t0
- }
- }
- PxVec3 t1(-circleDir.z, 0.0f, circleDir.x); // PxVec3 t1 = circleDir.cross(PxVec3(0,1,0));
- tangentFrame.column0 = t0;
- tangentFrame.column1 = t1;
- tangentFrame.column2 = t0.cross(t1);
- ffPosErr = PxVec3(params.positionTarget.x - r, 0, 0);
- }
- break;
- }
-
- PxVec3 ffVel = (params.cs.type == ForceFieldCoordinateSystemType::TOROIDAL) ? tangentFrame.getInverse() * localVel : localVel;
-
- if(useVelMul)
- {
- ffForce += params.velocityMultiplier * (params.velocityTarget - ffVel);
- }
-
- if(usePosMul)
- {
- ffForce += params.positionMultiplier * ffPosErr;
- }
-
- //TODO, enable noise, with existing noise functionality
- //applyNoise(ffForce, params.noise, NpPhysicsSDK::instance->getNpPhysicsTls()->mNpLinearKernelRnd);
- //ffForce *= PxVec3(1) + params.noise * [-1, 1]^3
-
- if(useFalloff)
- {
- ffForce *= falloff(ffPosErr, params.falloffLinear, params.falloffQuadratic);
- }
-
- PxVec3 force = (params.cs.type == ForceFieldCoordinateSystemType::TOROIDAL) ? tangentFrame * ffForce : ffForce;
- return force;
-}
-
-APEX_CUDA_CALLABLE PX_INLINE void genericEvalCartesian(PxVec3& force, const PxVec3& localPos, const PxVec3& localVel, const GenericForceFieldFSKernelParams& params)
-{
- // compute tangent frame
- // -- none here
-
- // evaluate kernel
- force = genericEvalLinearKernel(localPos, localVel, params);
-}
-
-APEX_CUDA_CALLABLE PX_INLINE void genericEvalSpherical(PxVec3& force, const PxVec3& localPos, const PxVec3& localVel, const GenericForceFieldFSKernelParams& params)
-{
- // compute tangent frame
- PxMat33 tangentFrame(PxZero);
- float l2 = localPos.magnitudeSquared();
- PxVec3 tangentPos;
- if(l2>1e-4f*1e-4f)
- {
- float r = PxSqrt(l2);
- PxVec3 t0 = localPos/r;
- tangentFrame.column0 = t0;
- tangentPos = PxVec3(r, 0, 0);
- }
- else
- {
- tangentPos = PxVec3(0);
- }
-
- // compute tangent frame velocity
- const PxVec3 tangentVel = tangentFrame.getInverse() * localVel;
-
- // evaluate kernel
- force = genericEvalLinearKernel(tangentPos, tangentVel, params);
-
- // transform back to local space
- force = tangentFrame * force;
-}
-
-APEX_CUDA_CALLABLE PX_INLINE void genericEvalCylindrical(PxVec3& force, const PxVec3& localPos, const PxVec3& localVel, const GenericForceFieldFSKernelParams& params)
-{
- // compute tangent frame
- PxMat33 tangentFrame;
- PxVec3 t0(localPos.x, 0, localPos.z); // Project to Cylindrical
- const float len = t0.magnitude();
- PxVec3 tangentPos;
- if(len > 1e-4f)
- {
- t0 /= len;
- tangentPos = PxVec3(len, localPos.y, 0);
- }
- else
- {
- t0 = PxVec3(0);
- tangentPos = PxVec3(0, localPos.y, 0);
- }
- tangentFrame.column0 = t0;
- tangentFrame.column1 = PxVec3(0.0f, 1.0f, 0.0f); // t1
- tangentFrame.column2 = PxVec3(-t0.z, 0.0f, t0.x); // t0.cross(t1)
-
- // compute tangent frame velocity
- const PxVec3 tangentVel = tangentFrame.getInverse() * localVel;
-
- // evaluate kernel
- force = genericEvalLinearKernel(tangentPos, tangentVel, params);
-
- // transform back to local space
- force = tangentFrame * force;
-}
-
-APEX_CUDA_CALLABLE PX_INLINE void genericEvalToroidal(PxVec3& force, const PxVec3& localPos, const PxVec3& localVel, const GenericForceFieldFSKernelParams& params)
-{
- // evaluate kernel
- force = genericEvalLinearKernel(localPos, localVel, params);
-}
-
-/**
-This is more or less a 1:1 copy of PhysX 2.8.4/UE3 generic force fields.
-Since 2.8.4 supported more flexible callbacks, we should probably optimize
-this quite a bit.
-*/
-APEX_CUDA_CALLABLE PX_INLINE PxVec3 executeForceFieldMainFS(const GenericForceFieldFSKernelParams& params, const PxVec3& pos, const PxVec3& vel, const uint32_t&)
-{
- // bring pos to force field coordinate system
- PxVec3 localPos = params.pose.inverseRT().transform(pos);
-
- if (isPosInShape(params.includeShape, localPos))
- {
- PxVec3 localVel = params.pose.inverseRT().rotate(vel);
-
- PxVec3 result(0);
- switch (params.cs.type)
- {
- case ForceFieldCoordinateSystemType::CARTESIAN:
- genericEvalCartesian(result, localPos, localVel, params);
- break;
- case ForceFieldCoordinateSystemType::SPHERICAL:
- genericEvalSpherical(result, localPos, localVel, params);
- break;
- case ForceFieldCoordinateSystemType::CYLINDRICAL:
- genericEvalCylindrical(result, localPos, localVel, params);
- break;
- case ForceFieldCoordinateSystemType::TOROIDAL:
- genericEvalToroidal(result, localPos, localVel, params);
- break;
- default:
- break;
- }
-
- // apply strength
- result = result * params.strength;
-
- // rotate result back to world coordinate system
- return params.pose.rotate(result);
- }
-
- return PxVec3(0, 0, 0);
-}
-
-APEX_CUDA_CALLABLE PX_INLINE PxVec3 executeForceFieldFS(const RadialForceFieldFSKernelParams& params, const PxVec3& pos, const uint32_t& totalElapsedMS)
-{
- PxVec3 resultField(0, 0, 0);
- resultField += executeForceFieldMainFS(params, pos, totalElapsedMS);
- return resultField;
-}
-
-APEX_CUDA_CALLABLE PX_INLINE PxVec3 executeForceFieldFS(const GenericForceFieldFSKernelParams& params, const PxVec3& pos, const PxVec3& vel, const uint32_t& totalElapsedMS)
-{
- PxVec3 resultField(0, 0, 0);
- resultField += executeForceFieldMainFS(params, pos, vel, totalElapsedMS);
- return resultField;
-}
-
-}
-} // end namespace nvidia
-
-#endif