#include "Library/Collision/PartsConnectorUtil.h" #include "Library/Collision/CollisionParts.h" #include "Library/Collision/CollisionPartsKeeperUtil.h" #include "Library/Collision/CollisionPartsTriangle.h" #include "Library/Collision/KCollisionServer.h" #include "Library/Collision/PartsConnector.h" #include "Library/Collision/PartsMtxConnector.h" #include "Library/Collision/PartsSensorConnector.h" #include "Library/LiveActor/ActorModelFunction.h" #include "Library/LiveActor/ActorPoseUtil.h" #include "Library/LiveActor/LiveActor.h" #include "Library/Math/MathUtil.h" #include "Library/Matrix/MatrixUtil.h" #include "Library/Placement/PlacementFunction.h" #include "Library/Screen/ScreenPointTarget.h" #include "Project/HitSensor/HitSensor.h" namespace al { inline bool IsConnectToCollision(const ActorInitInfo& initInfo) { bool isConnectToCollision = false; if (!tryGetArg(&isConnectToCollision, initInfo, "IsConnectToCollision")) return false; return isConnectToCollision; } MtxConnector* createMtxConnector(const LiveActor* actor) { return new MtxConnector(getQuat(actor), getTrans(actor)); } MtxConnector* createMtxConnector(const LiveActor* actor, const sead::Quatf& quat) { return new MtxConnector(quat, getTrans(actor)); } MtxConnector* tryCreateMtxConnector(const LiveActor* actor, const ActorInitInfo& initInfo) { return IsConnectToCollision(initInfo) ? createMtxConnector(actor) : nullptr; } MtxConnector* tryCreateMtxConnector(const LiveActor* actor, const ActorInitInfo& initInfo, const sead::Quatf& quat) { return IsConnectToCollision(initInfo) ? createMtxConnector(actor, quat) : nullptr; } CollisionPartsConnector* createCollisionPartsConnector(const LiveActor* actor, const sead::Quatf& quat) { CollisionPartsConnector* connector = new CollisionPartsConnector(); connector->setBaseQuatTrans(quat, getTrans(actor)); return connector; } CollisionPartsConnector* tryCreateCollisionPartsConnector(const LiveActor* actor, const ActorInitInfo& initInfo) { return tryCreateCollisionPartsConnector(actor, initInfo, getQuat(actor)); } CollisionPartsConnector* tryCreateCollisionPartsConnector(const LiveActor* actor, const ActorInitInfo& initInfo, const sead::Quatf& quat) { return IsConnectToCollision(initInfo) ? createCollisionPartsConnector(actor, quat) : nullptr; } bool isMtxConnectorConnecting(const MtxConnector* connector) { return connector->isConnecting(); } void disconnectMtxConnector(MtxConnector* connector) { return connector->clear(); } CollisionParts* attachMtxConnectorToCollision(MtxConnector* connector, const LiveActor* actor, const sead::Vector3f& pos, const sead::Vector3f& dir) { CollisionPartsFilterActor partsFilter = CollisionPartsFilterActor(actor); CollisionParts* parts = alCollisionUtil::getStrikeArrowCollisionParts(actor, nullptr, pos, dir, &partsFilter, nullptr); if (!parts) return nullptr; attachMtxConnectorToCollisionParts(connector, parts); return parts; } CollisionParts* attachMtxConnectorToCollision(MtxConnector* connector, const LiveActor* actor, bool isAttachToGround) { return attachMtxConnectorToCollision(connector, actor, 50.0f, isAttachToGround ? -150.0f : 150.0f); } CollisionParts* attachMtxConnectorToCollision(MtxConnector* connector, const LiveActor* actor, f32 checkOffUp, f32 checkDistance) { sead::Vector3f upDir; calcUpDir(&upDir, actor); sead::Vector3f dir = upDir * -checkDistance; sead::Vector3f pos = getTrans(actor) + upDir * checkOffUp; return attachMtxConnectorToCollision(connector, actor, pos, dir); } void attachMtxConnectorToCollisionParts(MtxConnector* connector, const CollisionParts* parts) { connector->init(&parts->getBaseMtx(), parts->getBaseInvMtx()); } void setConnectorBaseQuatTrans(const sead::Quatf& quat, const sead::Vector3f& trans, MtxConnector* connector) { connector->setBaseQuatTrans(quat, trans); } void setConnectorBaseQuatTrans(LiveActor* actor, MtxConnector* connector) { connector->setBaseQuatTrans(getQuat(actor), getTrans(actor)); } void connectPoseQT(LiveActor* actor, const MtxConnector* connector) { calcConnectQT(getQuatPtr(actor), getTransPtr(actor), connector); } void connectPoseQT(LiveActor* actor, const MtxConnector* connector, const sead::Quatf& quat, const sead::Vector3f& trans) { calcConnectQT(getQuatPtr(actor), getTransPtr(actor), connector, quat, trans); } void connectPoseTrans(LiveActor* actor, const MtxConnector* connector, const sead::Vector3f& trans) { calcConnectTrans(getTransPtr(actor), connector, trans); } void connectPoseMtx(LiveActor* actor, const MtxConnector* connector, const sead::Matrix34f& mtx) { sead::Matrix34f poseMtx; calcConnectMtx(&poseMtx, connector, mtx); normalize(&poseMtx); updatePoseMtx(actor, &poseMtx); } void calcConnectTrans(sead::Vector3f* outTrans, const MtxConnector* connector, const sead::Vector3f& trans) { connector->multTrans(outTrans, trans); } void calcConnectTrans(sead::Vector3f* outTrans, const MtxConnector* connector) { calcConnectTrans(outTrans, connector, connector->getBaseTrans()); } void calcConnectDir(sead::Vector3f* outDir, const MtxConnector* connector, const sead::Vector3f& dir) { connector->multVec(outDir, dir); normalize(outDir); } void calcConnectQT(sead::Quatf* outQuat, sead::Vector3f* outTrans, const MtxConnector* connector, const sead::Quatf& poseQuat, const sead::Vector3f& poseTrans) { connector->multQT(outQuat, outTrans, poseQuat, poseTrans); } void calcConnectQT(sead::Quatf* outQuat, sead::Vector3f* outTrans, const MtxConnector* connector) { connector->multQT(outQuat, outTrans, nullptr); } void calcConnectMtx(sead::Matrix34f* outMtx, const MtxConnector* connector, const sead::Matrix34f& mtx) { connector->multMtx(outMtx, mtx); } void calcConnectMtx(sead::Matrix34f* outMtx, const MtxConnector* connector, const sead::Quatf& quat, const sead::Vector3f& trans) { sead::Matrix34f mtx; mtx.makeQT(quat, trans); calcConnectMtx(outMtx, connector, mtx); } void attachMtxConnectorToCollisionRT(MtxConnector* connector, const LiveActor* actor, bool isFacingUp, bool useStrikeArrowPos) { sead::Vector3f facingDir; calcUpDir(&facingDir, actor); if (!isFacingUp) facingDir = -facingDir; sead::Vector3f dir = facingDir * 150.0f; sead::Vector3f pos = getTrans(actor) - facingDir * 50.0f; CollisionPartsFilterActor partsFilter = CollisionPartsFilterActor(actor); sead::Vector3f arrowPos; CollisionParts* parts = alCollisionUtil::getStrikeArrowCollisionParts( actor, &arrowPos, pos, dir, &partsFilter, nullptr); if (!parts) return; const sead::Vector3f& rotate = getRotate(actor); sead::Matrix34f mtx; mtx.makeRT({sead::Mathf::deg2rad(rotate.x), sead::Mathf::deg2rad(rotate.y), sead::Mathf::deg2rad(rotate.z)}, useStrikeArrowPos ? arrowPos : getTrans(actor)); connector->init(&parts->getBaseMtx(), parts->getBaseInvMtx() * mtx); } void attachMtxConnectorToCollisionQT(MtxConnector* connector, const LiveActor* actor, bool isFacingUp, bool useStrikeArrowPos) { sead::Vector3f facingDir; calcUpDir(&facingDir, actor); if (!isFacingUp) facingDir = -facingDir; sead::Vector3f dir = facingDir * 150.0f; sead::Vector3f pos = getTrans(actor) - facingDir * 50.0f; CollisionPartsFilterActor partsFilter = CollisionPartsFilterActor(actor); sead::Vector3f arrowPos; CollisionParts* parts = alCollisionUtil::getStrikeArrowCollisionParts( actor, &arrowPos, pos, dir, &partsFilter, nullptr); if (!parts) return; sead::Matrix34f mtx; mtx.makeQT(getQuat(actor), useStrikeArrowPos ? arrowPos : getTrans(actor)); connector->init(&parts->getBaseMtx(), parts->getBaseInvMtx() * mtx); } void attachMtxConnectorToJoint(MtxConnector* connector, const LiveActor* actor, const char* jointName) { attachMtxConnectorToMtxPtr(connector, getJointMtxPtr(actor, jointName)); } void attachMtxConnectorToJoint(MtxConnector* connector, const LiveActor* actor, const char* jointName, const sead::Vector3f& rotation, const sead::Vector3f& trans) { attachMtxConnectorToMtxPtr(connector, getJointMtxPtr(actor, jointName), rotation, trans); } void attachMtxConnectorToMtxPtr(MtxConnector* connector, const sead::Matrix34f* mtx, const sead::Vector3f& rotation, const sead::Vector3f& trans) { sead::Quatf quat; quat.setRPY(sead::Mathf::deg2rad(rotation.x), sead::Mathf::deg2rad(rotation.y), sead::Mathf::deg2rad(rotation.z)); connector->setBaseQuatTrans(quat, trans); attachMtxConnectorToMtxPtr(connector, mtx); } void attachMtxConnectorToActor(MtxConnector* connector, const LiveActor* actor) { attachMtxConnectorToMtxPtr(connector, actor->getBaseMtx()); } void attachMtxConnectorToActor(MtxConnector* connector, const LiveActor* actor, const sead::Vector3f& rotation, const sead::Vector3f& trans) { attachMtxConnectorToMtxPtr(connector, actor->getBaseMtx(), rotation, trans); } void attachMtxConnectorToMtxPtr(MtxConnector* connector, const sead::Matrix34f* mtx) { connector->init(mtx, sead::Matrix34f::ident); } void attachMtxConnectorToSensor(MtxConnector* connector, HitSensor* hitSensor, const sead::Matrix34f& mtx) { const sead::Matrix34f* followMtx = hitSensor->getFollowMtx(); if (followMtx) { sead::Matrix34f newMtx; newMtx.setInverse(*followMtx); newMtx = newMtx * mtx; connector->init(followMtx, newMtx); return; } if (hitSensor->getParentActor()->getBaseMtx()) { const sead::Matrix34f* baseMtx = hitSensor->getParentActor()->getBaseMtx(); if (baseMtx) { sead::Matrix34f newMtx; newMtx.setInverse(*baseMtx); newMtx = newMtx * mtx; connector->init(baseMtx, newMtx); } } } void attachSensorConnectorToSensor(SensorConnector* connector, HitSensor* hitSensor, const sead::Matrix34f& mtx) { const sead::Matrix34f* followMtx = hitSensor->getFollowMtx(); if (followMtx) { sead::Matrix34f newMtx; newMtx.setInverse(*followMtx); newMtx = newMtx * mtx; connector->init(followMtx, newMtx, hitSensor); return; } if (hitSensor->getParentActor()->getBaseMtx()) { const sead::Matrix34f* baseMtx = hitSensor->getParentActor()->getBaseMtx(); if (baseMtx) { sead::Matrix34f newMtx; newMtx.setInverse(*baseMtx); newMtx = newMtx * mtx; connector->init(baseMtx, newMtx, hitSensor); } } } void attachMtxConnectorToScreenPointTarget(MtxConnector* connector, ScreenPointTarget* screenPointTarget, const sead::Matrix34f& mtx) { const sead::Matrix34f* followMtx = screenPointTarget->getJointMtx(); if (followMtx) { sead::Matrix34f newMtx; newMtx.setInverse(*followMtx); newMtx = newMtx * mtx; connector->init(followMtx, newMtx); return; } if (screenPointTarget->getActor()->getBaseMtx()) { const sead::Matrix34f* baseMtx = screenPointTarget->getActor()->getBaseMtx(); if (baseMtx) { sead::Matrix34f newMtx; newMtx.setInverse(*baseMtx); newMtx = newMtx * mtx; connector->init(baseMtx, newMtx); } } } void attachCollisionPartsConnector(CollisionPartsConnector* partsConnector, const CollisionParts* parts) { partsConnector->init(&parts->getBaseMtx(), parts->getBaseInvMtx(), parts); } void attachCollisionPartsConnectorToGround(CollisionPartsConnector* partsConnector, const LiveActor* actor) { // Same as attachMtxConnectorToCollision(connector, actor, true) CollisionPartsFilterActor partsFilter = CollisionPartsFilterActor(actor); sead::Vector3f upDir{0.0f, 0.0f, 0.0f}; calcUpDir(&upDir, actor); CollisionParts* parts = alCollisionUtil::getStrikeArrowCollisionParts( actor, nullptr, getTrans(actor) + upDir * 50.0f, upDir * -150.0f, &partsFilter, nullptr); attachCollisionPartsConnector(partsConnector, parts); } void attachToHitTriangle(CollisionPartsConnector* partsConnector, const Triangle& triangle, const sead::Matrix34f& mtx) { const CollisionParts* collisionParts = triangle.getCollisionParts(); sead::Matrix34f partsMtx = collisionParts->getBaseInvMtx() * mtx; partsConnector->init(&collisionParts->getBaseMtx(), partsMtx, collisionParts); } void attachToHitInfo(CollisionPartsConnector* partsConnector, const HitInfo& hitInfo, const sead::Matrix34f& mtx) { attachToHitTriangle(partsConnector, hitInfo.triangle, mtx); } void attachToHitInfoNrmToMinusZ(CollisionPartsConnector* partsConnector, const HitInfo& hitInfo) { sead::Matrix34f mtx; makeMtxFrontNoSupportPos(&mtx, -hitInfo.triangle.getFaceNormal(), hitInfo.collisionHitPos); attachToHitInfo(partsConnector, hitInfo, mtx); } void calcConnectInfo(const MtxConnector* connector, sead::Vector3f* outTrans, sead::Quatf* outQuat, sead::Vector3f* outScale, const sead::Vector3f& vecA, const sead::Vector3f& vecB) { connector->calcConnectInfo(outTrans, outQuat, outScale, vecA, vecB); } void connectPoseQTUsingConnectInfo(LiveActor* actor, const MtxConnector* connector) { if (!connector->isConnecting()) return; sead::Vector3f trans; sead::Quatf quat; connector->calcConnectInfo(&trans, &quat, nullptr, sead::Vector3f::zero, sead::Vector3f::zero); setTrans(actor, trans); setQuat(actor, quat); } const sead::Quatf& getConnectBaseQuat(const MtxConnector* connector) { return connector->getBaseQuat(); } const sead::Vector3f& getConnectBaseTrans(const MtxConnector* connector) { return connector->getBaseTrans(); } } // namespace al