summaryrefslogtreecommitdiff
path: root/src/KingSystem
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2022-03-17 13:29:27 +0100
committerLéo Lam <leo@leolam.fr>2022-03-18 01:19:59 +0100
commitbd1c2b6ed69bde46dabf27ea239b68c00c117e26 (patch)
tree58c9714275b9c79c533e7814fe338fabd1ae0248 /src/KingSystem
parent8d88461c52f6e118a0997edc1b8230724021558a (diff)
ksys/phys: Start adding RayCast
Diffstat (limited to 'src/KingSystem')
-rw-r--r--src/KingSystem/Map/mapAutoPlacement.cpp31
-rw-r--r--src/KingSystem/Map/mapAutoPlacement.h13
-rw-r--r--src/KingSystem/Physics/CMakeLists.txt2
-rw-r--r--src/KingSystem/Physics/System/physRayCast.cpp142
-rw-r--r--src/KingSystem/Physics/System/physRayCast.h120
5 files changed, 286 insertions, 22 deletions
diff --git a/src/KingSystem/Map/mapAutoPlacement.cpp b/src/KingSystem/Map/mapAutoPlacement.cpp
index 886a65da..a49e6153 100644
--- a/src/KingSystem/Map/mapAutoPlacement.cpp
+++ b/src/KingSystem/Map/mapAutoPlacement.cpp
@@ -7,11 +7,23 @@
#include "KingSystem/Map/mapAutoPlacementFlowMgr.h"
#include "KingSystem/Map/mapAutoPlacementMgr.h"
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
+#include "KingSystem/Physics/System/physRayCast.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/World/worldWeatherMgr.h"
namespace ksys::map {
+// TODO: this phys::RayCast derived class should be moved to phys::
+struct Raycast : phys::RayCast {
+ Raycast();
+ ~Raycast() override;
+
+ static Raycast* create(void*, u32);
+
+ void sub_7100FC55AC(u32);
+ void release();
+};
+
AutoPlacement::AutoPlacement() = default;
AutoPlacement::~AutoPlacement() = default;
@@ -128,23 +140,22 @@ bool PlacementThing::invoke() {
if (mRaycast == nullptr || mState != State::Initialized)
return false;
- mRaycast->addContactLayer(phys::ContactLayer::EntityGround);
- mRaycast->addContactLayer(phys::ContactLayer::EntityGroundRough);
- mRaycast->addContactLayer(phys::ContactLayer::EntityGroundSmooth);
- mRaycast->addContactLayer(phys::ContactLayer::EntityAirWall);
- mRaycast->addContactLayer(phys::ContactLayer::EntityGroundObject);
- mRaycast->addContactLayer(phys::ContactLayer::EntityTree);
+ mRaycast->enableLayer(phys::ContactLayer::EntityGround);
+ mRaycast->enableLayer(phys::ContactLayer::EntityGroundRough);
+ mRaycast->enableLayer(phys::ContactLayer::EntityGroundSmooth);
+ mRaycast->enableLayer(phys::ContactLayer::EntityAirWall);
+ mRaycast->enableLayer(phys::ContactLayer::EntityGroundObject);
+ mRaycast->enableLayer(phys::ContactLayer::EntityTree);
if (_8944) {
sead::Vector3f v1 = mVec1 + sead::Vector3f{0, 4, 30};
sead::Vector3f v2 = mVec1 - sead::Vector3f{0, 4, 30};
- mRaycast->sub_7100FC38A0(v1, v2);
+ mRaycast->setStartAndEnd(v1, v2);
} else {
sead::Vector3f v1{mVec1.x, 2000.0f, mVec1.z};
sead::Vector3f v2{mVec1.x, -100.0f, mVec1.z};
- mRaycast->sub_7100FC38A0(v1, v2);
- // void** p = &mRaycast->mGroups[0]._68;
- // *p = &mDelegate;
+ mRaycast->setStartAndEnd(v1, v2);
+ mRaycast->setCallback(&mDelegate);
}
mState = State::LayersDone;
diff --git a/src/KingSystem/Map/mapAutoPlacement.h b/src/KingSystem/Map/mapAutoPlacement.h
index ecdb3a36..0ec68ba8 100644
--- a/src/KingSystem/Map/mapAutoPlacement.h
+++ b/src/KingSystem/Map/mapAutoPlacement.h
@@ -20,18 +20,7 @@ class AutoPlacement;
struct AutoPlacementFlowRes;
class PlacementThing;
-// TODO: move this
-struct Raycast {
- Raycast();
- virtual ~Raycast();
-
- static Raycast* create(void*, u32);
-
- void addContactLayer(phys::ContactLayer layer);
- void sub_7100FC55AC(u32);
- void release();
- void sub_7100FC38A0(const sead::Vector3f&, const sead::Vector3f&);
-};
+struct Raycast;
struct PlacementGroup {
sead::SafeString a;
diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt
index 6593112a..bef1e5db 100644
--- a/src/KingSystem/Physics/CMakeLists.txt
+++ b/src/KingSystem/Physics/CMakeLists.txt
@@ -139,6 +139,8 @@ target_sources(uking PRIVATE
System/physParamSet.h
System/physQueryContactPointInfo.cpp
System/physQueryContactPointInfo.h
+ System/physRayCast.cpp
+ System/physRayCast.h
System/physSensorContactListener.cpp
System/physSensorContactListener.h
System/physSensorGroupFilter.cpp
diff --git a/src/KingSystem/Physics/System/physRayCast.cpp b/src/KingSystem/Physics/System/physRayCast.cpp
new file mode 100644
index 00000000..ea25cea3
--- /dev/null
+++ b/src/KingSystem/Physics/System/physRayCast.cpp
@@ -0,0 +1,142 @@
+#include "KingSystem/Physics/System/physRayCast.h"
+#include "KingSystem/Physics/physLayerMaskBuilder.h"
+
+namespace ksys::phys {
+
+RayCast::RayCast(SystemGroupHandler* group_handler, GroundHit ground_hit)
+ : mGroupHandler(group_handler), mGroundHit(ground_hit) {
+ reset();
+}
+
+RayCast::~RayCast() = default;
+
+// NON_MATCHING: reorderings
+void RayCast::reset() {
+ mTo = sead::Vector3f::zero;
+ mFrom = sead::Vector3f::zero;
+ mLayerMasks = {};
+ mExtraGroupHandlers.clear();
+
+ resetCastResult();
+}
+
+void RayCast::resetCastResult() {
+ static_cast<void>(_98.load());
+
+ _30 = {};
+ _34 = sead::Vector3f::zero;
+ mHitFraction = -1.0;
+ _48 = {};
+ _50 = {};
+ _54 = {};
+ _58 = {};
+ _60 = {};
+ _70 = {};
+}
+
+static bool isLayerValid(ContactLayer layer, ContactLayerType type) {
+ if (type == ContactLayerType::Entity) {
+ if (layer > ContactLayer::EntityHitOnlyGround)
+ return false;
+ } else {
+ if (layer > ContactLayer::SensorNoHit)
+ return false;
+ }
+
+ return true;
+}
+
+void RayCast::enableLayer(ContactLayer layer) {
+ auto type = getContactLayerType(layer);
+ if (!isLayerValid(layer, type))
+ return;
+
+ const auto mask = makeContactLayerMask(layer);
+ getLayerMask(type).set(mask);
+}
+
+void RayCast::disableLayer(ContactLayer layer) {
+ auto type = getContactLayerType(layer);
+ if (!isLayerValid(layer, type))
+ return;
+
+ getLayerMask(type).resetBit(getContactLayerBaseRelativeValue(layer));
+}
+
+void RayCast::setLayers(const LayerMaskBuilder& builder) {
+ for (int i = 0; i < NumContactLayerTypes; ++i)
+ mLayerMasks[i] = builder.getMasks()[i].layers;
+}
+
+bool RayCast::isLayerEnabled(ContactLayer layer) const {
+ auto type = getContactLayerType(layer);
+ if (!isLayerValid(layer, type))
+ return false;
+
+ return getLayerMask(type).isOnBit(getContactLayerBaseRelativeValue(layer));
+}
+
+void RayCast::setGroundHit(GroundHit ground_hit) {
+ mGroundHit = ground_hit;
+}
+
+GroundHit RayCast::getGroundHit() const {
+ return mGroundHit;
+}
+
+void RayCast::setD8(int value) {
+ _d8 = value;
+}
+
+void RayCast::set9A(bool value) {
+ _9a = value;
+}
+
+void RayCast::setStart(const sead::Vector3f& start) {
+ mFrom = start;
+}
+
+void RayCast::setEnd(const sead::Vector3f& end) {
+ mTo = end;
+}
+
+void RayCast::setStartAndEnd(const sead::Vector3f& start, const sead::Vector3f& end) {
+ setStart(start);
+ setEnd(end);
+}
+
+void RayCast::setStartAndDisplacement(const sead::Vector3f& start,
+ const sead::Vector3f& displacement) {
+ setStart(start);
+ setEnd(start + displacement);
+}
+
+void RayCast::setStartAndDisplacementScaled(const sead::Vector3f& start,
+ const sead::Vector3f& displacement,
+ float displacement_scale) {
+ setStart(start);
+ setEnd(start + displacement * displacement_scale);
+}
+
+bool RayCast::addGroupHandler(SystemGroupHandler* group_handler) {
+ if (mExtraGroupHandlers.size() == mExtraGroupHandlers.capacity() || group_handler == nullptr)
+ return false;
+
+ mExtraGroupHandlers.pushBack(group_handler);
+ return true;
+}
+
+void RayCast::setRigidBody(RigidBody* body) {
+ if (_70 != 1)
+ mRigidBody = body;
+}
+
+void RayCast::getHitPosition(sead::Vector3f* out) const {
+ *out = ((1 - mHitFraction) * mFrom) + (mHitFraction * mTo);
+}
+
+void RayCast::get34(sead::Vector3f* out) const {
+ *out = _34;
+}
+
+} // namespace ksys::phys
diff --git a/src/KingSystem/Physics/System/physRayCast.h b/src/KingSystem/Physics/System/physRayCast.h
new file mode 100644
index 00000000..d2b915e8
--- /dev/null
+++ b/src/KingSystem/Physics/System/physRayCast.h
@@ -0,0 +1,120 @@
+#pragma once
+
+#include <container/seadPtrArray.h>
+#include <math/seadVector.h>
+#include <prim/seadBitFlag.h>
+#include <prim/seadDelegate.h>
+#include <prim/seadRuntimeTypeInfo.h>
+#include <thread/seadAtomic.h>
+#include "KingSystem/Physics/physDefines.h"
+#include "KingSystem/Physics/physMaterialMask.h"
+
+namespace ksys::phys {
+
+struct ActorInfo;
+class LayerMaskBuilder;
+class RigidBody;
+class SystemGroupHandler;
+
+class RayCast {
+ SEAD_RTTI_BASE(RayCast)
+public:
+ // TODO: what kind of callback is this?
+ using Callback = sead::IDelegate1<phys::RigidBody*>;
+
+ RayCast(SystemGroupHandler* group_handler, GroundHit ground_hit);
+ virtual ~RayCast();
+
+ virtual void m4(void*) {}
+
+ void reset();
+ void resetCastResult();
+
+ void enableLayer(ContactLayer layer);
+ void disableLayer(ContactLayer layer);
+ void setLayers(const LayerMaskBuilder& builder);
+ bool isLayerEnabled(ContactLayer layer) const;
+
+ void setGroundHit(GroundHit ground_hit);
+ GroundHit getGroundHit() const;
+
+ // TODO: rename
+ void setD8(int value);
+ void set9A(bool value);
+
+ void setStart(const sead::Vector3f& start);
+ void setEnd(const sead::Vector3f& end);
+ void setStartAndEnd(const sead::Vector3f& start, const sead::Vector3f& end);
+ void setStartAndDisplacement(const sead::Vector3f& start, const sead::Vector3f& displacement);
+ void setStartAndDisplacementScaled(const sead::Vector3f& start,
+ const sead::Vector3f& displacement,
+ float displacement_scale);
+
+ bool addGroupHandler(SystemGroupHandler* group_handler);
+ void setRigidBody(RigidBody* body);
+
+ void setCallback(Callback* callback) { mCallback = callback; }
+ Callback* getCallback() const { return mCallback; }
+
+ // 0x0000007100fc39b4
+ bool worldRayCast(ContactLayerType layer_type);
+ // 0x0000007100fc3da4
+ bool shapeRayCast(RigidBody* rigid_body);
+ // 0x0000007100fc4248
+ bool phantomRayCast(void* unk);
+
+ void getHitPosition(sead::Vector3f* out) const;
+ // TODO: rename
+ void get34(sead::Vector3f* out) const;
+ // TODO: rename
+ // 0x0000007100fc4844
+ void getUnkVectors(sead::Vector3f* unk1, sead::Vector3f* unk2, void* unk3) const;
+
+ // 0x0000007100fc4bd4
+ bool x_1(sead::Vector3f* out) const;
+
+private:
+ auto& getLayerMask(ContactLayerType type) { return mLayerMasks[int(type)]; }
+ auto& getLayerMask(ContactLayerType type) const { return mLayerMasks[int(type)]; }
+
+ // 0x0000007100fc3b1c
+ void worldRayCastImpl(void* arg, ContactLayerType layer_type);
+ // 0x0000007100fc3f0c
+ void shapeRayCastImpl(void* arg, RigidBody* rigid_body);
+ // 0x0000007100fc43b0
+ void phantomRayCastImpl(void* unk);
+
+ // 0x0000007100fc4630
+ const ActorInfo* getActorInfoMaybe(void* unk);
+
+ // 0x0000007100fc4764
+ bool x_2(sead::Vector3f* out, void* unk1, int unk2) const;
+
+ sead::Vector3f mFrom = sead::Vector3f::zero;
+ sead::Vector3f mTo = sead::Vector3f::zero;
+ SystemGroupHandler* mGroupHandler{};
+ GroundHit mGroundHit{};
+ u32 _2c;
+ bool _30;
+ sead::Vector3f _34;
+ float mHitFraction;
+ void* _48;
+ u32 _50;
+ bool _54;
+ void* _58{};
+ void* _60;
+ sead::SafeArray<sead::BitFlag32, NumContactLayerTypes> mLayerMasks{};
+ sead::Atomic<u32> _70;
+ sead::Atomic<u32> _74;
+ MaterialMask mMaterialMask;
+ RigidBody* mRigidBody{};
+ sead::Atomic<bool> _98;
+ bool _99{};
+ bool _9a{};
+ sead::FixedPtrArray<SystemGroupHandler, 4> mExtraGroupHandlers;
+ // TODO: rename once we figure out what kind of callback this is
+ Callback* mCallback{};
+ u32 _d8 = 0x10;
+};
+
+} // namespace ksys::phys