more on ubode

This commit is contained in:
UbitUmarov
2022-08-07 02:47:14 +01:00
parent dfb564e6c1
commit ef2d075395
12 changed files with 862 additions and 883 deletions
@@ -1108,15 +1108,23 @@ ODE_PURE_INLINE dReal dCalcVectorDot4(const dReal *a, const dReal *b)
*/
ODE_PURE_INLINE dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b)
{
return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
}
ODE_PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); }
ODE_PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); }
ODE_PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); }
ODE_PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); }
ODE_PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,4); }
ODE_PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b)
{
//return _dCalcVectorDot3(a,b,4,1);
return a[0] * b[0] + a[4] * b[1] + a[8] * b[2];
}
ODE_PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b)
{
//return _dCalcVectorDot3(a,b,4,4);
return a[0] * b[0] + a[4] * b[4] + a[8] * b[8];
}
#if defined(__AVX__)
ODE_PURE_INLINE void dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b)
@@ -1126,12 +1134,15 @@ ODE_PURE_INLINE void dCalcVectorCross3(dReal *res, const dReal *a, const dReal *
mb = _mm_loadu_ps(b);
t1 = _mm_shuffle_ps(ma, ma, _MM_SHUFFLE(3, 0, 2, 1)); // a1 a2 a0 a3
t2 = _mm_shuffle_ps(mb, mb, _MM_SHUFFLE(3, 1, 0, 2)); // b2 b0 b1 b2
t2 = _mm_shuffle_ps(mb, mb, _MM_SHUFFLE(3, 1, 0, 2)); // b2 b0 b1 b3
t3 = _mm_mul_ps(t1, t2); //a1b2 a2b0 a0b1 a3b2
t1 = _mm_shuffle_ps(t1, t1, _MM_SHUFFLE(3, 0, 2, 1));
t2 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(3, 1, 0, 2));
//t1 = _mm_shuffle_ps(t1, t1, _MM_SHUFFLE(3, 0, 2, 1));
//t2 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(3, 1, 0, 2));
t1 = _mm_shuffle_ps(ma, ma, _MM_SHUFFLE(3, 1, 0, 2));
t2 = _mm_shuffle_ps(mb, mb, _MM_SHUFFLE(3, 0, 2, 1));
t4 = _mm_mul_ps(t1, t2);
ma = _mm_sub_ps(t3, t4);
@@ -1154,12 +1165,14 @@ ODE_PURE_INLINE void dCalcVectorCross3r4(dReal *res, const dReal *a, const dReal
mb = _mm_loadu_ps(b);
t1 = _mm_shuffle_ps(ma, ma, _MM_SHUFFLE(3, 0, 2, 1)); // a1 a2 a0 a3
t2 = _mm_shuffle_ps(mb, mb, _MM_SHUFFLE(3, 1, 0, 2)); // b2 b0 b1 b2
t2 = _mm_shuffle_ps(mb, mb, _MM_SHUFFLE(3, 1, 0, 2)); // b2 b0 b1 b3
t3 = _mm_mul_ps(t1, t2); //a1b2 a2b0 a0b1 a3b2
t1 = _mm_shuffle_ps(t1, t1, _MM_SHUFFLE(3, 0, 2, 1));
t2 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(3, 1, 0, 2));
//t1 = _mm_shuffle_ps(t1, t1, _MM_SHUFFLE(3, 0, 2, 1));
//t2 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(3, 1, 0, 2));
t1 = _mm_shuffle_ps(ma, ma, _MM_SHUFFLE(3, 1, 0, 2));
t2 = _mm_shuffle_ps(mb, mb, _MM_SHUFFLE(3, 0, 2, 1));
t4 = _mm_mul_ps(t1, t2);
ma = _mm_sub_ps(t3, t4);
@@ -1181,12 +1194,19 @@ ODE_PURE_INLINE void dCalcVectorCross3r4(dReal *res, const dReal *a, const dReal
ODE_PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b)
{
res[ 0] = a[ step_a] * b[2*step_b] - a[2*step_a] *b [ step_b];
res[ step_res] = a[2*step_a] * b[ 0] - a[ 0] *b [2*step_b];
res[2 * step_res] = a[ 0] * b[ step_b] - a[ step_a] *b [ 0];
res[0] = a[step_a] * b[2 * step_b] - a[2 * step_a] * b[step_b];
res[step_res] = a[2 * step_a] * b[0] - a[0] * b[2 * step_b];
res[2 * step_res] = a[0] * b[step_b] - a[step_a] * b[0];
}
ODE_PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b)
{
//_dCalcVectorCross3(res, a, b, 1, 1, 4);
res[0] = a[1] * b[8] - a[2] * b[4];
res[1] = a[2] * b[0] - a[0] * b[8];
res[2] = a[0] * b[4] - a[1] * b[0];
}
ODE_PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); }
ODE_PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); }
ODE_PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); }
@@ -1562,32 +1582,27 @@ ODE_PURE_INLINE void dMultVector3r4(dReal *res, const dReal *a)
ODE_PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
{
__m128 ma, mb, mc;
dReal restmp[3];
mb = _mm_loadu_ps(b);
ma = _mm_loadu_ps(a);
mc = _mm_dp_ps(ma, mb, 0x71);
restmp[0] = (dReal)_mm_cvtss_f32(mc);
res[0] = (dReal)_mm_cvtss_f32(mc);
ma = _mm_loadu_ps(a + 4);
mc = _mm_dp_ps(ma, mb, 0x71);
restmp[1] = (dReal)_mm_cvtss_f32(mc);
res[1] = (dReal)_mm_cvtss_f32(mc);
ma = _mm_loadu_ps(a + 8);
mc = _mm_dp_ps(ma, mb, 0x71);
restmp[2] = (dReal)_mm_cvtss_f32(mc);
res[0] = restmp[0];
res[1] = restmp[1];
res[2] = restmp[2];
res[2] = (dReal)_mm_cvtss_f32(mc);
}
#else
ODE_PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
{
res[0] = dCalcVectorDot3(a, b);
res[1] = dCalcVectorDot3(a + 4, b);
res[2] = dCalcVectorDot3(a + 8, b);
res[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
res[1] = a[4] * b[0] + a[5] * b[1] + a[6] * b[2];
res[2] = a[8] * b[0] + a[9] * b[1] + a[10] * b[2];
}
#endif
@@ -1595,7 +1610,6 @@ ODE_PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b)
ODE_PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
{
__m128 ma, t0, t1, t2, m0, m1, m2, m3;
dReal restmp[3];
t0 = _mm_loadu_ps(a); // a0 a1 a2 a3
t1 = _mm_loadu_ps(a + 4); // a4 a5 a6 a7
@@ -1613,22 +1627,18 @@ ODE_PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
t2 = _mm_shuffle_ps(m2, m3, _MM_SHUFFLE(2, 2, 2, 0)); // a2 a6 a10 a10
m0 = _mm_dp_ps(ma, t0, 0x71);
restmp[0] = _mm_cvtss_f32(m0);
res[0] = _mm_cvtss_f32(m0);
m1 = _mm_dp_ps(ma, t1, 0x71);
restmp[1] = _mm_cvtss_f32(m1);
res[1] = _mm_cvtss_f32(m1);
m2 = _mm_dp_ps(ma, t2, 0x71);
restmp[2] = _mm_cvtss_f32(m2);
res[0] = restmp[0];
res[1] = restmp[1];
res[2] = restmp[2];
res[2] = _mm_cvtss_f32(m2);
}
#else
ODE_PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b)
{
res[0] = dCalcVectorDot3_41(a, b);
res[1] = dCalcVectorDot3_41(a + 1, b);
res[2] = dCalcVectorDot3_41(a + 2, b);
res[0] = a[0] * b[0] + a[4] * b[1] + a[8] * b[2];
res[1] = a[1] * b[0] + a[5] * b[1] + a[9] * b[2];
res[2] = a[2] * b[0] + a[6] * b[1] + a[10] * b[2];
}
#endif
@@ -23,140 +23,4 @@
#ifndef _ODE_ODEMATH_LEGACY_H_
#define _ODE_ODEMATH_LEGACY_H_
/*
* These macros are not used any more inside of ODE
* They are kept for backward compatibility with external code that
* might still be using them.
*/
/*
* General purpose vector operations with other vectors or constants.
*/
#define dOP(a,op,b,c) do { \
(a)[0] = ((b)[0]) op ((c)[0]); \
(a)[1] = ((b)[1]) op ((c)[1]); \
(a)[2] = ((b)[2]) op ((c)[2]); \
} while (0)
#define dOPC(a,op,b,c) do { \
(a)[0] = ((b)[0]) op (c); \
(a)[1] = ((b)[1]) op (c); \
(a)[2] = ((b)[2]) op (c); \
} while (0)
#define dOPE(a,op,b) do {\
(a)[0] op ((b)[0]); \
(a)[1] op ((b)[1]); \
(a)[2] op ((b)[2]); \
} while (0)
#define dOPEC(a,op,c) do { \
(a)[0] op (c); \
(a)[1] op (c); \
(a)[2] op (c); \
} while (0)
/* Define an equation with operators
* For example this function can be used to replace
* <PRE>
* for (int i=0; i<3; ++i)
* a[i] += b[i] + c[i];
* </PRE>
*/
#define dOPE2(a,op1,b,op2,c) do { \
(a)[0] op1 ((b)[0]) op2 ((c)[0]); \
(a)[1] op1 ((b)[1]) op2 ((c)[1]); \
(a)[2] op1 ((b)[2]) op2 ((c)[2]); \
} while (0)
#define dLENGTHSQUARED(a) dCalcVectorLengthSquare3(a)
#define dLENGTH(a) dCalcVectorLength3(a)
#define dDISTANCE(a, b) dCalcPointsDistance3(a, b)
#define dDOT(a, b) dCalcVectorDot3(a, b)
#define dDOT13(a, b) dCalcVectorDot3_13(a, b)
#define dDOT31(a, b) dCalcVectorDot3_31(a, b)
#define dDOT33(a, b) dCalcVectorDot3_33(a, b)
#define dDOT14(a, b) dCalcVectorDot3_14(a, b)
#define dDOT41(a, b) dCalcVectorDot3_41(a, b)
#define dDOT44(a, b) dCalcVectorDot3_44(a, b)
/*
* cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
* and `c' are spaced p, q and r indexes apart respectively.
* dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
* +=, -= etc to get other effects.
*/
#define dCROSS(a,op,b,c) \
do { \
(a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
(a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
(a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \
} while(0)
#define dCROSSpqr(a,op,b,c,p,q,r) \
do { \
(a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \
(a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \
(a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \
} while(0)
#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
/*
* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
* A is stored by rows, and has `skip' elements per row. the matrix is
* assumed to be already zero, so this does not write zero elements!
* if (plus,minus) is (+,-) then a positive version will be written.
* if (plus,minus) is (-,+) then a negative version will be written.
*/
#define dCROSSMAT(A,a,skip,plus,minus) \
do { \
(A)[1] = minus (a)[2]; \
(A)[2] = plus (a)[1]; \
(A)[(skip)+0] = plus (a)[2]; \
(A)[(skip)+2] = minus (a)[0]; \
(A)[2*(skip)+0] = minus (a)[1]; \
(A)[2*(skip)+1] = plus (a)[0]; \
} while(0)
/*
Note: NEVER call any of these functions/macros with the same variable for A and C,
it is not equivalent to A*=B.
*/
#define dMULTIPLY0_331(A, B, C) dMultiply0_331(A, B, C)
#define dMULTIPLY1_331(A, B, C) dMultiply1_331(A, B, C)
#define dMULTIPLY0_133(A, B, C) dMultiply0_133(A, B, C)
#define dMULTIPLY0_333(A, B, C) dMultiply0_333(A, B, C)
#define dMULTIPLY1_333(A, B, C) dMultiply1_333(A, B, C)
#define dMULTIPLY2_333(A, B, C) dMultiply2_333(A, B, C)
#define dMULTIPLYADD0_331(A, B, C) dMultiplyAdd0_331(A, B, C)
#define dMULTIPLYADD1_331(A, B, C) dMultiplyAdd1_331(A, B, C)
#define dMULTIPLYADD0_133(A, B, C) dMultiplyAdd0_133(A, B, C)
#define dMULTIPLYADD0_333(A, B, C) dMultiplyAdd0_333(A, B, C)
#define dMULTIPLYADD1_333(A, B, C) dMultiplyAdd1_333(A, B, C)
#define dMULTIPLYADD2_333(A, B, C) dMultiplyAdd2_333(A, B, C)
/*
* These macros are not used any more inside of ODE
* They are kept for backward compatibility with external code that
* might still be using them.
*/
#endif /* #ifndef _ODE_ODEMATH_LEGACY_H_ */
+11 -2
View File
@@ -332,8 +332,17 @@ static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd,
&ccdSimplexPoint(portal, 3)->v,
pdir);
*depth = CCD_SQRT(*depth);
ccdVec3Normalize(pdir);
if (ccdIsZero(*depth)){
// If depth is zero, then we have a touching contact.
// So following findPenetrTouch(), we assign zero to
// the direction vector (it can actually be anything
// according to the decription of ccdMPRPenetration
// function).
ccdVec3Copy(pdir, ccd_vec3_origin);
}else
{
ccdVec3Normalize(pdir);
}
// barycentric coordinates:
findPos(obj1, obj2, ccd, portal, pos);
@@ -168,8 +168,17 @@ ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P,
q = ccdVec3Dot(&a, &d2);
r = ccdVec3Dot(&d1, &d2);
s = (q * r - w * p) / (w * v - r * r);
t = (-s * r - q) / w;
ccd_real_t d = (w * v - r * r);
if (ccdIsZero(d))
{
// To avoid division by zero for zero (or near zero) area triangles
s = t = -1.;
}
else
{
s = (q * r - w * p) / d;
t = (-s * r - q) / w;
}
if ((ccdIsZero(s) || s > CCD_ZERO)
&& (ccdEq(s, CCD_ONE) || s < CCD_ONE)
@@ -147,11 +147,13 @@ static int colliders_initialized = 0;
static void setCollider (int i, int j, dColliderFn *fn)
{
if (colliders[i][j].fn == 0) {
if (colliders[i][j].fn == 0)
{
colliders[i][j].fn = fn;
colliders[i][j].reverse = 0;
}
if (colliders[j][i].fn == 0) {
if (colliders[j][i].fn == 0)
{
colliders[j][i].fn = fn;
colliders[j][i].reverse = 1;
}
@@ -98,7 +98,8 @@ enum dxContactMergeOptions {
// the pos and R of the body (if body nonzero).
// a dGeomID is a pointer to this object.
struct dxGeom : public dBase {
struct dxGeom : public dBase
{
int type; // geom type number, set by subclass constructor
int gflags; // flags used by geom and space
void *data; // user-defined data pointer
@@ -170,8 +171,10 @@ struct dxGeom : public dBase {
// compute the AABB only if it is not current. this function manipulates
// the GEOM_AABB_BAD flag.
void recomputeAABB() {
if (gflags & GEOM_AABB_BAD) {
void recomputeAABB()
{
if (gflags & GEOM_AABB_BAD)
{
// our aabb functions assume final_posr is up to date
recomputePosr();
computeAABB();
@@ -183,10 +186,12 @@ struct dxGeom : public dBase {
// add and remove this geom from a linked list maintained by a space.
void spaceAdd (dxGeom **first_ptr) {
void spaceAdd (dxGeom **first_ptr)
{
next = *first_ptr;
tome = first_ptr;
if (*first_ptr) (*first_ptr)->tome = &next;
if (*first_ptr)
(*first_ptr)->tome = &next;
*first_ptr = this;
}
void spaceRemove() {
@@ -196,7 +201,8 @@ struct dxGeom : public dBase {
// add and remove this geom from a linked list maintained by a body.
void bodyAdd (dxBody *b) {
void bodyAdd (dxBody *b)
{
body = b;
body_next = b->geom;
b->geom = this;
@@ -221,7 +227,8 @@ struct dxGeom : public dBase {
#define dSPACE_TLS_KIND_MANUAL_VALUE 0
#endif
struct dxSpace : public dxGeom {
struct dxSpace : public dxGeom
{
int count; // number of geoms in this space
dxGeom *first; // first geom in list
int cleanup; // cleanup mode, 1=destroy geoms on exit
@@ -269,8 +276,8 @@ struct dxSpace : public dxGeom {
//////////////////////////////////////////////////////////////////////////
/*inline */
void dxGeom::markAABBBad() {
inline void dxGeom::markAABBBad()
{
gflags |= (GEOM_DIRTY | GEOM_AABB_BAD);
CHECK_NOT_LOCKED(parent_space);
}
@@ -32,16 +32,6 @@
#include "collision_space_internal.h"
#define AXIS0 0
#define AXIS1 1
#define UP 2
//#define DRAWBLOCKS
const int SPLITAXIS = 2;
const int SPLITS = SPLITAXIS * SPLITAXIS;
#define GEOM_ENABLED(g) (((g)->gflags & GEOM_ENABLE_TEST_MASK) == GEOM_ENABLE_TEST_VALUE)
class Block
@@ -60,7 +50,6 @@ public:
void Collide(void* UserData, dNearCallback* Callback);
void Collide(dGeomID g1, dGeomID g2, void* UserData, dNearCallback* Callback);
void CollideLocal(dGeomID g2, void* UserData, dNearCallback* Callback);
void AddObject(dGeomID Object);
@@ -73,11 +62,10 @@ public:
Block* GetBlockChild(const dReal* AABB);
};
void Block::Create(const dReal MinX, const dReal MaxX, const dReal MinZ, const dReal MaxZ, Block* Parent, int Depth, Block*& Blocks)
void Block::Create(const dReal MinX, const dReal MaxX, const dReal MinY, const dReal MaxY, Block* Parent, int Depth, Block* &Blocks)
{
dIASSERT(MinX <= MaxX);
dIASSERT(MinZ <= MaxZ);
dIASSERT(MinY <= MaxY);
mGeomCount = 0;
mFirst = 0;
@@ -85,43 +73,34 @@ void Block::Create(const dReal MinX, const dReal MaxX, const dReal MinZ, const d
mMinX = MinX;
mMaxX = MaxX;
mMinZ = MinZ;
mMaxZ = MaxZ;
mMinZ = MinY;
mMaxZ = MaxY;
this->mParent = Parent;
if (Depth > 0)
{
mChildren = Blocks;
Blocks += SPLITS;
const dReal ChildExtentX = (MaxX - MinX) / SPLITAXIS;
const dReal ChildExtentZ = (MaxZ - MinZ) / SPLITAXIS;
const int ChildDepth = Depth - 1;
int Index = 0;
dReal ChildRightX = MinX;
for (int i = 0; i < SPLITAXIS; i++)
{
const dReal ChildLeftX = ChildRightX;
ChildRightX = (i != SPLITAXIS - 1) ? ChildLeftX + ChildExtentX : MaxX;
mChildren = Blocks;
Blocks += 4;
dReal ChildRightZ = MinZ;
for (int j = 0; j < SPLITAXIS; j++)
{
const dReal ChildLeftZ = ChildRightZ;
ChildRightZ = (j != SPLITAXIS - 1) ? ChildLeftZ + ChildExtentZ : MaxZ;
const dReal ChildExtentX = (MaxX - MinX) * dReal(0.5);
const dReal ChildExtentY = (MaxY - MinY) * dReal(0.5);
const dReal ChildMidX = MinX + ChildExtentX;
const dReal ChildMidY = MinY + ChildExtentY;
mChildren[0].Create(MinX, ChildMidX, MinY, ChildMidY, this, ChildDepth, Blocks);
mChildren[1].Create(MinX, ChildMidX, ChildMidY, MaxY, this, ChildDepth, Blocks);
mChildren[Index].Create(ChildLeftX, ChildRightX, ChildLeftZ, ChildRightZ, this, ChildDepth, Blocks);
++Index;
}
}
mChildren[2].Create(ChildMidX, MaxX, MinY, ChildMidY, this, ChildDepth, Blocks);
mChildren[3].Create(ChildMidX, MaxX, ChildMidY, MaxY, this, ChildDepth, Blocks);
}
else mChildren = 0;
else
mChildren = 0;
}
void Block::Collide(void* UserData, dNearCallback* Callback){
void Block::Collide(void* UserData, dNearCallback* Callback)
{
// Collide the local list
dxGeom* g = mFirst;
while (g)
@@ -136,7 +115,7 @@ void Block::Collide(void* UserData, dNearCallback* Callback){
// Recurse for children
if (mChildren)
{
for (int i = 0; i < SPLITS; i++)
for (int i = 0; i < 4; i++)
{
Block &CurrentChild = mChildren[i];
if (CurrentChild.mGeomCount <= 1)
@@ -149,22 +128,20 @@ void Block::Collide(void* UserData, dNearCallback* Callback){
}
// Note: g2 is assumed to be in this Block
void Block::Collide(dxGeom* g1, dxGeom* g2, void* UserData, dNearCallback* Callback)
void Block::Collide(dGeomID g1, dGeomID g2, void* UserData, dNearCallback* Callback)
{
// Collide against local list
while (g2)
{
if (GEOM_ENABLED(g2))
{
collideAABBs (g1, g2, UserData, Callback);
}
if (GEOM_ENABLED(g2) && testCollideAABBs(g1, g2))
Callback(UserData, g1, g2);
g2 = g2->next_ex;
}
// Collide against children
if (mChildren)
{
for (int i = 0; i < SPLITS; i++)
for (int i = 0; i < 4; i++)
{
Block &CurrentChild = mChildren[i];
// Early out for empty blocks
@@ -177,24 +154,24 @@ void Block::Collide(dxGeom* g1, dxGeom* g2, void* UserData, dNearCallback* Callb
// Don't do AABB tests for single geom blocks.
if (CurrentChild.mGeomCount > 1)
{
if (g1->aabb[AXIS0 * 2 + 0] >= CurrentChild.mMaxX ||
g1->aabb[AXIS0 * 2 + 1] < CurrentChild.mMinX ||
g1->aabb[AXIS1 * 2 + 0] >= CurrentChild.mMaxZ ||
g1->aabb[AXIS1 * 2 + 1] < CurrentChild.mMinZ)
if (g1->aabb[0] > CurrentChild.mMaxX ||
g1->aabb[1] < CurrentChild.mMinX ||
g1->aabb[2] > CurrentChild.mMaxZ ||
g1->aabb[3] < CurrentChild.mMinZ)
continue;
}
CurrentChild.Collide(g1, CurrentChild.mFirst, UserData, Callback);
}
}
}
void Block::CollideLocal(dxGeom* g2, void* UserData, dNearCallback* Callback){
void Block::CollideLocal(dGeomID g2, void* UserData, dNearCallback* Callback)
{
// Collide against local list
dxGeom* g1 = mFirst;
while (g1){
if (GEOM_ENABLED(g1)){
collideAABBs (g1, g2, UserData, Callback);
}
while (g1)
{
if (GEOM_ENABLED(g1) && testCollideAABBs(g1, g2))
Callback(UserData, g1, g2);
g1 = g1->next_ex;
}
}
@@ -229,7 +206,6 @@ void Block::DelObject(dGeomID Object)
Last->next_ex = g->next_ex;
else
mFirst = g->next_ex;
break;
}
Last = g;
@@ -261,12 +237,12 @@ void Block::Traverse(dGeomID Object)
}
}
bool Block::Inside(const dReal* AABB)
inline bool Block::Inside(const dReal* AABB)
{
return AABB[AXIS0 * 2 + 0] >= mMinX &&
AABB[AXIS0 * 2 + 1] < mMaxX &&
AABB[AXIS1 * 2 + 0] >= mMinZ &&
AABB[AXIS1 * 2 + 1] < mMaxZ;
return AABB[0] > mMinX &&
AABB[1] < mMaxX &&
AABB[2] > mMinZ &&
AABB[3] < mMaxZ;
}
Block* Block::GetBlock(const dReal* AABB)
@@ -286,7 +262,7 @@ Block* Block::GetBlockChild(const dReal* AABB)
{
if (mChildren)
{
for (int i = 0; i < SPLITS; i++)
for (int i = 0; i < 4; i++)
{
Block &CurrentChild = mChildren[i];
if (CurrentChild.Inside(AABB))
@@ -350,10 +326,10 @@ dxQuadTreeSpace::dxQuadTreeSpace(dSpaceID _space, const dVector3 Center, const d
return;
}
dReal MinX = Center[AXIS0] - Extents[AXIS0];
dReal MaxX = dNextAfter((Center[AXIS0] + Extents[AXIS0]), (dReal)dInfinity);
dReal MinZ = Center[AXIS1] - Extents[AXIS1];
dReal MaxZ = dNextAfter((Center[AXIS1] + Extents[AXIS1]), (dReal)dInfinity);
dReal MinX = Center[0] - Extents[0];
dReal MaxX = dNextAfter((Center[0] + Extents[0]), (dReal)dInfinity);
dReal MinZ = Center[1] - Extents[1];
dReal MaxZ = dNextAfter((Center[1] + Extents[1]), (dReal)dInfinity);
Block* nBlocks = this->Blocks + 1; // This pointer gets modified!
this->Blocks[0].Create(MinX, MaxX, MinZ, MaxZ, 0, Depth, nBlocks);
@@ -380,7 +356,7 @@ dxGeom* dxQuadTreeSpace::getGeom(int Index){
//@@@
dDebug (0,"dxQuadTreeSpace::getGeom() not yet implemented");
return 0;
// This doesnt work
/*
if (CurrentIndex == Index){
@@ -446,7 +422,8 @@ PARENTRECURSE:
*/
}
void dxQuadTreeSpace::add(dxGeom* g){
void dxQuadTreeSpace::add(dxGeom* g)
{
CHECK_NOT_LOCKED (this);
dAASSERT(g);
dUASSERT(g->tome_ex == 0 && g->next_ex == 0, "geom is already in a space");
@@ -465,32 +442,38 @@ void dxQuadTreeSpace::remove(dxGeom* g){
// remove
((Block*)g->tome_ex)->DelObject(g);
for (int i = 0; i < DirtyList.size(); i++){
if (DirtyList[i] == g){
for (int i = 0; i < DirtyList.size(); i++)
{
if (DirtyList[i] == g)
{
DirtyList.remove(i);
// (mg) there can be multiple instances of a dirty object on stack be sure to remove ALL and not just first, for this we decrement i
--i;
}
}
dxSpace::remove(g);
}
void dxQuadTreeSpace::dirty(dxGeom* g){
void dxQuadTreeSpace::dirty(dxGeom* g)
{
DirtyList.push(g);
}
void dxQuadTreeSpace::computeAABB(){
void dxQuadTreeSpace::computeAABB()
{
//
}
void dxQuadTreeSpace::cleanGeoms(){
void dxQuadTreeSpace::cleanGeoms()
{
// compute the AABBs of all dirty geoms, and clear the dirty flags
lock_count++;
for (int i = 0; i < DirtyList.size(); i++){
for (int i = 0; i < DirtyList.size(); i++)
{
dxGeom* g = DirtyList[i];
if (IS_SPACE(g)){
if (IS_SPACE(g))
{
((dxSpace*)g)->cleanGeoms();
}
g->recomputeAABB();
@@ -503,7 +486,8 @@ void dxQuadTreeSpace::cleanGeoms(){
lock_count--;
}
void dxQuadTreeSpace::collide(void* UserData, dNearCallback* Callback){
void dxQuadTreeSpace::collide(void* UserData, dNearCallback* Callback)
{
dAASSERT(Callback);
lock_count++;
@@ -515,7 +499,8 @@ void dxQuadTreeSpace::collide(void* UserData, dNearCallback* Callback){
}
struct DataCallback {
struct DataCallback
{
void *data;
dNearCallback *callback;
};
@@ -527,14 +512,16 @@ static void swap_callback(void *data, dxGeom *g1, dxGeom *g2)
}
void dxQuadTreeSpace::collide2(void* UserData, dxGeom* g2, dNearCallback* Callback){
void dxQuadTreeSpace::collide2(void* UserData, dxGeom* g2, dNearCallback* Callback)
{
dAASSERT(g2 && Callback);
lock_count++;
cleanGeoms();
g2->recomputeAABB();
if (g2->parent_space == this){
if (g2->parent_space == this)
{
// The block the geom is in
Block* CurrentBlock = (Block*)g2->tome_ex;
@@ -545,9 +532,9 @@ void dxQuadTreeSpace::collide2(void* UserData, dxGeom* g2, dNearCallback* Callba
// Collide against parents
while ((CurrentBlock = CurrentBlock->mParent))
CurrentBlock->CollideLocal(g2, UserData, Callback);
}
else {
else
{
DataCallback dc = {UserData, Callback};
Blocks[0].Collide(g2, Blocks[0].mFirst, &dc, swap_callback);
}
@@ -555,6 +542,7 @@ void dxQuadTreeSpace::collide2(void* UserData, dxGeom* g2, dNearCallback* Callba
lock_count--;
}
dSpaceID dQuadTreeSpaceCreate(dxSpace* space, const dVector3 Center, const dVector3 Extents, int Depth){
dSpaceID dQuadTreeSpaceCreate(dxSpace* space, const dVector3 Center, const dVector3 Extents, int Depth)
{
return new dxQuadTreeSpace(space, Center, Extents, Depth);
}
@@ -210,7 +210,8 @@ private:
};
// Creation
dSpaceID dSweepAndPruneSpaceCreate( dxSpace* space, int axisorder ) {
dSpaceID dSweepAndPruneSpaceCreate( dxSpace* space, int axisorder )
{
return new dxSAPSpace( space, axisorder );
}
@@ -237,11 +238,11 @@ static void collideGeomsNoAABBs( dxGeom *g1, dxGeom *g2, void *data, dNearCallba
dIASSERT( (g2->gflags & GEOM_AABB_BAD)==0 );
// no contacts if both geoms on the same body, and the body is not 0
if (g1->body == g2->body && g1->body) return;
if (g1->body && g1->body == g2->body) return;
// test if the category and collide bitfields match
if ( ((g1->category_bits & g2->collide_bits) ||
(g2->category_bits & g1->collide_bits)) == 0) {
if ( ((g1->category_bits & g2->collide_bits) || (g2->category_bits & g1->collide_bits)) == 0)
{
return;
}
File diff suppressed because it is too large Load Diff
@@ -40,19 +40,19 @@ stuff common to all spaces
// NOTE: this assumes that the geom AABBs are valid on entry
// and that both geoms are enabled.
static inline void collideAABBs (dxGeom *g1, dxGeom *g2,
static inline void collideAABBs(dxGeom *g1, dxGeom *g2,
void *data, dNearCallback *callback)
{
dIASSERT((g1->gflags & GEOM_AABB_BAD)==0);
dIASSERT((g2->gflags & GEOM_AABB_BAD)==0);
// no contacts if both geoms on the same body, and the body is not 0
if (g1->body == g2->body && g1->body) return;
if (g1->body && g1->body == g2->body) return;
// test if the category and collide bitfields match
if ( ((g1->category_bits & g2->collide_bits) ||
(g2->category_bits & g1->collide_bits)) == 0) {
return;
if ( ((g1->category_bits & g2->collide_bits) || (g2->category_bits & g1->collide_bits)) == 0)
{
return;
}
// if the bounding boxes are disjoint then don't do anything
@@ -69,11 +69,42 @@ static inline void collideAABBs (dxGeom *g1, dxGeom *g2,
// check if either object is able to prove that it doesn't intersect the
// AABB of the other
if (g1->AABBTest (g2,bounds2) == 0) return;
if (g2->AABBTest (g1,bounds1) == 0) return;
//if (g1->AABBTest(g2, bounds2) == 0) return;
//if (g2->AABBTest(g1, bounds1) == 0) return;
// the objects might actually intersect - call the space callback function
callback (data,g1,g2);
}
static inline bool testCollideAABBs(dxGeom *g1, dxGeom *g2)
{
dIASSERT((g1->gflags & GEOM_AABB_BAD) == 0);
dIASSERT((g2->gflags & GEOM_AABB_BAD) == 0);
// no contacts if both geoms on the same body, and the body is not 0
if (g1->body && g1->body == g2->body) return false;
// test if the category and collide bitfields match
if (((g1->category_bits & g2->collide_bits) || (g2->category_bits & g1->collide_bits)) == 0)
{
return false;
}
// if the bounding boxes are disjoint then don't do anything
dReal *bounds1 = g1->aabb;
dReal *bounds2 = g2->aabb;
if (bounds1[0] > bounds2[1] ||
bounds1[1] < bounds2[0] ||
bounds1[2] > bounds2[3] ||
bounds1[3] < bounds2[2] ||
bounds1[4] > bounds2[5] ||
bounds1[5] < bounds2[4]) return false;
// check if either object is able to prove that it doesn't intersect the
// AABB of the other
//if (g1->AABBTest(g2, bounds2) == 0) return false;
//if (g2->AABBTest(g1, bounds1) == 0) return false;
return true;
}
#endif
@@ -474,8 +474,8 @@ dReal dJointGetAMotorAngleRate( dJointID j, int anum )
if (joint->node[0].body) {
dVector3 axis;
dJointGetAMotorAxis (joint, anum, axis);
dReal rate = dDOT(axis,joint->node[0].body->avel);
if (joint->node[1].body) rate -= dDOT(axis,joint->node[1].body->avel);
dReal rate = dCalcVectorDot3(axis,joint->node[0].body->avel);
if (joint->node[1].body) rate -= dCalcVectorDot3(axis,joint->node[1].body->avel);
return rate;
}
return 0;
+12 -12
View File
@@ -35,23 +35,23 @@
#ifdef __cplusplus
template <typename element_type>
ODE_INLINE
void _dSetZero (element_type *a, size_t n)
ODE_INLINE void _dSetZero (element_type *a, size_t n)
{
element_type *acurr = a;
element_type *const aend = a + n;
while (acurr != aend) {
while (acurr != aend)
{
*(acurr++) = 0;
}
}
template <typename element_type>
ODE_INLINE
void _dSetValue (element_type *a, size_t n, element_type value)
ODE_INLINE void _dSetValue (element_type *a, size_t n, element_type value)
{
element_type *acurr = a;
element_type *const aend = a + n;
while (acurr != aend) {
while (acurr != aend)
{
*(acurr++) = value;
}
}
@@ -59,22 +59,22 @@ void _dSetValue (element_type *a, size_t n, element_type value)
#else // #ifndef __cplusplus
ODE_PURE_INLINE
void _dSetZero (dReal *a, size_t n)
ODE_PURE_INLINE void _dSetZero (dReal *a, size_t n)
{
dReal *acurr = a;
dReal *const aend = a + n;
while (acurr != aend) {
while (acurr != aend)
{
*(acurr++) = 0;
}
}
ODE_PURE_INLINE
void _dSetValue (dReal *a, size_t n, dReal value)
ODE_PURE_INLINE void _dSetValue (dReal *a, size_t n, dReal value)
{
dReal *acurr = a;
dReal *const aend = a + n;
while (acurr != aend) {
while (acurr != aend)
{
*(acurr++) = value;
}
}