void Actor::attachBasedOnFlags(base::Compound* c) { PxBounds3 b; c->getLocalBounds(b); // Determine sheet face if (mSheetFracture) { PxVec3 dim = b.getDimensions(); if ( dim.x < dim.y && dim.x < dim.z ) { ((Compound*)c)->mNormal = PxVec3(1.f,0.f,0.f); } else if ( dim.y < dim.x && dim.y < dim.z ) { ((Compound*)c)->mNormal = PxVec3(0.f,1.f,0.f); } else { ((Compound*)c)->mNormal = PxVec3(0.f,0.f,1.f); } } // Attach const float w = 0.01f*b.getDimensions().maxElement(); nvidia::Array<PxBounds3> bounds; bounds.reserve(6); if (mAttachmentFlags.posX) { PxBounds3 a(b); a.minimum.x = a.maximum.x-w; bounds.pushBack(a); } if (mAttachmentFlags.negX) { PxBounds3 a(b); a.maximum.x = a.minimum.x+w; bounds.pushBack(a); } if (mAttachmentFlags.posY) { PxBounds3 a(b); a.minimum.y = a.maximum.y-w; bounds.pushBack(a); } if (mAttachmentFlags.negY) { PxBounds3 a(b); a.maximum.y = a.minimum.y+w; bounds.pushBack(a); } if (mAttachmentFlags.posZ) { PxBounds3 a(b); a.minimum.z = a.maximum.z-w; bounds.pushBack(a); } if (mAttachmentFlags.negZ) { PxBounds3 a(b); a.maximum.z = a.minimum.z+w; bounds.pushBack(a); } c->attachLocal(bounds); }
////////////////////////////////////////////////////////////////////////// // checks if points form a valid AABB cube, if not construct a default CUBE static bool checkPointsAABBValidity(PxU32 numPoints, const PxVec3* points, PxU32 stride , float distanceEpsilon, float resizeValue, PxVec3& center, PxVec3& scale, PxU32& vcount, PxVec3* vertices, bool fCheck = false) { const char* vtx = reinterpret_cast<const char *> (points); PxBounds3 bounds; bounds.setEmpty(); // get the bounding box for (PxU32 i = 0; i < numPoints; i++) { const PxVec3& p = *reinterpret_cast<const PxVec3 *> (vtx); vtx += stride; bounds.include(p); } PxVec3 dim = bounds.getDimensions(); center = bounds.getCenter(); // special case, the AABB is very thin or user provided us with only input 2 points // we construct an AABB cube and return it if ( dim.x < distanceEpsilon || dim.y < distanceEpsilon || dim.z < distanceEpsilon || numPoints < 3 ) { float len = FLT_MAX; // pick the shortest size bigger than the distance epsilon if ( dim.x > distanceEpsilon && dim.x < len ) len = dim.x; if ( dim.y > distanceEpsilon && dim.y < len ) len = dim.y; if ( dim.z > distanceEpsilon && dim.z < len ) len = dim.z; // if the AABB is small in all dimensions, resize it if ( len == FLT_MAX ) { dim = PxVec3(resizeValue); } // if one edge is small, set to 1/5th the shortest non-zero edge. else { if ( dim.x < distanceEpsilon ) dim.x = len * 0.05f; else dim.x *= 0.5f; if ( dim.y < distanceEpsilon ) dim.y = len * 0.05f; else dim.y *= 0.5f; if ( dim.z < distanceEpsilon ) dim.z = len * 0.05f; else dim.z *= 0.5f; } // construct the AABB const PxVec3 extPos = center + dim; const PxVec3 extNeg = center - dim; if(fCheck) vcount = 0; vertices[vcount++] = extNeg; vertices[vcount++] = PxVec3(extPos.x,extNeg.y,extNeg.z); vertices[vcount++] = PxVec3(extPos.x,extPos.y,extNeg.z); vertices[vcount++] = PxVec3(extNeg.x,extPos.y,extNeg.z); vertices[vcount++] = PxVec3(extNeg.x,extNeg.y,extPos.z); vertices[vcount++] = PxVec3(extPos.x,extNeg.y,extPos.z); vertices[vcount++] = extPos; vertices[vcount++] = PxVec3(extNeg.x,extPos.y,extPos.z); return true; // return cube } else { scale = dim; } return false; }