PlaneConvex

Working example of a plane convex type, now groundplane does not need to create a box for its collisions.
This commit is contained in:
marauder2k7 2024-05-19 01:18:50 +01:00
parent b7c04c5734
commit 2d2d3c7560
4 changed files with 130 additions and 16 deletions

View file

@ -272,37 +272,37 @@ void GroundPlane::buildConvex( const Box3F& box, Convex* convex )
return; return;
// See if we already have a convex in the working set. // See if we already have a convex in the working set.
BoxConvex *boxConvex = NULL; PlaneConvex *planeConvex = NULL;
CollisionWorkingList &wl = convex->getWorkingList(); CollisionWorkingList &wl = convex->getWorkingList();
CollisionWorkingList *itr = wl.wLink.mNext; CollisionWorkingList *itr = wl.wLink.mNext;
for ( ; itr != &wl; itr = itr->wLink.mNext ) for ( ; itr != &wl; itr = itr->wLink.mNext )
{ {
if ( itr->mConvex->getType() == BoxConvexType && if ( itr->mConvex->getType() == PlaneConvexType &&
itr->mConvex->getObject() == this ) itr->mConvex->getObject() == this )
{ {
boxConvex = (BoxConvex*)itr->mConvex; planeConvex = (PlaneConvex*)itr->mConvex;
break; break;
} }
} }
if ( !boxConvex ) if ( !planeConvex)
{ {
boxConvex = new BoxConvex; planeConvex = new PlaneConvex;
mConvexList->registerObject( boxConvex ); mConvexList->registerObject(planeConvex);
boxConvex->init( this ); planeConvex->init( this );
convex->addToWorkingList( boxConvex ); convex->addToWorkingList(planeConvex);
} }
// Update our convex to best match the queried box // Update our convex to best match the queried box
if ( boxConvex ) if (planeConvex)
{ {
Point3F queryCenter = box.getCenter(); Point3F queryCenter = box.getCenter();
boxConvex->mCenter = Point3F( queryCenter.x, queryCenter.y, -GROUND_PLANE_BOX_HEIGHT_HALF ); planeConvex->mCenter = Point3F( queryCenter.x, queryCenter.y, 0 );
boxConvex->mSize = Point3F( box.getExtents().x, planeConvex->mSize = Point3F( box.getExtents().x,
box.getExtents().y, box.getExtents().y,
GROUND_PLANE_BOX_HEIGHT_HALF ); 0 );
} }
} }

View file

@ -215,3 +215,100 @@ const MatrixF& OrthoBoxConvex::getTransform() const
return mOrthoMatrixCache; return mOrthoMatrixCache;
} }
Point3F PlaneConvex::getVertex(S32 v)
{
Point3F p = mCenter;
p.x += (v & 1) ? mSize.x : -mSize.x;
p.y += (v & 2) ? mSize.y : -mSize.y;
return p;
}
void PlaneConvex::emitEdge(S32 v1, S32 v2, const MatrixF& mat, ConvexFeature* cf)
{
S32 vc = cf->mVertexList.size();
cf->mVertexList.increment(2);
Point3F* vp = cf->mVertexList.begin();
mat.mulP(getVertex(v1), &vp[vc]);
mat.mulP(getVertex(v2), &vp[vc + 1]);
cf->mEdgeList.increment();
ConvexFeature::Edge& edge = cf->mEdgeList.last();
edge.vertex[0] = vc;
edge.vertex[1] = vc + 1;
}
void PlaneConvex::emitFace(const MatrixF& mat, ConvexFeature* cf) {
// Assuming sFace contains a single face definition for the plane
Face& face = sFace[4];
// Emit vertices
S32 vc = cf->mVertexList.size();
cf->mVertexList.increment(4);
Point3F* vp = cf->mVertexList.begin();
for (S32 v = 0; v < 4; v++) {
mat.mulP(getVertex(face.vertex[v]), &vp[vc + v]);
}
// Emit edges
cf->mEdgeList.increment(4);
ConvexFeature::Edge* edge = cf->mEdgeList.end() - 4;
for (S32 e = 0; e < 4; e++) {
edge[e].vertex[0] = vc + e;
edge[e].vertex[1] = vc + ((e + 1) & 3);
}
// Emit 2 triangle faces
cf->mFaceList.increment(2);
ConvexFeature::Face* ef = cf->mFaceList.end() - 2;
mat.getColumn(face.axis, &ef->normal);
ef[1].normal = ef[0].normal;
ef[1].vertex[0] = ef[0].vertex[0] = vc;
ef[1].vertex[1] = ef[0].vertex[2] = vc + 2;
ef[0].vertex[1] = vc + 1;
ef[1].vertex[2] = vc + 3;
}
Point3F PlaneConvex::support(const VectorF& v) const {
Point3F p = mCenter;
p.x += (v.x >= 0) ? mSize.x : -mSize.x;
p.y += (v.y >= 0) ? mSize.y : -mSize.y;
return p;
}
void PlaneConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf)
{
cf->material = 0;
cf->mObject = mObject;
// Emit edges
for (S32 i = 0; i < 4; ++i) {
S32 next = (i + 1) % 4;
emitEdge(i, next, mat, cf);
}
emitFace(mat, cf);
}
void PlaneConvex::getPolyList(AbstractPolyList* list)
{
list->setTransform(&getTransform(), getScale());
list->setObject(getObject());
U32 base = list->addPoint(mCenter + Point3F(-mSize.x, -mSize.y, -mSize.z));
list->addPoint(mCenter + Point3F(mSize.x, -mSize.y, -mSize.z));
list->addPoint(mCenter + Point3F(-mSize.x, mSize.y, -mSize.z));
list->addPoint(mCenter + Point3F(mSize.x, mSize.y, -mSize.z));
list->begin(0, 0);
list->vertex(base + sFace[4].vertex[3]);
list->vertex(base + sFace[4].vertex[2]);
list->vertex(base + sFace[4].vertex[1]);
list->vertex(base + sFace[4].vertex[0]);
list->plane(base + sFace[4].vertex[2],
base + sFace[4].vertex[1],
base + sFace[4].vertex[0]);
list->end();
}

View file

@ -48,7 +48,6 @@ public:
void getPolyList(AbstractPolyList* list) override; void getPolyList(AbstractPolyList* list) override;
}; };
class OrthoBoxConvex : public BoxConvex class OrthoBoxConvex : public BoxConvex
{ {
typedef BoxConvex Parent; typedef BoxConvex Parent;
@ -60,4 +59,21 @@ class OrthoBoxConvex: public BoxConvex
const MatrixF& getTransform() const override; const MatrixF& getTransform() const override;
}; };
class PlaneConvex : public Convex
{
Point3F getVertex(S32 v);
void emitEdge(S32 v1, S32 v2, const MatrixF& mat, ConvexFeature* cf);
void emitFace(const MatrixF& mat, ConvexFeature* cf);
public:
Point3F mCenter;
VectorF mSize;
PlaneConvex() { mType = PlaneConvexType; }
void init(SceneObject* obj) { mObject = obj; }
Point3F support(const VectorF& v) const override;
void getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf) override;
void getPolyList(AbstractPolyList* list) override;
};
#endif #endif

View file

@ -90,7 +90,8 @@ enum ConvexType {
TSPolysoupConvexType, TSPolysoupConvexType,
MeshRoadConvexType, MeshRoadConvexType,
ConvexShapeCollisionConvexType, ConvexShapeCollisionConvexType,
ForestConvexType ForestConvexType,
PlaneConvexType
}; };