From 0c3df3ed97101d91df6bfa7522e268f35885e58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 14 Mar 2022 01:41:28 +0100 Subject: ksys/phys: Add ShapeCast --- .../Physics/System/physShapeCastWithInfo.cpp | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/KingSystem/Physics/System/physShapeCastWithInfo.cpp (limited to 'src/KingSystem/Physics/System/physShapeCastWithInfo.cpp') diff --git a/src/KingSystem/Physics/System/physShapeCastWithInfo.cpp b/src/KingSystem/Physics/System/physShapeCastWithInfo.cpp new file mode 100644 index 00000000..cf0a8ac0 --- /dev/null +++ b/src/KingSystem/Physics/System/physShapeCastWithInfo.cpp @@ -0,0 +1,94 @@ +#include "KingSystem/Physics/System/physShapeCastWithInfo.h" +#include +#include +#include +#include +#include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereRigidBody.h" +#include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereShape.h" +#include "KingSystem/Physics/RigidBody/physRigidBody.h" +#include "KingSystem/Physics/System/physQueryContactPointInfo.h" +#include "KingSystem/Physics/System/physSystem.h" +#include "KingSystem/Physics/physConversions.h" + +namespace ksys::phys { + +ShapeCastWithInfo::ShapeCastWithInfo(RigidBody* body, int num_contact_points, Mode mode, + const sead::SafeString& name, LowPriority low_priority) + : ShapeCast(body, nullptr, mode) { + mStatus = Status::_1; + auto* heap = System::instance()->getPhysicsTempHeap(low_priority); + mContactPointInfo = QueryContactPointInfo::make(heap, num_contact_points, name, 0, 0); +} + +ShapeCastWithInfo::ShapeCastWithInfo(RigidBody* body, QueryContactPointInfo* contact_point_info, + Mode mode) + : ShapeCast(body, contact_point_info, mode) {} + +ShapeCastWithInfo::~ShapeCastWithInfo() { + if (mStatus == Status::_1 || mStatus == Status::_3) + QueryContactPointInfo::free(mContactPointInfo); +} + +// NON_MATCHING: mMode test + regalloc +bool ShapeCastWithInfo::executeQuery(WeldClosestPoints weld_closest_points) { + if (mMode == Mode::_1 || mMode == Mode::_0) { + FilteredClosestCdPointCollector cast_collector{mBody, mContactPointInfo}; + hkpAllCdPointCollector start_collector; + return doExecuteQuery(cast_collector, &start_collector, weld_closest_points, + OnlyLockIfNeeded::Yes); + } else { + hkpAllCdPointCollector cast_collector; + hkpAllCdPointCollector start_collector; + return doExecuteQuery(cast_collector, &start_collector, weld_closest_points, + OnlyLockIfNeeded::Yes); + } +} + +void ShapeCastWithInfo::doCast(const hkpLinearCastInput& input, hkpCdPointCollector& cast_collector, + hkpCdPointCollector* start_collector) { + hkTransformf transform; + const auto translate = mFrom; + transform.set(toHkQuat(mRotation), toHkVec4(translate)); + + hkpRigidBody* hk_body = mBody->getHkBody(); + hkpCollidable collidable{hk_body->getCollidable()->getShape(), + hk_body->getMotion()->getMotionState()}; + collidable.setTransform(&transform); + collidable.setCollisionFilterInfo(hk_body->getCollisionFilterInfo()); + + auto* world = System::instance()->getHavokWorld(mBody->getLayerType()); + world->linearCast(&collidable, input, cast_collector, start_collector); +} + +SphereCast::SphereCast(ContactLayer layer, GroundHit ground_hit, SystemGroupHandler* group_handler, + int num_contact_points, ShapeCast::Mode mode, const sead::Vector3f& from, + float sphere_radius, const sead::SafeString& name, LowPriority low_priority) + : ShapeCastWithInfo(nullptr, num_contact_points, mode, name, low_priority) { + auto* heap = System::instance()->getPhysicsTempHeap(low_priority); + + SphereParam sphere_param; + sphere_param.name = sead::SafeString::cEmptyString.cstr(); + sphere_param.radius = sphere_radius; + sphere_param.translate = from; + sphere_param.contact_layer = layer; + sphere_param.groundhit = ground_hit; + sphere_param.motion_type = MotionType::Fixed; + sphere_param.system_group_handler = group_handler; + sphere_param._90 = true; + + mSphere = SphereRigidBody::make(&sphere_param, heap); + mBody = mSphere; + mStatus = Status::_3; +} + +SphereCast::~SphereCast() { + if (mStatus == Status::_2 || mStatus == Status::_3) + delete mSphere; +} + +void SphereCast::setRadius(float radius) { + mSphere->setRadius(radius); + mSphere->x_40(); +} + +} // namespace ksys::phys -- cgit v1.2.3