ksys/phys: Start adding RayCast

This commit is contained in:
Léo Lam
2022-03-17 13:29:27 +01:00
parent 8d88461c52
commit bd1c2b6ed6
6 changed files with 312 additions and 48 deletions
+21 -10
View File
@@ -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;
+1 -12
View File
@@ -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;
+2
View File
@@ -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
@@ -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
+120
View File
@@ -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