29 #include "../precompiled.h"
39 #define IGNORE_UNSATISFIABLE_VARIABLES
77 void GetMaxStep(
int d,
float dir,
float &maxStep,
int &limit,
int &limitSide )
const;
129 for ( j = 0; j <
i; j++ ) {
136 for ( i = numClamped - 1; i >= 0; i-- ) {
158 b.SwapElements( i, j );
189 for ( j = 0; j <
i; j++ ) {
198 for ( j = 0; j <
i; j++ ) {
216 float *y0, *
y1, *z0, *z1;
217 double diag, beta0, beta1, p0, p1, q0, q1, d;
228 y0 = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
229 z0 = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
230 y1 = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
231 z1 = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
238 memset( y1, 0, numClamped *
sizeof(
float ) );
241 memset( z0, 0, numClamped *
sizeof(
float ) );
249 Swap( r, numClamped );
262 for ( i = 0; i <
r; i++ ) {
284 if ( diag == 0.0
f ) {
295 if ( diag == 0.0
f ) {
353 ptr = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
435 s = (
lo[d] -
f[d] ) / dir;
443 s = (
hi[d] -
f[d] ) / dir;
477 for ( i = numClamped; i < d; i++ ) {
478 if (
side[i] == -1 ) {
482 }
else if (
side[i] == 1 ) {
508 int i,
j,
n, limit, limitSide, boxStartIndex;
509 float dir, maxStep,
dot,
s;
574 if ( boxStartIndex != i ) {
575 Swap( boxStartIndex, i );
605 #ifdef IGNORE_UNSATISFIABLE_VARIABLES
618 if ( i == boxStartIndex ) {
619 for ( j = 0; j < boxStartIndex; j++ ) {
622 for ( j = boxStartIndex; j <
m.
GetNumRows(); j++ ) {
660 if (
a[i] <= 0.0
f ) {
673 GetMaxStep( i, dir, maxStep, limit, limitSide );
675 if ( maxStep <= 0.0
f ) {
676 #ifdef IGNORE_UNSATISFIABLE_VARIABLES
683 failed =
va(
"invalid step size %.4f", maxStep );
695 side[limit] = limitSide;
696 switch( limitSide ) {
703 f[limit] =
lo[limit];
710 f[limit] =
hi[limit];
724 if ( n >= maxIterations ) {
725 failed =
va(
"max iterations %d", maxIterations );
734 #ifdef IGNORE_UNSATISFIABLE_VARIABLES
736 if ( lcp_showFailures.
GetBool() ) {
744 if ( lcp_showFailures.
GetBool() ) {
752 #if defined(_DEBUG) && 0
761 if (
f[i] ==
lo[i] ) {
765 }
else if (
f[i] ==
hi[i] ) {
777 for ( i = 0; i <
f.
GetSize(); i++ ) {
830 void Swap(
int i,
int j );
837 void GetMaxStep(
int d,
float dir,
float &maxStep,
int &limit,
int &limitSide )
const;
887 b.SwapElements( i, j );
919 if ( useSolveCache ) {
928 float *
v = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
959 float *addSub, *original, *
v, *ptr, *
v1, *
v2,
dot;
960 double sum, diag, newDiag, invNewDiag, p1, p2, alpha1, alpha2, beta1, beta2;
979 addSub = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
985 if ( diag == 0.0
f ) {
986 idLib::common->
Printf(
"idLCP_Symmetric::RemoveClamped: updating factorization failed\n" );
999 addSub[
i] = ptr[
i] - original[
i];
1004 v = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
1017 if ( diag == 0.0
f ) {
1018 idLib::common->
Printf(
"idLCP_Symmetric::RemoveClamped: updating factorization failed\n" );
1027 for ( i = 0; i <
r; i++ ) {
1037 for ( j = 0; j <
r; j++ ) {
1038 sum += ptr[
j] * v[
j];
1046 v1 = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
1047 v2 = (
float *) _alloca16(
numClamped *
sizeof(
float ) );
1050 v1[
r] = ( 0.5f * addSub[
r] + 1.0f ) * diag;
1051 v2[
r] = ( 0.5f * addSub[
r] - 1.0f ) * diag;
1053 v1[
i] = v2[
i] = addSub[
i] * diag;
1065 newDiag = diag + alpha1 * p1 * p1;
1067 if ( newDiag == 0.0
f ) {
1068 idLib::common->
Printf(
"idLCP_Symmetric::RemoveClamped: updating factorization failed\n" );
1073 beta1 = p1 * alpha1;
1078 newDiag = diag + alpha2 * p2 * p2;
1080 if ( newDiag == 0.0
f ) {
1081 idLib::common->
Printf(
"idLCP_Symmetric::RemoveClamped: updating factorization failed\n" );
1086 diagonal[
i] = invNewDiag = 1.0f / newDiag;
1088 alpha2 *= invNewDiag;
1089 beta2 = p2 * alpha2;
1095 for ( j = i+1; j < numClamped - 1; j += 2 ) {
1097 float sum0 = ptr[(j+0)*n];
1098 float sum1 = ptr[(j+1)*n];
1100 v1[j+0] -= p1 * sum0;
1101 v1[j+1] -= p1 * sum1;
1103 sum0 += beta1 * v1[j+0];
1104 sum1 += beta1 * v1[j+1];
1106 v2[j+0] -= p2 * sum0;
1107 v2[j+1] -= p2 * sum1;
1109 sum0 += beta2 * v2[j+0];
1110 sum1 += beta2 * v2[j+1];
1112 ptr[(j+0)*n] = sum0;
1113 ptr[(j+1)*n] = sum1;
1121 sum += beta1 * v1[
j];
1124 sum += beta2 * v2[
j];
1225 s = (
lo[d] -
f[d] ) / dir;
1226 if ( s < maxStep ) {
1233 s = (
hi[d] -
f[d] ) / dir;
1234 if ( s < maxStep ) {
1247 if ( s < maxStep ) {
1257 if ( s < maxStep ) {
1267 for ( i = numClamped; i < d; i++ ) {
1268 if (
side[i] == -1 ) {
1272 }
else if (
side[i] == 1 ) {
1284 if ( s < maxStep ) {
1298 int i,
j,
n, limit, limitSide, boxStartIndex;
1299 float dir, maxStep,
dot,
s;
1364 if ( boxStartIndex != i ) {
1365 Swap( boxStartIndex, i );
1397 #ifdef IGNORE_UNSATISFIABLE_VARIABLES
1412 if ( i == boxStartIndex ) {
1413 for ( j = 0; j < boxStartIndex; j++ ) {
1416 for ( j = boxStartIndex; j <
m.
GetNumRows(); j++ ) {
1454 if (
a[i] <= 0.0
f ) {
1467 GetMaxStep( i, dir, maxStep, limit, limitSide );
1469 if ( maxStep <= 0.0
f ) {
1470 #ifdef IGNORE_UNSATISFIABLE_VARIABLES
1477 failed =
va(
"invalid step size %.4f", maxStep );
1489 side[limit] = limitSide;
1490 switch( limitSide ) {
1497 f[limit] =
lo[limit];
1504 f[limit] =
hi[limit];
1518 if ( n >= maxIterations ) {
1519 failed =
va(
"max iterations %d", maxIterations );
1528 #ifdef IGNORE_UNSATISFIABLE_VARIABLES
1530 if ( lcp_showFailures.
GetBool() ) {
1538 if ( lcp_showFailures.
GetBool() ) {
1546 #if defined(_DEBUG) && 0
1555 if (
f[i] ==
lo[i] ) {
1559 }
else if (
f[i] ==
hi[i] ) {
1571 for ( i = 0; i <
f.
GetSize(); i++ ) {
void ChangeAccel(int d, float step)
static const float INFINITY
assert(prefInfo.fullscreenBtn)
void SolveClamped(idVecX &x, const float *b)
void RemoveClamped(int r)
const float LCP_ACCEL_EPSILON
const float LCP_DELTA_FORCE_EPSILON
idVecX & SwapElements(int e1, int e2)
const float LCP_BOUND_EPSILON
void ChangeForce(int d, float step)
virtual bool Solve(const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex)
virtual void VPCALL MatX_LowerTriangularSolveTranspose(const idMatX &L, float *x, const float *b, const int n)=0
static idLCP * AllocSymmetric(void)
static idLCP * AllocSquare(void)
virtual bool Solve(const idMatX &o_m, idVecX &o_x, const idVecX &o_b, const idVecX &o_lo, const idVecX &o_hi, const int *o_boxIndex)
GLfloat GLfloat GLfloat v2
int GetNumColumns(void) const
void GetMaxStep(int d, float dir, float &maxStep, int &limit, int &limitSide) const
idMatX & SwapColumns(int r1, int r2)
virtual void VPCALL MulAdd(float *dst, const float constant, const float *src, const int count)=0
static float Fabs(float f)
static const float SQRT_1OVER2
const float * ToFloatPtr(void) const
void GetMaxStep(int d, float dir, float &maxStep, int &limit, int &limitSide) const
void AddClamped(int r, bool useSolveCache)
virtual void VPCALL MatX_LowerTriangularSolve(const idMatX &L, float *x, const float *b, const int n, int skip=0)=0
virtual void VPCALL Dot(float *dst, const idVec3 &constant, const idVec3 *src, const int count)=0
int GetNumRows(void) const
virtual int GetMaxIterations(void)
virtual void VPCALL Mul(float *dst, const float constant, const float *src, const int count)=0
GLubyte GLubyte GLubyte a
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void CalcForceDelta(int d, float dir)
ID_INLINE void idSwap(type &a, type &b)
virtual bool VPCALL MatX_LDLTFactor(idMatX &mat, idVecX &invDiag, const int n)=0
void CalcForceDelta(int d, float dir)
GLdouble GLdouble GLdouble r
void RemoveClamped(int r)
void SolveClamped(idVecX &x, const float *b)
virtual void SetMaxIterations(int max)
const float LCP_DELTA_ACCEL_EPSILON
void CalcAccelDelta(int d)
void SetData(int rows, int columns, float *data)
void SetData(int length, float *data)
void CalcAccelDelta(int d)
float dot(float a[], float b[])
char * va(const char *fmt,...)
void ChangeForce(int d, float step)
const float * ToFloatPtr(void) const
static class idCommon * common
void ChangeAccel(int d, float step)
idSIMDProcessor * SIMDProcessor