bool TestCollision(const BoundingVolume* pBV, const Transformation& objT) const{ if (!mBV) return false; auto newCenter = objT.ApplyInverse(pBV->GetCenter()); Real newRad = pBV->GetRadius(); BoundingVolumePtr localBV = BoundingVolume::Create(); localBV->SetCenter(newCenter); localBV->SetRadius(newRad); return mBV->TestIntersection(localBV.get()); }
Vec3 GetRandomPosInVolume(const Vec3* nearWorld, const Transformation& objT) const{ if (!mBV) { return Vec3(0, 0, 0); } if (nearWorld) { Vec3 nearLocal = objT.ApplyInverse(*nearWorld); return mBV->GetRandomPosInVolume(&nearLocal); } return mBV->GetRandomPosInVolume(); }
IResult Intersects(const Ray3& ray, const Transformation& objT) const{ if (!mBV) return IResult(false, FLT_MAX); Ray3 localRay = objT.ApplyInverse(ray); Ray3::IResult ret = localRay.Intersects(mBV.get()); return ret; }
void SpatialObject::MergeBoundingVolume(const BoundingVolumePtr src){ mBoundingVolume->Merge(src.get()); *mBoundingVolumeWorld = *mBoundingVolume; mBoundingVolumeWorld->SetCenter(mBoundingVolume->GetCenter() + mLocation.GetTranslation()); auto scale = mLocation.GetScale(); mBoundingVolumeWorld->SetRadius(mBoundingVolume->GetRadius() * std::max(scale.x, std::max(scale.y, scale.z))); }
void BVaabb::TransformBy(const Transformation& transform, BoundingVolumePtr result) { assert(result); BVaabb* pNewBound = (BVaabb*)result.get(); AABB newAABB = mAABB; newAABB.Translate(transform.GetTranslation()); pNewBound->SetAABB(newAABB); }
//---------------------------------------------------------------------------- void BVSphere::TransformBy(const Transformation& transform, BoundingVolumePtr result) { assert(result); BVSphere* pNewSphere = (BVSphere*)result.get(); Vec3 newCenter = transform.ApplyForward(mCenter); Real newRadius = transform.GetNorm() * mRadius; pNewSphere->SetCenter(newCenter); pNewSphere->SetRadius(newRadius); }
//--------------------------------------------------------------------------- Impl(ColisionShapeType::Enum e, const Transformation& t, MeshObjectPtr colMesh) : mColShape(e) , mColMesh(colMesh) , mTransformation(t) { switch (e) { case ColisionShapeType::SPHERE: { mBV = BoundingVolume::Create(BoundingVolume::BV_SPHERE); auto scale = t.GetScale(); if (scale.x != scale.z || scale.x != scale.y) { Logger::Log(FB_ERROR_LOG_ARG, "Collision Sphere should be uniform scaled!"); assert(0); } mBV->SetRadius(1 * t.GetScale().x); mBV->SetCenter(Vec3::ZERO); } break; case ColisionShapeType::CUBE: { mBV = BoundingVolume::Create(BoundingVolume::BV_AABB); AABB aabb; aabb.SetMax(Vec3(1, 1, 1) * t.GetScale()); aabb.SetMin(Vec3(-1, -1, -1) * t.GetScale()); BVaabb* bvaabb = (BVaabb*)mBV.get(); bvaabb->SetAABB(aabb); } break; default: break; } }