#include "Library/Clipping/ClippingActorInfo.h" #include "Library/Clipping/ClippingJudge.h" #include "Library/Clipping/ClippingRequestKeeper.h" #include "Library/Clipping/ViewIdHolder.h" #include "Library/LiveActor/ActorClippingFunction.h" #include "Library/LiveActor/ActorFlagFunction.h" #include "Library/LiveActor/ActorPoseUtil.h" #include "Library/LiveActor/LiveActor.h" #include "Library/Placement/PlacementFunction.h" #include "Library/Placement/PlacementId.h" namespace al { enum class ClippingRequestType; ClippingActorInfo::ClippingActorInfo(LiveActor* actor) : mLiveActor(actor), mPlacementId(new PlacementId()) { setTypeToSphere(300.0f, nullptr); } void ClippingActorInfo::setTypeToSphere(f32 radius, const sead::Vector3f* pos) { mClippingRadius = radius; if (!pos) pos = getTransPtr(mLiveActor); mTransPtr = pos; _20.setUndef(); } void ClippingActorInfo::startClipped() { if (!isDead(mLiveActor) && !isClipped(mLiveActor)) mLiveActor->startClipped(); } void ClippingActorInfo::endClipped() { if (!isDead(mLiveActor) && isClipped(mLiveActor)) mLiveActor->endClipped(); } void ClippingActorInfo::updateClipping(const ClippingJudge* clippingJudge) { bool isClipping = judgeClipping(clippingJudge); bool isClip = isClipped(mLiveActor); if (isClipping) { if (isClip) return; startClipped(); } else { if (!isClip) return; endClipped(); } } bool ClippingActorInfo::judgeClipping(const ClippingJudge* clippingJudge) const { if (!_20.isUndef()) return clippingJudge->isJudgedToClipFrustumObb(_18, _20, _38, _4a); return clippingJudge->isJudgedToClipFrustum(*mTransPtr, mClippingRadius, _38, _4a); } void ClippingActorInfo::updateClipping(ClippingRequestKeeper* clippingRequestKeeper, const ClippingJudge* clippingJudge) { bool isClipping = judgeClipping(clippingJudge); bool isClip = isClipped(mLiveActor); if (isClipping) { if (isClip) return; clippingRequestKeeper->request(mLiveActor, ClippingRequestType::IsClipped); } else { if (!isClip) return; clippingRequestKeeper->request(mLiveActor, ClippingRequestType::IsNotClipped); } } bool ClippingActorInfo::isGroupClipping() const { return mIsEnableGroupClipping && isGroupClippingInit(); } bool ClippingActorInfo::isGroupClippingInit() const { return mPlacementId->isValid(); } void ClippingActorInfo::setTypeToObb(const sead::BoundBox3f& boundBox, const sead::Matrix34f* matrix) { if (!matrix) matrix = mLiveActor->getBaseMtx(); _18 = matrix; _20 = boundBox; } void ClippingActorInfo::setGroupClippingId(const ActorInitInfo& clippingId) { alPlacementFunction::getClippingGroupId(mPlacementId, clippingId); } void ClippingActorInfo::setFarClipLevel20M() { _48 = 1; updateFarClipLevel(); } void ClippingActorInfo::updateFarClipLevel() { _4a = _48; if (_48 != 0 && checkActiveViewGroupAny()) _4a = 0; } void ClippingActorInfo::setFarClipLevelMax() { _48 = 0; _4a = 0; } bool ClippingActorInfo::isFarClipLevelMax() const { return _48 == 0; } bool ClippingActorInfo::checkActiveViewGroupAny() const { if (!mFarClipFlags) return false; for (s32 i = 0; i < mFarClipFlagSize; i++) { const bool* farClipFlag = mFarClipFlags[i]; if (farClipFlag && *farClipFlag) return true; } return false; } void ClippingActorInfo::initViewGroup(const ViewIdHolder* viewIdHolder) { if (!viewIdHolder) return; mViewIdHolder = viewIdHolder; mFarClipFlagEntries = viewIdHolder->getNumPlacements(); mFarClipFlags = new const bool*[mFarClipFlagEntries]; for (s32 i = 0; i < mFarClipFlagEntries; i++) mFarClipFlags[i] = nullptr; } void ClippingActorInfo::registerViewGroupFarClipFlag(const bool* flag) { mFarClipFlags[mFarClipFlagSize] = flag; mFarClipFlagSize++; } } // namespace al