RavEngine
Loading...
Searching...
No Matches
DySolverConstraintsShared.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef DY_SOLVER_CONSTRAINT_SHARED_H
30#define DY_SOLVER_CONSTRAINT_SHARED_H
31
32#include "foundation/PxPreprocessor.h"
33#include "foundation/PxVecMath.h"
34
35#include "DySolverBody.h"
36#include "DySolverContact.h"
37#include "DySolverConstraint1D.h"
38#include "DySolverConstraintDesc.h"
39#include "foundation/PxUtilities.h"
40#include "DyConstraint.h"
41#include "foundation/PxAtomic.h"
42
43
44namespace physx
45{
46
47namespace Dy
48{
49 PX_FORCE_INLINE static FloatV solveDynamicContacts(SolverContactPoint* contacts, const PxU32 nbContactPoints, const Vec3VArg contactNormal,
50 const FloatVArg invMassA, const FloatVArg invMassB, const FloatVArg angDom0, const FloatVArg angDom1, Vec3V& linVel0_, Vec3V& angState0_,
51 Vec3V& linVel1_, Vec3V& angState1_, PxF32* PX_RESTRICT forceBuffer)
52{
53 Vec3V linVel0 = linVel0_;
54 Vec3V angState0 = angState0_;
55 Vec3V linVel1 = linVel1_;
56 Vec3V angState1 = angState1_;
57 FloatV accumulatedNormalImpulse = FZero();
58
59 const Vec3V delLinVel0 = V3Scale(contactNormal, invMassA);
60 const Vec3V delLinVel1 = V3Scale(contactNormal, invMassB);
61
62 for(PxU32 i=0;i<nbContactPoints;i++)
63 {
64 SolverContactPoint& c = contacts[i];
65 PxPrefetchLine(&contacts[i], 128);
66
67 const Vec3V raXn = Vec3V_From_Vec4V(c.raXn_velMultiplierW);
68
69 const Vec3V rbXn = Vec3V_From_Vec4V(c.rbXn_maxImpulseW);
70
71 const FloatV appliedForce = FLoad(forceBuffer[i]);
72 const FloatV velMultiplier = c.getVelMultiplier();
73 const FloatV impulseMultiplier = c.getImpulseMultiplier();
74
75 /*const FloatV targetVel = c.getTargetVelocity();
76 const FloatV nScaledBias = c.getScaledBias();*/
77 const FloatV maxImpulse = c.getMaxImpulse();
78
79 //Compute the normal velocity of the constraint.
80 const Vec3V v0 = V3MulAdd(linVel0, contactNormal, V3Mul(angState0, raXn));
81 const Vec3V v1 = V3MulAdd(linVel1, contactNormal, V3Mul(angState1, rbXn));
82 const FloatV normalVel = V3SumElems(V3Sub(v0, v1));
83
84 const FloatV biasedErr = c.getBiasedErr();//FScaleAdd(targetVel, velMultiplier, nScaledBias);
85
86 //KS - clamp the maximum force
87 const FloatV _deltaF = FMax(FNegScaleSub(normalVel, velMultiplier, biasedErr), FNeg(appliedForce));
88 const FloatV _newForce = FAdd(FMul(impulseMultiplier, appliedForce), _deltaF);
89 const FloatV newForce = FMin(_newForce, maxImpulse);
90 const FloatV deltaF = FSub(newForce, appliedForce);
91
92 linVel0 = V3ScaleAdd(delLinVel0, deltaF, linVel0);
93 linVel1 = V3NegScaleSub(delLinVel1, deltaF, linVel1);
94 angState0 = V3ScaleAdd(raXn, FMul(deltaF, angDom0), angState0);
95 angState1 = V3NegScaleSub(rbXn, FMul(deltaF, angDom1), angState1);
96
97 FStore(newForce, &forceBuffer[i]);
98
99 accumulatedNormalImpulse = FAdd(accumulatedNormalImpulse, newForce);
100 }
101
102 linVel0_ = linVel0;
103 angState0_ = angState0;
104 linVel1_ = linVel1;
105 angState1_ = angState1;
106 return accumulatedNormalImpulse;
107}
108
109PX_FORCE_INLINE static FloatV solveStaticContacts(SolverContactPoint* contacts, const PxU32 nbContactPoints, const Vec3VArg contactNormal,
110 const FloatVArg invMassA, const FloatVArg angDom0, Vec3V& linVel0_, Vec3V& angState0_, PxF32* PX_RESTRICT forceBuffer)
111{
112 Vec3V linVel0 = linVel0_;
113 Vec3V angState0 = angState0_;
114 FloatV accumulatedNormalImpulse = FZero();
115
116 const Vec3V delLinVel0 = V3Scale(contactNormal, invMassA);
117
118 for(PxU32 i=0;i<nbContactPoints;i++)
119 {
120 SolverContactPoint& c = contacts[i];
121 PxPrefetchLine(&contacts[i],128);
122
123 const Vec3V raXn = Vec3V_From_Vec4V(c.raXn_velMultiplierW);
124
125 const FloatV appliedForce = FLoad(forceBuffer[i]);
126 const FloatV velMultiplier = c.getVelMultiplier();
127 const FloatV impulseMultiplier = c.getImpulseMultiplier();
128
129 /*const FloatV targetVel = c.getTargetVelocity();
130 const FloatV nScaledBias = c.getScaledBias();*/
131 const FloatV maxImpulse = c.getMaxImpulse();
132
133 const Vec3V v0 = V3MulAdd(linVel0, contactNormal, V3Mul(angState0, raXn));
134 const FloatV normalVel = V3SumElems(v0);
135
136
137 const FloatV biasedErr = c.getBiasedErr();//FScaleAdd(targetVel, velMultiplier, nScaledBias);
138
139 // still lots to do here: using loop pipelining we can interweave this code with the
140 // above - the code here has a lot of stalls that we would thereby eliminate
141 const FloatV _deltaF = FMax(FNegScaleSub(normalVel, velMultiplier, biasedErr), FNeg(appliedForce));
142 const FloatV _newForce = FAdd(FMul(appliedForce, impulseMultiplier), _deltaF);
143 const FloatV newForce = FMin(_newForce, maxImpulse);
144 const FloatV deltaF = FSub(newForce, appliedForce);
145
146 linVel0 = V3ScaleAdd(delLinVel0, deltaF, linVel0);
147 angState0 = V3ScaleAdd(raXn, FMul(deltaF, angDom0), angState0);
148
149 FStore(newForce, &forceBuffer[i]);
150
151 accumulatedNormalImpulse = FAdd(accumulatedNormalImpulse, newForce);
152 }
153
154 linVel0_ = linVel0;
155 angState0_ = angState0;
156 return accumulatedNormalImpulse;
157}
158
159FloatV solveExtContacts(SolverContactPointExt* contacts, const PxU32 nbContactPoints, const Vec3VArg contactNormal,
160 Vec3V& linVel0, Vec3V& angVel0,
161 Vec3V& linVel1, Vec3V& angVel1,
162 Vec3V& li0, Vec3V& ai0,
163 Vec3V& li1, Vec3V& ai1,
164 PxF32* PX_RESTRICT appliedForceBuffer);
165
166}
167
168}
169
170#endif
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_FORCE_INLINE void PxPrefetchLine(const void *ptr, uint32_t offset=0)
Definition PxUnixIntrinsics.h:83