mirror of https://github.com/zeldaret/botw.git
ksys/phys: Add ShapeCast
This commit is contained in:
parent
2a9e3318b5
commit
0c3df3ed97
|
@ -48306,7 +48306,7 @@ Address,Quality,Size,Name
|
|||
0x000000710079482c,U,000400,
|
||||
0x00000071007949bc,U,001556,
|
||||
0x0000007100794fd0,U,000016,
|
||||
0x0000007100794fe0,U,000004,nullsub_2388
|
||||
0x0000007100794fe0,U,000004,_ZN4ksys4phys16LayerMaskBuilderD2Ev
|
||||
0x0000007100794fe4,U,000992,CameraPhysCollisionCheck
|
||||
0x00000071007953c4,U,000004,nullsub_2389
|
||||
0x00000071007953c8,U,000076,
|
||||
|
@ -48376,7 +48376,7 @@ Address,Quality,Size,Name
|
|||
0x0000007100799d10,U,000008,
|
||||
0x0000007100799d18,U,000008,
|
||||
0x0000007100799d20,U,000008,
|
||||
0x0000007100799d28,U,000004,j__ZdlPv_323
|
||||
0x0000007100799d28,U,000004,_ZN4ksys4phys16LayerMaskBuilderD0Ev
|
||||
0x0000007100799d2c,U,000052,
|
||||
0x0000007100799d60,U,000092,
|
||||
0x0000007100799dbc,O,000008,_ZNK4sead11IDelegate1RIPvbE9isNoDummyEv
|
||||
|
@ -84161,42 +84161,42 @@ Address,Quality,Size,Name
|
|||
0x0000007100fc86f8,O,000008,_ZN4ksys4phys17SensorGroupFilter37getCollisionFilterInfoGroupHandlerIdxEj
|
||||
0x0000007100fc8700,O,000008,_ZN4ksys4phys17SensorGroupFilter23makeCollisionFilterInfoENS0_12ContactLayerENS0_9GroundHitEjj
|
||||
0x0000007100fc8708,O,000036,_ZN4ksys4phys17SensorGroupFilter34setSensorLayerCollisionEnabledMaskENS0_12ContactLayerEj
|
||||
0x0000007100fc872c,U,000172,
|
||||
0x0000007100fc87d8,U,000004,nullsub_4250
|
||||
0x0000007100fc87dc,U,000004,j__ZdlPv_1011
|
||||
0x0000007100fc87e0,U,000028,
|
||||
0x0000007100fc87fc,U,000068,
|
||||
0x0000007100fc8840,U,000068,
|
||||
0x0000007100fc8884,U,000052,
|
||||
0x0000007100fc88b8,U,000064,
|
||||
0x0000007100fc88f8,U,000076,
|
||||
0x0000007100fc8944,U,000040,
|
||||
0x0000007100fc896c,U,000004,nullsub_4251
|
||||
0x0000007100fc8970,U,000588,
|
||||
0x0000007100fc8bbc,U,000560,
|
||||
0x0000007100fc8dec,U,000100,
|
||||
0x0000007100fc8e50,U,000004,nullsub_4252
|
||||
0x0000007100fc8e54,U,000080,
|
||||
0x0000007100fc8ea4,U,000040,
|
||||
0x0000007100fc8ecc,U,000476,
|
||||
0x0000007100fc90a8,U,000112,
|
||||
0x0000007100fc9118,U,000092,
|
||||
0x0000007100fc9174,U,000124,
|
||||
0x0000007100fc91f0,U,000052,
|
||||
0x0000007100fc9224,U,000072,
|
||||
0x0000007100fc926c,U,000080,
|
||||
0x0000007100fc92bc,U,000456,
|
||||
0x0000007100fc9484,U,000316,
|
||||
0x0000007100fc95c0,U,000536,
|
||||
0x0000007100fc97d8,U,000124,
|
||||
0x0000007100fc9854,U,000132,
|
||||
0x0000007100fc98d8,U,000040,
|
||||
0x0000007100fc9900,U,000204,
|
||||
0x0000007100fc99cc,U,000092,
|
||||
0x0000007100fc9a28,U,000288,
|
||||
0x0000007100fc9b48,U,000092,
|
||||
0x0000007100fc9ba4,U,000140,
|
||||
0x0000007100fc9c30,U,000140,
|
||||
0x0000007100fc872c,O,000172,_ZN4ksys4phys9ShapeCastC2EPNS0_9RigidBodyEPNS0_21QueryContactPointInfoENS1_4ModeE
|
||||
0x0000007100fc87d8,O,000004,_ZN4ksys4phys9ShapeCastD1Ev
|
||||
0x0000007100fc87dc,O,000004,_ZN4ksys4phys9ShapeCastD0Ev
|
||||
0x0000007100fc87e0,O,000028,_ZN4ksys4phys9ShapeCast5resetEv
|
||||
0x0000007100fc87fc,O,000068,_ZN4ksys4phys9ShapeCast11setRotationERKN4sead8Matrix33IfEE
|
||||
0x0000007100fc8840,O,000068,_ZN4ksys4phys9ShapeCast11setRotationERKN4sead8Matrix34IfEE
|
||||
0x0000007100fc8884,O,000052,_ZN4ksys4phys9ShapeCast14setStartAndEndERKN4sead7Vector3IfEES6_
|
||||
0x0000007100fc88b8,O,000064,_ZN4ksys4phys9ShapeCast23setStartAndDisplacementERKN4sead7Vector3IfEES6_
|
||||
0x0000007100fc88f8,O,000076,_ZN4ksys4phys9ShapeCast29setStartAndDisplacementScaledERKN4sead7Vector3IfEES6_f
|
||||
0x0000007100fc8944,O,000040,_ZN4ksys4phys9ShapeCast13setLayerMasksERKNS0_16LayerMaskBuilderE
|
||||
0x0000007100fc896c,O,000004,_ZN4ksys4phys9ShapeCast9setColorsERKN4sead7Color4fES5_S5_b
|
||||
0x0000007100fc8970,M,000588,_ZN4ksys4phys9ShapeCast14doExecuteQueryER19hkpCdPointCollectorP22hkpAllCdPointCollectorNS1_17WeldClosestPointsENS0_16OnlyLockIfNeededE
|
||||
0x0000007100fc8bbc,O,000560,_ZN4ksys4phys9ShapeCast20registerContactPointERK14hkpRootCdPointPNS0_9RigidBodyENS1_13ClampDistanceE
|
||||
0x0000007100fc8dec,O,000100,_ZN4ksys4phys31FilteredClosestCdPointCollectorC1EPNS0_9RigidBodyEPNS0_21QueryContactPointInfoE
|
||||
0x0000007100fc8e50,O,000004,_ZN4ksys4phys31FilteredClosestCdPointCollectorD1Ev
|
||||
0x0000007100fc8e54,m,000080,_ZN4ksys4phys31FilteredClosestCdPointCollectorD0Ev
|
||||
0x0000007100fc8ea4,O,000040,_ZN4ksys4phys31FilteredClosestCdPointCollector5resetEv
|
||||
0x0000007100fc8ecc,O,000476,_ZN4ksys4phys31FilteredClosestCdPointCollector10addCdPointERK10hkpCdPoint
|
||||
0x0000007100fc90a8,O,000112,_ZNK4ksys4phys9ShapeCast27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100fc9118,O,000092,_ZNK4ksys4phys9ShapeCast18getRuntimeTypeInfoEv
|
||||
0x0000007100fc9174,O,000124,_ZN4ksys4phys17ShapeCastWithInfoC1EPNS0_9RigidBodyEiNS0_9ShapeCast4ModeERKN4sead14SafeStringBaseIcEENS0_11LowPriorityE
|
||||
0x0000007100fc91f0,O,000052,_ZN4ksys4phys17ShapeCastWithInfoC1EPNS0_9RigidBodyEPNS0_21QueryContactPointInfoENS0_9ShapeCast4ModeE
|
||||
0x0000007100fc9224,O,000072,_ZN4ksys4phys17ShapeCastWithInfoD1Ev
|
||||
0x0000007100fc926c,O,000080,_ZN4ksys4phys17ShapeCastWithInfoD0Ev
|
||||
0x0000007100fc92bc,m,000456,_ZN4ksys4phys17ShapeCastWithInfo12executeQueryENS0_9ShapeCast17WeldClosestPointsE
|
||||
0x0000007100fc9484,O,000316,_ZN4ksys4phys17ShapeCastWithInfo6doCastERK18hkpLinearCastInputR19hkpCdPointCollectorPS5_
|
||||
0x0000007100fc95c0,O,000536,_ZN4ksys4phys10SphereCastC1ENS0_12ContactLayerENS0_9GroundHitEPNS0_18SystemGroupHandlerEiNS0_9ShapeCast4ModeERKN4sead7Vector3IfEEfRKNS8_14SafeStringBaseIcEENS0_11LowPriorityE
|
||||
0x0000007100fc97d8,O,000124,_ZN4ksys4phys10SphereCastD1Ev
|
||||
0x0000007100fc9854,O,000132,_ZN4ksys4phys10SphereCastD0Ev
|
||||
0x0000007100fc98d8,O,000040,_ZN4ksys4phys10SphereCast9setRadiusEf
|
||||
0x0000007100fc9900,O,000204,_ZNK4ksys4phys17ShapeCastWithInfo27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100fc99cc,O,000092,_ZNK4ksys4phys17ShapeCastWithInfo18getRuntimeTypeInfoEv
|
||||
0x0000007100fc9a28,O,000288,_ZNK4ksys4phys10SphereCast27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100fc9b48,O,000092,_ZNK4ksys4phys10SphereCast18getRuntimeTypeInfoEv
|
||||
0x0000007100fc9ba4,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys9ShapeCastEE9isDerivedEPKNS0_9InterfaceE
|
||||
0x0000007100fc9c30,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys17ShapeCastWithInfoEE9isDerivedEPKNS0_9InterfaceE
|
||||
0x0000007100fc9cbc,O,000208,_ZN4ksys4phys14StaticCompoundC1Ev
|
||||
0x0000007100fc9d8c,U,000352,ResourceHksc::dtor
|
||||
0x0000007100fc9eec,U,000008,
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -89,7 +89,9 @@ add_library(hkStubs OBJECT
|
|||
|
||||
Havok/Physics2012/Collide/Agent/hkpCollisionInput.h
|
||||
Havok/Physics2012/Collide/Agent/hkpCollisionQualityInfo.h
|
||||
Havok/Physics2012/Collide/Agent/hkpProcessCollisionInput.h
|
||||
Havok/Physics2012/Collide/Agent/Collidable/hkpCdBody.h
|
||||
Havok/Physics2012/Collide/Agent/Collidable/hkpCdPoint.h
|
||||
Havok/Physics2012/Collide/Agent/Collidable/hkpCollidable.h
|
||||
Havok/Physics2012/Collide/Agent/Collidable/hkpCollidableQualityType.h
|
||||
Havok/Physics2012/Collide/Agent/ContactMgr/hkpContactMgr.h
|
||||
|
@ -110,7 +112,11 @@ add_library(hkStubs OBJECT
|
|||
Havok/Physics2012/Collide/Filter/Group/hkpGroupFilter.cpp
|
||||
Havok/Physics2012/Collide/Filter/Group/hkpGroupFilter.h
|
||||
Havok/Physics2012/Collide/Query/hkpRayHitCollector.h
|
||||
Havok/Physics2012/Collide/Query/CastUtil/hkpLinearCastInput.h
|
||||
Havok/Physics2012/Collide/Query/CastUtil/hkpWorldRayCastInput.h
|
||||
Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpAllCdPointCollector.h
|
||||
Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpClosestCdPointCollector.h
|
||||
Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpRootCdPoint.h
|
||||
Havok/Physics2012/Collide/Shape/hkpShape.h
|
||||
Havok/Physics2012/Collide/Shape/hkpShapeBase.h
|
||||
Havok/Physics2012/Collide/Shape/hkpShapeBuffer.h
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Common/Base/Types/Physics/ContactPoint/hkContactPoint.h>
|
||||
#include <Havok/Common/Base/hkBase.h>
|
||||
|
||||
class hkpCdBody;
|
||||
|
||||
struct hkpCdPoint {
|
||||
HK_DECLARE_CLASS_ALLOCATOR(hkpCdPoint)
|
||||
|
||||
hkpCdPoint(const hkpCdBody& a, const hkpCdBody& b) : m_cdBodyA(a), m_cdBodyB(b) {}
|
||||
hkpCdPoint(const hkpCdBody& a, const hkpCdBody& b, const hkContactPoint& cp)
|
||||
: m_contact(cp), m_cdBodyA(a), m_cdBodyB(b) {
|
||||
m_unweldedNormal = cp.getNormal();
|
||||
}
|
||||
|
||||
const hkContactPoint& getContact() const { return m_contact; }
|
||||
|
||||
void setContact(const hkContactPoint& cp) {
|
||||
m_contact = cp;
|
||||
m_unweldedNormal = cp.getNormal();
|
||||
}
|
||||
|
||||
void setContact(hkVector4Parameter pos, hkVector4Parameter norm, hkReal d) {
|
||||
m_contact.set(pos, norm, d);
|
||||
m_unweldedNormal = norm;
|
||||
}
|
||||
|
||||
void setContact(hkVector4Parameter pos, hkVector4Parameter norm,
|
||||
hkVector4Parameter unweldedNorm, hkReal d) {
|
||||
m_contact.set(pos, norm, d);
|
||||
m_unweldedNormal = unweldedNorm;
|
||||
}
|
||||
|
||||
void setContactDistance(hkReal d) { m_contact.setDistance(d); }
|
||||
void setContactNormal(hkVector4Parameter norm) { m_contact.setNormalOnly(norm); }
|
||||
void setContactDistance(hkSimdRealParameter d) { m_contact.setDistanceSimdReal(d); }
|
||||
void setUnweldedNormal(hkVector4Parameter norm) { m_unweldedNormal = norm; }
|
||||
const hkVector4& getUnweldedNormal() const { return m_unweldedNormal; }
|
||||
|
||||
protected:
|
||||
hkContactPoint m_contact;
|
||||
hkVector4 m_unweldedNormal;
|
||||
|
||||
public:
|
||||
const hkpCdBody& m_cdBodyA;
|
||||
const hkpCdBody& m_cdBodyB;
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Common/Base/Types/Physics/hkStepInfo.h>
|
||||
#include <Havok/Common/Base/hkBase.h>
|
||||
#include <Havok/Physics2012/Collide/Agent/hkpCollisionInput.h>
|
||||
|
||||
struct hkpAgent1nSector;
|
||||
struct hkpCollisionAgentConfig;
|
||||
struct hkpCollisionQualityInfo;
|
||||
|
||||
struct hkpProcessCollisionInput : hkpCollisionInput {
|
||||
HK_DECLARE_CLASS_ALLOCATOR(hkpProcessCollisionInput)
|
||||
|
||||
hkStepInfo m_stepInfo;
|
||||
mutable hkpCollisionQualityInfo* m_collisionQualityInfo;
|
||||
mutable hkpAgent1nSector* m_spareAgentSector;
|
||||
void* m_dynamicsInfo;
|
||||
hkBool m_enableDeprecatedWelding;
|
||||
hkBool m_allowToSkipConfirmedCallbacks;
|
||||
hkpCollisionAgentConfig* m_config;
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Common/Base/hkBase.h>
|
||||
|
||||
struct hkpLinearCastInput {
|
||||
HK_DECLARE_CLASS_ALLOCATOR(hkpLinearCastInput)
|
||||
|
||||
hkVector4 m_to;
|
||||
hkReal m_maxExtraPenetration = HK_REAL_EPSILON;
|
||||
hkReal m_startPointTolerance = HK_REAL_EPSILON;
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Common/Base/hkBase.h>
|
||||
#include <Havok/Physics2012/Collide/Agent/Query/hkpCdPointCollector.h>
|
||||
#include <Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpRootCdPoint.h>
|
||||
|
||||
class hkpAllCdPointCollector : public hkpCdPointCollector {
|
||||
public:
|
||||
HK_DECLARE_CLASS_ALLOCATOR(hkpAllCdPointCollector)
|
||||
|
||||
inline hkpAllCdPointCollector();
|
||||
inline ~hkpAllCdPointCollector() override;
|
||||
inline void reset() override;
|
||||
|
||||
inline const hkArray<hkpRootCdPoint>& getHits() const;
|
||||
inline hkArray<hkpRootCdPoint>& getHits();
|
||||
|
||||
inline int getNumHits() const;
|
||||
inline hkBool hasHit() const;
|
||||
|
||||
void sortHits();
|
||||
|
||||
void addCdPoint(const hkpCdPoint& event) override;
|
||||
|
||||
protected:
|
||||
hkInplaceArray<hkpRootCdPoint, 8> m_hits;
|
||||
};
|
||||
|
||||
inline hkpAllCdPointCollector::hkpAllCdPointCollector() {
|
||||
reset();
|
||||
}
|
||||
|
||||
inline hkpAllCdPointCollector::~hkpAllCdPointCollector() = default;
|
||||
|
||||
inline void hkpAllCdPointCollector::reset() {
|
||||
m_hits.clear();
|
||||
hkpCdPointCollector::reset();
|
||||
}
|
||||
|
||||
inline const hkArray<hkpRootCdPoint>& hkpAllCdPointCollector::getHits() const {
|
||||
return m_hits;
|
||||
}
|
||||
|
||||
inline hkArray<hkpRootCdPoint>& hkpAllCdPointCollector::getHits() {
|
||||
return m_hits;
|
||||
}
|
||||
|
||||
inline int hkpAllCdPointCollector::getNumHits() const {
|
||||
return m_hits.getSize();
|
||||
}
|
||||
|
||||
inline hkBool hkpAllCdPointCollector::hasHit() const {
|
||||
return getNumHits() > 0;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Physics2012/Collide/Agent/Query/hkpCdPointCollector.h>
|
||||
#include <Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpRootCdPoint.h>
|
||||
|
||||
class hkpClosestCdPointCollector : public hkpCdPointCollector {
|
||||
public:
|
||||
HK_DECLARE_CLASS_ALLOCATOR(hkpClosestCdPointCollector)
|
||||
|
||||
inline hkpClosestCdPointCollector();
|
||||
inline ~hkpClosestCdPointCollector() override;
|
||||
|
||||
inline void reset() override;
|
||||
|
||||
inline hkBool hasHit() const;
|
||||
inline const hkpRootCdPoint& getHit() const;
|
||||
inline const hkContactPoint& getHitContact() const;
|
||||
|
||||
inline const hkVector4& getUnweldedNormal() const;
|
||||
|
||||
protected:
|
||||
void addCdPoint(const hkpCdPoint& pointInfo) override;
|
||||
|
||||
hkpRootCdPoint m_hitPoint;
|
||||
hkVector4 m_unweldedNormal;
|
||||
};
|
||||
|
||||
inline hkpClosestCdPointCollector::hkpClosestCdPointCollector() {
|
||||
reset();
|
||||
}
|
||||
|
||||
inline hkpClosestCdPointCollector::~hkpClosestCdPointCollector() = default;
|
||||
|
||||
inline void hkpClosestCdPointCollector::reset() {
|
||||
m_hitPoint.m_rootCollidableA = nullptr;
|
||||
m_hitPoint.m_contact.setDistanceSimdReal(hkSimdReal::getConstant<HK_QUADREAL_MAX>());
|
||||
hkpCdPointCollector::reset();
|
||||
}
|
||||
|
||||
inline hkBool hkpClosestCdPointCollector::hasHit() const {
|
||||
return m_hitPoint.m_rootCollidableA != nullptr;
|
||||
}
|
||||
|
||||
inline const hkpRootCdPoint& hkpClosestCdPointCollector::getHit() const {
|
||||
return m_hitPoint;
|
||||
}
|
||||
|
||||
inline const hkContactPoint& hkpClosestCdPointCollector::getHitContact() const {
|
||||
return m_hitPoint.getContact();
|
||||
}
|
||||
|
||||
inline const hkVector4& hkpClosestCdPointCollector::getUnweldedNormal() const {
|
||||
return m_unweldedNormal;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Common/Base/Types/Physics/ContactPoint/hkContactPoint.h>
|
||||
#include <Havok/Common/Base/hkBase.h>
|
||||
#include <Havok/Physics2012/Collide/Shape/hkpShapeBase.h>
|
||||
|
||||
class hkpCollidable;
|
||||
|
||||
struct hkpRootCdPoint {
|
||||
HK_DECLARE_CLASS_ALLOCATOR(hkpRootCdPoint)
|
||||
|
||||
hkBool32 operator<(const hkpRootCdPoint& b) const {
|
||||
return m_contact.getDistanceSimdReal().isLess(b.m_contact.getDistanceSimdReal());
|
||||
}
|
||||
|
||||
const hkContactPoint& getContact() const { return m_contact; }
|
||||
|
||||
void setContact(const hkContactPoint& cp) { m_contact = cp; }
|
||||
|
||||
void setContact(hkVector4Parameter pos, hkVector4Parameter norm, hkReal d) {
|
||||
m_contact.set(pos, norm, d);
|
||||
}
|
||||
void setContact(hkVector4Parameter pos, hkVector4Parameter norm, hkSimdRealParameter d) {
|
||||
m_contact.setPositionNormalAndDistance(pos, norm, d);
|
||||
}
|
||||
|
||||
void setContactDistance(hkReal d) { m_contact.setDistance(d); }
|
||||
void setContactDistance(hkSimdRealParameter d) { m_contact.setDistanceSimdReal(d); }
|
||||
|
||||
hkContactPoint m_contact;
|
||||
const hkpCollidable* m_rootCollidableA;
|
||||
hkpShapeKey m_shapeKeyA;
|
||||
const hkpCollidable* m_rootCollidableB;
|
||||
hkpShapeKey m_shapeKeyB;
|
||||
};
|
|
@ -311,6 +311,11 @@ public:
|
|||
hkThreadPool* threadPool, hkSemaphoreBusyWait* semaphore,
|
||||
int numCommandsPerJob = 32) const;
|
||||
|
||||
/// Cast a shape.
|
||||
///
|
||||
/// @param collA The collidable for the shape to cast.
|
||||
/// @param castCollector Collects all potential hits.
|
||||
/// @param startCollector [Optional] Collects points that are closest to the start point.
|
||||
void linearCast(const hkpCollidable* collA, const hkpLinearCastInput& input,
|
||||
hkpCdPointCollector& castCollector,
|
||||
hkpCdPointCollector* startCollector = nullptr) const;
|
||||
|
|
|
@ -143,6 +143,10 @@ target_sources(uking PRIVATE
|
|||
System/physSensorContactListener.h
|
||||
System/physSensorGroupFilter.cpp
|
||||
System/physSensorGroupFilter.h
|
||||
System/physShapeCast.cpp
|
||||
System/physShapeCast.h
|
||||
System/physShapeCastWithInfo.cpp
|
||||
System/physShapeCastWithInfo.h
|
||||
System/physSystem.cpp
|
||||
System/physSystem.h
|
||||
System/physSystemData.cpp
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
|
||||
float getVolume() override;
|
||||
|
||||
void setRadius(float radius);
|
||||
|
||||
protected:
|
||||
Shape* getShape_() override;
|
||||
const Shape* getShape_() const override;
|
||||
|
|
|
@ -527,7 +527,7 @@ public:
|
|||
bool isEntityMotionFlag200On() const;
|
||||
|
||||
// FIXME: return type
|
||||
virtual u32 getCollisionMasks(RigidBody::CollisionMasks* masks, const u32* unk,
|
||||
virtual u32 getCollisionMasks(RigidBody::CollisionMasks* masks, const u32* shape_key,
|
||||
const sead::Vector3f& contact_point) = 0;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -19,11 +19,7 @@ void ClosestPointQuery::reset() {
|
|||
}
|
||||
|
||||
void ClosestPointQuery::setLayerMasks(const LayerMaskBuilder& builder) {
|
||||
auto* info = mContactPointInfo;
|
||||
for (int i = 0; i < NumContactLayerTypes; ++i) {
|
||||
info->mSubscribedLayers[i] = builder.getMasks()[i].layers;
|
||||
info->mLayerMask2[i] = builder.getMasks()[i].layers2;
|
||||
}
|
||||
mContactPointInfo->setLayerMasks(builder);
|
||||
}
|
||||
|
||||
bool ClosestPointQuery::isSuccess() const {
|
||||
|
|
|
@ -226,8 +226,8 @@ int ContactListener::notifyContactPointInfo(RigidBody* body_a, RigidBody* body_b
|
|||
|
||||
int result = 1;
|
||||
|
||||
if (info_b && info_b->isLayerSubscribed(layer_a) && (info_b->get30() == 0 || distance <= 0.0) &&
|
||||
(info_b->get34() == 0 || !contact_disabled)) {
|
||||
if (info_b && info_b->isLayerSubscribed(layer_a) &&
|
||||
info_b->testContactPointDistance(distance) && (info_b->get34() == 0 || !contact_disabled)) {
|
||||
if (should_notify) {
|
||||
point.body_a = body_b;
|
||||
point.body_b = body_a;
|
||||
|
@ -250,8 +250,8 @@ int ContactListener::notifyContactPointInfo(RigidBody* body_a, RigidBody* body_b
|
|||
clearCallbackDelay(event);
|
||||
}
|
||||
|
||||
if (info_a && info_a->isLayerSubscribed(layer_b) && (info_a->get30() == 0 || distance <= 0.0) &&
|
||||
(info_a->get34() == 0 || !contact_disabled)) {
|
||||
if (info_a && info_a->isLayerSubscribed(layer_b) &&
|
||||
info_a->testContactPointDistance(distance) && (info_a->get34() == 0 || !contact_disabled)) {
|
||||
if (should_notify) {
|
||||
point.body_a = body_a;
|
||||
point.body_b = body_b;
|
||||
|
@ -293,7 +293,7 @@ void ContactListener::notifyLayerContactPointInfo(const TrackedContactPointLayer
|
|||
return;
|
||||
|
||||
const hkReal distance = event.m_contactPoint->getDistance();
|
||||
if (!(tracked_layer.info->get30() == 0 || distance <= 0.0))
|
||||
if (!tracked_layer.info->testContactPointDistance(distance))
|
||||
return;
|
||||
|
||||
if (tracked_layer.info->get34() != 0 && isContactDisabled(event))
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <prim/seadSafeString.h>
|
||||
#include <thread/seadAtomic.h>
|
||||
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
|
||||
#include "KingSystem/Physics/physDefines.h"
|
||||
#include "KingSystem/Physics/physLayerMaskBuilder.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace ksys::phys {
|
||||
|
@ -31,6 +33,9 @@ public:
|
|||
u32 get30() const { return _30; }
|
||||
void set30(u32 value) { _30 = value; }
|
||||
|
||||
// TODO: rename
|
||||
bool testContactPointDistance(float distance) const { return get30() == 0 || distance <= 0; }
|
||||
|
||||
u32 get34() const { return _34; }
|
||||
void set34(u32 value) { _34 = value; }
|
||||
|
||||
|
@ -45,9 +50,18 @@ public:
|
|||
return mLayerMask2[int(type)].isOnBit(int(getContactLayerBaseRelativeValue(layer)));
|
||||
}
|
||||
|
||||
void setLayerMasks(const LayerMaskBuilder& builder) {
|
||||
for (int i = 0; i < NumContactLayerTypes; ++i) {
|
||||
mSubscribedLayers[i] = builder.getMasks()[i].layers;
|
||||
mLayerMask2[i] = builder.getMasks()[i].layers2;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// For internal use by the physics system.
|
||||
|
||||
sead::Atomic<int>& getNumContactPoints() { return mNumContactPoints; }
|
||||
|
||||
bool isLinked() const { return mListNode.isLinked(); }
|
||||
|
||||
static constexpr size_t getListNodeOffset() {
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
#include "KingSystem/Physics/System/physShapeCast.h"
|
||||
#include <Havok/Physics2012/Collide/Agent/Collidable/hkpCdPoint.h>
|
||||
#include <Havok/Physics2012/Collide/Agent/hkpProcessCollisionInput.h>
|
||||
#include <Havok/Physics2012/Collide/Query/CastUtil/hkpLinearCastInput.h>
|
||||
#include <Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpAllCdPointCollector.h>
|
||||
#include "KingSystem/Physics/System/physContactMgr.h"
|
||||
#include "KingSystem/Physics/System/physEntityContactListener.h"
|
||||
#include "KingSystem/Physics/System/physGroupFilter.h"
|
||||
#include "KingSystem/Physics/System/physQueryContactPointInfo.h"
|
||||
#include "KingSystem/Physics/System/physSystem.h"
|
||||
#include "KingSystem/Physics/physConversions.h"
|
||||
#include "KingSystem/Physics/physLayerMaskBuilder.h"
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
ShapeCast::ShapeCast(RigidBody* body, QueryContactPointInfo* contact_point_info, Mode mode)
|
||||
: mContactPointInfo(contact_point_info), mMode(mode) {
|
||||
if (body)
|
||||
mBody = body;
|
||||
|
||||
mTo = sead::Vector3f::zero;
|
||||
mFrom = sead::Vector3f::zero;
|
||||
mRotation.set(1, 0, 0, 0);
|
||||
reset();
|
||||
}
|
||||
|
||||
ShapeCast::~ShapeCast() = default;
|
||||
|
||||
void ShapeCast::reset() {
|
||||
_40 = {};
|
||||
_41 = {};
|
||||
_42 = {};
|
||||
_44 = {};
|
||||
|
||||
if (mContactPointInfo)
|
||||
mContactPointInfo->getNumContactPoints() = 0;
|
||||
}
|
||||
|
||||
void ShapeCast::setRotation(sead::Quatf rotation) {
|
||||
mRotation = rotation;
|
||||
}
|
||||
|
||||
void ShapeCast::setRotation(const sead::Matrix33f& rotation_matrix) {
|
||||
auto quat = sead::Quatf::unit;
|
||||
rotation_matrix.toQuat(quat);
|
||||
setRotation(quat);
|
||||
}
|
||||
|
||||
void ShapeCast::setRotation(const sead::Matrix34f& transform_matrix) {
|
||||
auto quat = sead::Quatf::unit;
|
||||
transform_matrix.toQuat(quat);
|
||||
setRotation(quat);
|
||||
}
|
||||
|
||||
void ShapeCast::setStartAndEnd(const sead::Vector3f& start, const sead::Vector3f& end) {
|
||||
mFrom = start;
|
||||
mTo = end;
|
||||
}
|
||||
|
||||
void ShapeCast::setStartAndDisplacement(const sead::Vector3f& start,
|
||||
const sead::Vector3f& displacement) {
|
||||
mFrom = start;
|
||||
mTo = start + displacement;
|
||||
}
|
||||
|
||||
void ShapeCast::setStartAndDisplacementScaled(const sead::Vector3f& start,
|
||||
const sead::Vector3f& displacement,
|
||||
float displacement_scale) {
|
||||
mFrom = start;
|
||||
mTo = start + displacement * displacement_scale;
|
||||
}
|
||||
|
||||
void ShapeCast::setLayerMasks(const LayerMaskBuilder& mask_builder) {
|
||||
mContactPointInfo->setLayerMasks(mask_builder);
|
||||
}
|
||||
|
||||
void ShapeCast::setColors(const sead::Color4f& color1, const sead::Color4f& color2,
|
||||
const sead::Color4f& color3, bool enabled) {
|
||||
// Stubbed in release builds.
|
||||
}
|
||||
|
||||
// NON_MATCHING: the last if block is a complete mess. Should be equivalent, though.
|
||||
bool ShapeCast::doExecuteQuery(hkpCdPointCollector& cast_collector,
|
||||
hkpAllCdPointCollector* start_collector,
|
||||
ShapeCast::WeldClosestPoints weld_closest_points,
|
||||
OnlyLockIfNeeded only_lock_if_needed) {
|
||||
const auto layer_type = mBody->getLayerType();
|
||||
|
||||
System::instance()->lockWorld(layer_type, "shape_cast", 0, only_lock_if_needed);
|
||||
|
||||
hkpLinearCastInput input;
|
||||
loadFromVec3(&input.m_to, mTo);
|
||||
|
||||
// Reset internal state.
|
||||
cast_collector.reset();
|
||||
if (_44 == 1)
|
||||
reset();
|
||||
|
||||
System::instance()->getHavokWorld(layer_type)->m_collisionInput->m_weldClosestPoints =
|
||||
bool(weld_closest_points);
|
||||
|
||||
doCast(input, cast_collector, start_collector);
|
||||
|
||||
System::instance()->unlockWorld(layer_type, "shape_cast", 0, only_lock_if_needed);
|
||||
|
||||
// Register every point that is in start_collector.
|
||||
auto* body = mBody;
|
||||
for (int i = 0, n = start_collector->getNumHits(); i < n; ++i) {
|
||||
if (registerContactPoint(start_collector->getHits()[i], body, ClampDistance::Yes)) {
|
||||
_40 = true;
|
||||
if (mMode == Mode::_0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_41 = _40;
|
||||
|
||||
if (mMode == Mode::_2 || !_40) {
|
||||
int num_hits = 0;
|
||||
FilteredClosestCdPointCollector* filtered_collector = nullptr;
|
||||
hkpAllCdPointCollector* all_point_collector = nullptr;
|
||||
bool ok = false;
|
||||
|
||||
if (mMode == Mode::_1 || mMode == Mode::_0) {
|
||||
filtered_collector = static_cast<FilteredClosestCdPointCollector*>(&cast_collector);
|
||||
num_hits = 1;
|
||||
ok = filtered_collector->hasHit();
|
||||
} else {
|
||||
all_point_collector = static_cast<hkpAllCdPointCollector*>(&cast_collector);
|
||||
num_hits = all_point_collector->getNumHits();
|
||||
ok = num_hits >= 0;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
for (int i = 0; i < num_hits; ++i) {
|
||||
const auto& point = mMode == Mode::_2 ? all_point_collector->getHits()[i] :
|
||||
filtered_collector->getHit();
|
||||
if (registerContactPoint(point, body, ClampDistance::No))
|
||||
_40 = true;
|
||||
}
|
||||
}
|
||||
|
||||
_42 = _40;
|
||||
}
|
||||
|
||||
_44 = 1;
|
||||
return _40;
|
||||
}
|
||||
|
||||
bool ShapeCast::registerContactPoint(const hkpRootCdPoint& point, RigidBody* body,
|
||||
ClampDistance clamp_distance) {
|
||||
auto* hit_entity = getHkpEntity(*point.m_rootCollidableB);
|
||||
if (!hit_entity)
|
||||
return false;
|
||||
|
||||
if (!mContactPointInfo->testContactPointDistance(point.getContact().getDistance()))
|
||||
return false;
|
||||
|
||||
auto* hit_body = getRigidBody(hit_entity);
|
||||
|
||||
if (System::instance()->getEntityContactListenerField91() && hit_body->isEntity() &&
|
||||
EntityContactListener::isObjectOrGroundOrNPCOrTree(*hit_body)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RigidBodyCollisionMasks masks_a, masks_b;
|
||||
sead::Vector3f contact_position;
|
||||
storeToVec3(&contact_position, point.getContact().getPosition());
|
||||
|
||||
body->getCollisionMasks(&masks_a, &point.m_shapeKeyA, contact_position);
|
||||
hit_body->getCollisionMasks(&masks_b, &point.m_shapeKeyB, contact_position);
|
||||
|
||||
auto* filter = System::instance()->getGroupFilter(hit_body->getLayerType());
|
||||
auto layer_b = filter->getCollisionFilterInfoLayer(masks_b.collision_filter_info);
|
||||
|
||||
if (!mContactPointInfo->isLayerSubscribed(layer_b))
|
||||
return false;
|
||||
|
||||
ContactPoint contact_point;
|
||||
contact_point.flags.makeAllZero();
|
||||
contact_point.body_a = body;
|
||||
contact_point.body_b = hit_body;
|
||||
contact_point.material_mask_a = MaterialMaskData(masks_a.material_mask);
|
||||
contact_point.material_mask_b = MaterialMaskData(masks_b.material_mask);
|
||||
storeToVec3(&contact_point.position, point.getContact().getPosition());
|
||||
storeToVec3(&contact_point.separating_normal, point.getContact().getSeparatingNormal());
|
||||
|
||||
float distance = point.getContact().getDistance();
|
||||
if (distance < 0 && bool(clamp_distance))
|
||||
distance = 0;
|
||||
|
||||
contact_point.separating_distance = distance;
|
||||
contact_point.shape_key_a = point.m_shapeKeyA;
|
||||
contact_point.shape_key_b = point.m_shapeKeyB;
|
||||
contact_point.separating_normal *= -1;
|
||||
|
||||
return System::instance()->getContactMgr()->registerContactPoint(mContactPointInfo,
|
||||
contact_point, true);
|
||||
}
|
||||
|
||||
FilteredClosestCdPointCollector::FilteredClosestCdPointCollector(
|
||||
RigidBody* body, QueryContactPointInfo* contact_point_info)
|
||||
: mBody(body), mContactPointInfo(contact_point_info) {}
|
||||
|
||||
// NON_MATCHING: the original code has a useless `if (this == nullptr)` check for some reason
|
||||
FilteredClosestCdPointCollector::~FilteredClosestCdPointCollector() = default;
|
||||
|
||||
void FilteredClosestCdPointCollector::addCdPoint(const hkpCdPoint& point) {
|
||||
auto* body = mBody;
|
||||
const auto point_distance = point.getContact().getDistanceSimdReal();
|
||||
|
||||
if (hasHit() && !point_distance.isLess(getHitContact().getDistanceSimdReal()))
|
||||
return;
|
||||
|
||||
auto* hit_entity = getHkpEntity(*point.m_cdBodyB.getRootCollidable());
|
||||
if (!hit_entity)
|
||||
return;
|
||||
|
||||
auto* hit_body = getRigidBody(hit_entity);
|
||||
|
||||
if (System::instance()->getEntityContactListenerField91() && hit_body->isEntity() &&
|
||||
EntityContactListener::isObjectOrGroundOrNPCOrTree(*hit_body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RigidBodyCollisionMasks masks_a, masks_b;
|
||||
sead::Vector3f contact_position;
|
||||
storeToVec3(&contact_position, point.getContact().getPosition());
|
||||
auto shape_key_a = point.m_cdBodyA.getShapeKey();
|
||||
auto shape_key_b = point.m_cdBodyB.getShapeKey();
|
||||
|
||||
body->getCollisionMasks(&masks_a, &shape_key_a, contact_position);
|
||||
hit_body->getCollisionMasks(&masks_b, &shape_key_b, contact_position);
|
||||
|
||||
auto* filter = System::instance()->getGroupFilter(hit_body->getLayerType());
|
||||
auto layer_b = filter->getCollisionFilterInfoLayer(masks_b.collision_filter_info);
|
||||
|
||||
if (!mContactPointInfo->isLayerSubscribed(layer_b))
|
||||
return;
|
||||
|
||||
m_hitPoint.setContact(point.getContact());
|
||||
m_hitPoint.m_rootCollidableA = point.m_cdBodyA.getRootCollidable();
|
||||
m_hitPoint.m_shapeKeyA = point.m_cdBodyA.getShapeKey();
|
||||
m_hitPoint.m_rootCollidableB = point.m_cdBodyB.getRootCollidable();
|
||||
m_hitPoint.m_shapeKeyB = point.m_cdBodyB.getShapeKey();
|
||||
// Set m_earlyOutDistance to the current distance as an optimisation.
|
||||
m_earlyOutDistance = point_distance;
|
||||
m_unweldedNormal = point.getUnweldedNormal();
|
||||
}
|
||||
|
||||
void FilteredClosestCdPointCollector::reset() {
|
||||
hkpClosestCdPointCollector::reset();
|
||||
m_earlyOutDistance = 1.0f;
|
||||
}
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -0,0 +1,100 @@
|
|||
#pragma once
|
||||
|
||||
#include <Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpClosestCdPointCollector.h>
|
||||
#include <gfx/seadColor.h>
|
||||
#include <math/seadMatrix.h>
|
||||
#include <math/seadQuat.h>
|
||||
#include <math/seadVector.h>
|
||||
#include <prim/seadRuntimeTypeInfo.h>
|
||||
|
||||
class hkpAllCdPointCollector;
|
||||
class hkpCdPointCollector;
|
||||
struct hkpLinearCastInput;
|
||||
struct hkpRootCdPoint;
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
enum class OnlyLockIfNeeded : bool;
|
||||
|
||||
class LayerMaskBuilder;
|
||||
class RigidBody;
|
||||
class QueryContactPointInfo;
|
||||
|
||||
class ShapeCast {
|
||||
SEAD_RTTI_BASE(ShapeCast)
|
||||
public:
|
||||
enum class WeldClosestPoints : bool { Yes = true, No = false };
|
||||
|
||||
virtual bool executeQuery(WeldClosestPoints weld_closest_points) = 0;
|
||||
|
||||
protected:
|
||||
virtual void doCast(const hkpLinearCastInput& input, hkpCdPointCollector& cast_collector,
|
||||
hkpCdPointCollector* start_collector) = 0;
|
||||
|
||||
public:
|
||||
enum class Mode {
|
||||
_0 = 0,
|
||||
_1 = 1,
|
||||
_2 = 2,
|
||||
};
|
||||
|
||||
ShapeCast(RigidBody* body, QueryContactPointInfo* contact_point_info, Mode mode);
|
||||
virtual ~ShapeCast();
|
||||
|
||||
void reset();
|
||||
|
||||
void setRotation(sead::Quatf rotation);
|
||||
void setRotation(const sead::Matrix33f& rotation_matrix);
|
||||
void setRotation(const sead::Matrix34f& transform_matrix);
|
||||
|
||||
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);
|
||||
|
||||
void setLayerMasks(const LayerMaskBuilder& mask_builder);
|
||||
|
||||
void setColors(const sead::Color4f& color1, const sead::Color4f& color2,
|
||||
const sead::Color4f& color3, bool enabled = true);
|
||||
|
||||
protected:
|
||||
bool doExecuteQuery(hkpCdPointCollector& cast_collector,
|
||||
hkpAllCdPointCollector* start_collector,
|
||||
WeldClosestPoints weld_closest_points,
|
||||
OnlyLockIfNeeded only_lock_if_needed);
|
||||
|
||||
enum class ClampDistance : bool { Yes = true, No = false };
|
||||
bool registerContactPoint(const hkpRootCdPoint& point, RigidBody* body,
|
||||
ClampDistance clamp_distance);
|
||||
|
||||
RigidBody* mBody{};
|
||||
QueryContactPointInfo* mContactPointInfo{};
|
||||
/// The start position of the ray in world space.
|
||||
sead::Vector3f mFrom = sead::Vector3f::zero;
|
||||
/// The end position of the ray in world space.
|
||||
sead::Vector3f mTo = sead::Vector3f::zero;
|
||||
sead::Quatf mRotation = sead::Quatf::unit;
|
||||
bool _40{};
|
||||
bool _41{};
|
||||
bool _42{};
|
||||
int _44{};
|
||||
Mode mMode{};
|
||||
};
|
||||
|
||||
class FilteredClosestCdPointCollector : public hkpClosestCdPointCollector {
|
||||
public:
|
||||
HK_DECLARE_CLASS_ALLOCATOR(FilteredClosestCdPointCollector)
|
||||
|
||||
FilteredClosestCdPointCollector(RigidBody* body, QueryContactPointInfo* contact_point_info);
|
||||
~FilteredClosestCdPointCollector() override;
|
||||
|
||||
void addCdPoint(const hkpCdPoint& point) override;
|
||||
void reset() override;
|
||||
|
||||
protected:
|
||||
RigidBody* mBody{};
|
||||
QueryContactPointInfo* mContactPointInfo{};
|
||||
};
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -0,0 +1,94 @@
|
|||
#include "KingSystem/Physics/System/physShapeCastWithInfo.h"
|
||||
#include <Havok/Physics2012/Collide/Agent/Collidable/hkpCollidable.h>
|
||||
#include <Havok/Physics2012/Collide/Query/Collector/PointCollector/hkpAllCdPointCollector.h>
|
||||
#include <Havok/Physics2012/Dynamics/Entity/hkpRigidBody.h>
|
||||
#include <Havok/Physics2012/Dynamics/World/hkpWorld.h>
|
||||
#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
|
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include "KingSystem/Physics/System/physShapeCast.h"
|
||||
#include "KingSystem/Physics/System/physSystem.h"
|
||||
#include "KingSystem/Physics/physDefines.h"
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
class SphereRigidBody;
|
||||
class SystemGroupHandler;
|
||||
|
||||
class ShapeCastWithInfo : public ShapeCast {
|
||||
SEAD_RTTI_OVERRIDE(ShapeCastWithInfo, ShapeCast)
|
||||
public:
|
||||
ShapeCastWithInfo(RigidBody* body, int num_contact_points, Mode mode,
|
||||
const sead::SafeString& name, LowPriority low_priority);
|
||||
ShapeCastWithInfo(RigidBody* body, QueryContactPointInfo* contact_point_info, Mode mode);
|
||||
|
||||
~ShapeCastWithInfo() override;
|
||||
|
||||
bool executeQuery(WeldClosestPoints weld_closest_points) override;
|
||||
|
||||
protected:
|
||||
enum class Status {
|
||||
_0 = 0,
|
||||
_1 = 1,
|
||||
_2 = 2,
|
||||
_3 = 3,
|
||||
};
|
||||
|
||||
void doCast(const hkpLinearCastInput& input, hkpCdPointCollector& cast_collector,
|
||||
hkpCdPointCollector* start_collector) override;
|
||||
|
||||
Status mStatus = Status::_0;
|
||||
};
|
||||
|
||||
class SphereCast : public ShapeCastWithInfo {
|
||||
SEAD_RTTI_OVERRIDE(SphereCast, ShapeCastWithInfo)
|
||||
public:
|
||||
SphereCast(ContactLayer layer, GroundHit ground_hit, SystemGroupHandler* group_handler,
|
||||
int num_contact_points, Mode mode, const sead::Vector3f& from, float sphere_radius,
|
||||
const sead::SafeString& name, LowPriority low_priority);
|
||||
|
||||
~SphereCast() override;
|
||||
|
||||
void setRadius(float radius);
|
||||
|
||||
private:
|
||||
SphereRigidBody* mSphere;
|
||||
};
|
||||
|
||||
} // namespace ksys::phys
|
|
@ -7,6 +7,8 @@
|
|||
#include "KingSystem/Physics/physDefines.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
class hkpWorld;
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
class CollisionInfo;
|
||||
|
@ -27,10 +29,8 @@ enum class IsIndoorStage {
|
|||
Yes,
|
||||
};
|
||||
|
||||
enum class LowPriority : bool {
|
||||
Yes = true,
|
||||
No = false,
|
||||
};
|
||||
enum class LowPriority : bool { Yes = true, No = false };
|
||||
enum class OnlyLockIfNeeded : bool { Yes = true, No = false };
|
||||
|
||||
class System {
|
||||
SEAD_SINGLETON_DISPOSER(System)
|
||||
|
@ -85,8 +85,11 @@ public:
|
|||
|
||||
void removeSystemGroupHandler(SystemGroupHandler* handler);
|
||||
|
||||
void lockWorld(ContactLayerType type, void* a = nullptr, int b = 0, bool c = false);
|
||||
void unlockWorld(ContactLayerType type, void* a = nullptr, int b = 0, bool c = false);
|
||||
hkpWorld* getHavokWorld(ContactLayerType type) const;
|
||||
void lockWorld(ContactLayerType type, const char* description = nullptr, int b = 0,
|
||||
OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No);
|
||||
void unlockWorld(ContactLayerType type, const char* description = nullptr, int b = 0,
|
||||
OnlyLockIfNeeded only_lock_if_needed = OnlyLockIfNeeded::No);
|
||||
|
||||
// TODO: rename
|
||||
// 0x0000007101216c60
|
||||
|
@ -94,6 +97,11 @@ public:
|
|||
// 0x0000007101216c74
|
||||
bool getEntityContactListenerField90() const;
|
||||
|
||||
// 0x0000007101216800
|
||||
void setEntityContactListenerField91(bool value);
|
||||
// 0x0000007101216814
|
||||
bool getEntityContactListenerField91() const;
|
||||
|
||||
// 0x0000007101216cec
|
||||
sead::Heap* getPhysicsTempHeap(LowPriority low_priority) const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue