aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/LowLevelParticles/src/PtCollisionSphere.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'PhysX_3.4/Source/LowLevelParticles/src/PtCollisionSphere.cpp')
-rw-r--r--PhysX_3.4/Source/LowLevelParticles/src/PtCollisionSphere.cpp156
1 files changed, 156 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/LowLevelParticles/src/PtCollisionSphere.cpp b/PhysX_3.4/Source/LowLevelParticles/src/PtCollisionSphere.cpp
new file mode 100644
index 00000000..cddce6af
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevelParticles/src/PtCollisionSphere.cpp
@@ -0,0 +1,156 @@
+// 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 "PtCollisionMethods.h"
+#if PX_USE_PARTICLE_SYSTEM_API
+
+using namespace physx;
+using namespace Pt;
+
+namespace
+{
+
+void collideWithSphereNonContinuous(ParticleCollData& collData, const PxVec3& pos, const PxReal& radius,
+ const PxReal& proxRadius)
+{
+ if(collData.localFlags & ParticleCollisionFlags::CC)
+ return; // Only apply discrete and proximity collisions if no continuous collisions was detected so far (for any
+ // colliding shape)
+
+ PxReal dist = pos.magnitude();
+ collData.localSurfaceNormal = pos;
+ if(dist < (radius + proxRadius))
+ {
+ if(dist != 0.0f)
+ collData.localSurfaceNormal *= (1.0f / dist);
+ else
+ collData.localSurfaceNormal = PxVec3(0);
+
+ // Push particle to surface such that the distance to the surface is equal to the collision radius
+ collData.localSurfacePos = collData.localSurfaceNormal * (radius + collData.restOffset);
+ collData.localFlags |= ParticleCollisionFlags::L_PROX;
+
+ if(dist < (radius + collData.restOffset))
+ collData.localFlags |= ParticleCollisionFlags::L_DC;
+ }
+}
+
+PX_FORCE_INLINE void collideWithSphere(ParticleCollData& collData, const PxSphereGeometry& sphereShapeData,
+ PxReal proxRadius)
+{
+ PxVec3& oldPos = collData.localOldPos;
+ PxVec3& newPos = collData.localNewPos;
+
+ PxReal radius = sphereShapeData.radius;
+
+ PxReal oldPosDist2 = oldPos.magnitudeSquared();
+ PxReal radius2 = radius * radius;
+
+ bool oldInSphere = (oldPosDist2 < radius2);
+
+ if(oldInSphere)
+ {
+ // old position inside the skeleton
+ // add ccd with time 0.0
+
+ collData.localSurfaceNormal = oldPos;
+ if(oldPosDist2 > 0.0f)
+ collData.localSurfaceNormal *= PxRecipSqrt(oldPosDist2);
+ else
+ collData.localSurfaceNormal = PxVec3(0, 1.0f, 0);
+
+ // Push particle to surface such that the distance to the surface is equal to the collision radius
+ collData.localSurfacePos = collData.localSurfaceNormal * (radius + collData.restOffset);
+ collData.ccTime = 0.0;
+ collData.localFlags |= ParticleCollisionFlags::L_CC;
+ }
+ else
+ {
+ // old position is outside of the skeleton
+
+ PxVec3 motion = newPos - oldPos;
+
+ // Discriminant
+ PxReal b = motion.dot(oldPos) * 2.0f;
+ PxReal a2 = 2.0f * motion.magnitudeSquared();
+ PxReal disc = (b * b) - (2.0f * a2 * (oldPosDist2 - radius2));
+
+ bool intersection = disc > 0.0f;
+
+ if((!intersection) || (a2 == 0.0f))
+ {
+ // the ray does not intersect the sphere
+ collideWithSphereNonContinuous(collData, newPos, radius, proxRadius);
+ }
+ else
+ {
+ // the ray intersects the sphere
+ PxReal t = -(b + PxSqrt(disc)) / a2; // Compute intersection point
+
+ if(t < 0.0f || t > 1.0f)
+ {
+ // intersection point lies outside motion vector
+ collideWithSphereNonContinuous(collData, newPos, radius, proxRadius);
+ }
+ else if(t < collData.ccTime)
+ {
+ // intersection point lies on sphere, add lcc
+ // collData.localSurfacePos = oldPos + (motion * t);
+ // collData.localSurfaceNormal = collData.localSurfacePos;
+ // collData.localSurfaceNormal *= (1.0f / radius);
+ // collData.localSurfacePos += (collData.localSurfaceNormal * collData.restOffset);
+ PxVec3 relativeImpact = motion * t;
+ collData.localSurfaceNormal = oldPos + relativeImpact;
+ collData.localSurfaceNormal *= (1.0f / radius);
+ computeContinuousTargetPosition(collData.localSurfacePos, collData.localOldPos, relativeImpact,
+ collData.localSurfaceNormal, collData.restOffset);
+
+ collData.ccTime = t;
+ collData.localFlags |= ParticleCollisionFlags::L_CC;
+ }
+ }
+ }
+}
+
+} // namespace
+
+void physx::Pt::collideWithSphere(ParticleCollData* particleCollData, PxU32 numCollData,
+ const Gu::GeometryUnion& sphereShape, PxReal proxRadius)
+{
+ PX_ASSERT(particleCollData);
+
+ const PxSphereGeometry& sphereShapeData = sphereShape.get<const PxSphereGeometry>();
+
+ for(PxU32 p = 0; p < numCollData; p++)
+ {
+ ::collideWithSphere(particleCollData[p], sphereShapeData, proxRadius);
+ }
+}
+
+#endif // PX_USE_PARTICLE_SYSTEM_API