Vector3<float> CollisionConvexHullShape::computeLocalInertia(float mass) const { AABBox<float> aabbox = toAABBox(PhysicsTransform()); float width = 2.0 * aabbox.getHalfSize(0); float height = 2.0 * aabbox.getHalfSize(1); float depth = 2.0 * aabbox.getHalfSize(2); float localInertia1 = (1.0/12.0) * mass * (height*height + depth*depth); float localInertia2 = (1.0/12.0) * mass * (width*width + depth*depth); float localInertia3 = (1.0/12.0) * mass * (width*width + height*height); return Vector3<float>(localInertia1, localInertia2, localInertia3); }
void ShapeToAABBoxTest::boxConversion() { CollisionBoxShape collisionBox(Vector3<float>(1.0, 2.0, 1.0)); //box 1x2x1 PhysicsTransform transform(urchin::Point3<float>(0.0, 0.0, 0.0), //move 0 unit on X, Y and Z axis urchin::Quaternion<float>(urchin::Vector3<float>(0.0, 0.0, 1.0), 3.14159265358979/4)); //rotate 45° on Z axis AABBox<float> box = collisionBox.toAABBox(transform); AssertHelper::assertFloatEquals(box.getHalfSize(0), 2.12132034356); AssertHelper::assertFloatEquals(box.getHalfSize(1), 2.12132034356); AssertHelper::assertFloatEquals(box.getHalfSize(2), 1.0); AssertHelper::assertPoint3FloatEquals(box.getMin(), Point3<float>(-2.12132034356, -2.12132034356, -1.0)); AssertHelper::assertPoint3FloatEquals(box.getMax(), Point3<float>(2.12132034356, 2.12132034356, 1.0)); }
/** * Split the bounding box in several bounding boxes at limitSize. * If original box doesn't exceed limit size, the original box is returned. */ std::vector<AABBox<float>> SplitBoundingBox::split(const AABBox<float> &aabbox) const { std::vector<float> axisSplits[3]; for(unsigned int axis=0; axis<3; ++axis) { float size = aabbox.getHalfSize(axis) * 2.0f; axisSplits[axis].push_back(aabbox.getMin()[axis]); auto nbSplits = static_cast<int>(std::ceil(size/limitSize)); float maxValue = aabbox.getMax()[axis]; for(int split = 0; split < nbSplits; ++split) { float splitValue = std::min(aabbox.getMin()[axis] + limitSize*(split+1), maxValue); axisSplits[axis].push_back(splitValue); } } std::vector<AABBox<float>> splittedBoundingBox; for(unsigned int x=1; x<axisSplits[0].size(); ++x) { for(unsigned int y=1; y<axisSplits[1].size(); ++y) { for(unsigned int z=1; z<axisSplits[2].size(); ++z) { Point3<float> minPoint(axisSplits[0][x-1], axisSplits[1][y-1], axisSplits[2][z-1]); Point3<float> maxPoint(axisSplits[0][x], axisSplits[1][y], axisSplits[2][z]); splittedBoundingBox.emplace_back(AABBox<float>(minPoint, maxPoint)); } } } return splittedBoundingBox; }
void ShapeToAABBoxTest::convexHullConversion() { Point3<float> boxPointsTab[] = { Point3<float>(-1.0, -2.0, 1.0), Point3<float>(1.0, -2.0, 1.0), Point3<float>(1.0, 2.0, 1.0), Point3<float>(-1.0, 2.0, 1.0), Point3<float>(-1.0, -2.0, -1.0), Point3<float>(1.0, -2.0, -1.0), Point3<float>(1.0, 2.0, -1.0), Point3<float>(-1.0, 2.0, -1.0), }; std::vector<Point3<float>> boxPoints(boxPointsTab, boxPointsTab+sizeof(boxPointsTab)/sizeof(Point3<float>)); CollisionConvexHullShape collisionConvexHull(0.0, boxPoints); PhysicsTransform transform(urchin::Point3<float>(0.0, 0.0, 0.0), //move 0 unit on X, Y and Z axis urchin::Quaternion<float>(urchin::Vector3<float>(0.0, 0.0, 1.0), -3.14159265358979/4)); //rotate 45° on Z axis AABBox<float> box = collisionConvexHull.toAABBox(transform); AssertHelper::assertFloatEquals(box.getHalfSize(0), 2.12132034356); AssertHelper::assertFloatEquals(box.getHalfSize(1), 2.12132034356); AssertHelper::assertFloatEquals(box.getHalfSize(2), 1.0); AssertHelper::assertPoint3FloatEquals(box.getMin(), Point3<float>(-2.12132034356, -2.12132034356, -1.0)); AssertHelper::assertPoint3FloatEquals(box.getMax(), Point3<float>(2.12132034356, 2.12132034356, 1.0)); }