add normal cone optimization for self-collision
This commit is contained in:
@@ -21,7 +21,7 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
|
||||
#include <iostream>
|
||||
//
|
||||
// Compile time configuration
|
||||
//
|
||||
@@ -131,6 +131,8 @@ subject to the following restrictions:
|
||||
/* btDbvtAabbMm */
|
||||
struct btDbvtAabbMm
|
||||
{
|
||||
DBVT_INLINE btDbvtAabbMm(){}
|
||||
DBVT_INLINE btDbvtAabbMm(const btDbvtAabbMm& other): mi(other.mi), mx(other.mx){}
|
||||
DBVT_INLINE btVector3 Center() const { return ((mi + mx) / 2); }
|
||||
DBVT_INLINE btVector3 Lengths() const { return (mx - mi); }
|
||||
DBVT_INLINE btVector3 Extents() const { return ((mx - mi) / 2); }
|
||||
@@ -190,6 +192,36 @@ struct btDbvtNode
|
||||
};
|
||||
};
|
||||
|
||||
/* btDbv(normal)tNode */
|
||||
struct btDbvntNode
|
||||
{
|
||||
btDbvtVolume volume;
|
||||
btVector3 normal;
|
||||
btScalar angle;
|
||||
DBVT_INLINE bool isleaf() const { return (childs[1] == 0); }
|
||||
DBVT_INLINE bool isinternal() const { return (!isleaf()); }
|
||||
btDbvntNode* childs[2];
|
||||
void* data;
|
||||
|
||||
btDbvntNode(const btDbvtNode* n)
|
||||
: volume(n->volume)
|
||||
, angle(0)
|
||||
, normal(0,0,0)
|
||||
, data(n->data)
|
||||
{
|
||||
childs[0] = 0;
|
||||
childs[1] = 0;
|
||||
}
|
||||
|
||||
~btDbvntNode()
|
||||
{
|
||||
if (childs[0])
|
||||
delete childs[0];
|
||||
if (childs[1])
|
||||
delete childs[1];
|
||||
}
|
||||
};
|
||||
|
||||
typedef btAlignedObjectArray<const btDbvtNode*> btNodeStack;
|
||||
|
||||
///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
|
||||
@@ -225,6 +257,14 @@ struct btDbvt
|
||||
btDbvtNode* parent;
|
||||
sStkCLN(const btDbvtNode* n, btDbvtNode* p) : node(n), parent(p) {}
|
||||
};
|
||||
|
||||
struct sStknNN
|
||||
{
|
||||
const btDbvntNode* a;
|
||||
const btDbvntNode* b;
|
||||
sStknNN() {}
|
||||
sStknNN(const btDbvntNode* na, const btDbvntNode* nb) : a(na), b(nb) {}
|
||||
};
|
||||
// Policies/Interfaces
|
||||
|
||||
/* ICollide */
|
||||
@@ -234,6 +274,7 @@ struct btDbvt
|
||||
DBVT_VIRTUAL void Process(const btDbvtNode*, const btDbvtNode*) {}
|
||||
DBVT_VIRTUAL void Process(const btDbvtNode*) {}
|
||||
DBVT_VIRTUAL void Process(const btDbvtNode* n, btScalar) { Process(n); }
|
||||
DBVT_VIRTUAL void Process(const btDbvntNode*, const btDbvntNode*) {}
|
||||
DBVT_VIRTUAL bool Descent(const btDbvtNode*) { return (true); }
|
||||
DBVT_VIRTUAL bool AllLeaves(const btDbvtNode*) { return (true); }
|
||||
};
|
||||
@@ -306,6 +347,9 @@ struct btDbvt
|
||||
void collideTT(const btDbvtNode* root0,
|
||||
const btDbvtNode* root1,
|
||||
DBVT_IPOLICY);
|
||||
DBVT_PREFIX
|
||||
void selfCollideT(const btDbvntNode* root,
|
||||
DBVT_IPOLICY);
|
||||
|
||||
DBVT_PREFIX
|
||||
void collideTTpersistentStack(const btDbvtNode* root0,
|
||||
@@ -837,6 +881,71 @@ inline void btDbvt::collideTT(const btDbvtNode* root0,
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
DBVT_PREFIX
|
||||
inline void btDbvt::selfCollideT(const btDbvntNode* root,
|
||||
DBVT_IPOLICY)
|
||||
{
|
||||
DBVT_CHECKTYPE
|
||||
if (root)
|
||||
{
|
||||
int depth = 1;
|
||||
int treshold = DOUBLE_STACKSIZE - 4;
|
||||
btAlignedObjectArray<sStknNN> stkStack;
|
||||
stkStack.resize(DOUBLE_STACKSIZE);
|
||||
stkStack[0] = sStknNN(root, root);
|
||||
do
|
||||
{
|
||||
sStknNN p = stkStack[--depth];
|
||||
if (depth > treshold)
|
||||
{
|
||||
stkStack.resize(stkStack.size() * 2);
|
||||
treshold = stkStack.size() - 4;
|
||||
}
|
||||
if (p.a == p.b)
|
||||
{
|
||||
if (p.a->isinternal() && p.a->angle > SIMD_PI)
|
||||
{
|
||||
stkStack[depth++] = sStknNN(p.a->childs[0], p.a->childs[0]);
|
||||
stkStack[depth++] = sStknNN(p.a->childs[1], p.a->childs[1]);
|
||||
stkStack[depth++] = sStknNN(p.a->childs[0], p.a->childs[1]);
|
||||
}
|
||||
}
|
||||
else if (Intersect(p.a->volume, p.b->volume))
|
||||
{
|
||||
if (p.a->isinternal())
|
||||
{
|
||||
if (p.b->isinternal())
|
||||
{
|
||||
stkStack[depth++] = sStknNN(p.a->childs[0], p.b->childs[0]);
|
||||
stkStack[depth++] = sStknNN(p.a->childs[1], p.b->childs[0]);
|
||||
stkStack[depth++] = sStknNN(p.a->childs[0], p.b->childs[1]);
|
||||
stkStack[depth++] = sStknNN(p.a->childs[1], p.b->childs[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
stkStack[depth++] = sStknNN(p.a->childs[0], p.b);
|
||||
stkStack[depth++] = sStknNN(p.a->childs[1], p.b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.b->isinternal())
|
||||
{
|
||||
stkStack[depth++] = sStknNN(p.a, p.b->childs[0]);
|
||||
stkStack[depth++] = sStknNN(p.a, p.b->childs[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
policy.Process(p.a, p.b);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DBVT_PREFIX
|
||||
inline void btDbvt::collideTTpersistentStack(const btDbvtNode* root0,
|
||||
const btDbvtNode* root1,
|
||||
|
||||
Reference in New Issue
Block a user