ksys/phys: Add RigidContactPointsEx iterator

This commit is contained in:
Léo Lam 2021-12-29 12:33:07 +01:00
parent b513fbbf03
commit 8ba8563775
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
3 changed files with 148 additions and 5 deletions

View File

@ -84308,10 +84308,10 @@ Address,Quality,Size,Name
0x0000007100fcfadc,O,000004,_ZN4ksys4phys20RigidContactPointsExD0Ev
0x0000007100fcfae0,O,000300,_ZN4ksys4phys20RigidContactPointsEx11allocPointsEPN4sead4HeapEii
0x0000007100fcfc0c,O,000168,_ZN4ksys4phys20RigidContactPointsEx10freePointsEv
0x0000007100fcfcb4,U,000260,
0x0000007100fcfdb8,U,000048,
0x0000007100fcfde8,U,000068,
0x0000007100fcfe2c,U,000028,
0x0000007100fcfcb4,O,000260,_ZNK4ksys4phys20RigidContactPointsEx8Iterator7getDataEPN4sead7Vector3IfEENS2_4ModeE
0x0000007100fcfdb8,O,000048,_ZNK4ksys4phys20RigidContactPointsEx8Iterator7getDataENS2_4ModeE
0x0000007100fcfde8,O,000068,_ZN4ksys4phys20RigidContactPointsEx8IteratorC1ERKN4sead6BufferIPNS1_5PointEEEi
0x0000007100fcfe2c,O,000028,_ZN4ksys4phys20RigidContactPointsEx11IteratorEndC1ERKN4sead6BufferIPNS1_5PointEEEi
0x0000007100fcfe48,U,000112,
0x0000007100fcfeb8,U,000072,
0x0000007100fcff00,U,000692,

Can't render this file because it is too large.

View File

@ -49,4 +49,53 @@ void RigidContactPointsEx::freePoints() {
mLayerEntries.freeBuffer();
}
void RigidContactPointsEx::Iterator::getData(sead::Vector3f* out,
RigidContactPointsEx::Iterator::Mode mode) const {
const float scale = getPoint()->scale;
out->e = getPoint()->_10.e;
switch (mode) {
case Mode::_0: {
if (getPoint()->flags.isOn(Point::Flag::_2))
return;
*out += getPoint()->_1c * -scale;
break;
}
case Mode::_1: {
if (!getPoint()->flags.isOn(Point::Flag::_2))
return;
*out += getPoint()->_1c * scale;
break;
}
case Mode::_2:
default: {
*out += getPoint()->_1c * scale * 0.5f;
break;
}
}
}
sead::Vector3f
RigidContactPointsEx::Iterator::getData(RigidContactPointsEx::Iterator::Mode mode) const {
sead::Vector3f out;
getData(&out, mode);
return out;
}
RigidContactPointsEx::Iterator::Iterator(const RigidContactPointsEx::Points& points, int count)
: mPoints(points.getBufferPtr()), mPointsNum(count), mPointsStart(points.getBufferPtr()) {
for (int i = 0; i != count; ++i) {
if (!mPoints[i]->flags.isOn(Point::Flag::_1))
break;
++mIdx;
}
}
RigidContactPointsEx::IteratorEnd::IteratorEnd(const RigidContactPointsEx::Points& points,
int count)
: mIdx(count), mPoints(points.getBufferPtr()), mPointsNum(count),
mPointsStart(points.getBufferPtr()) {}
} // namespace ksys::phys

View File

@ -1,14 +1,105 @@
#pragma once
#include <container/seadObjArray.h>
#include <math/seadVector.h>
#include <prim/seadTypedBitFlag.h>
#include "KingSystem/Physics/System/physDefines.h"
#include "KingSystem/Physics/System/physRigidContactPoints.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::phys {
// FIXME: rename. This should be below SensorGroupFilter and StaticCompound stuff
class RigidContactPointsEx : public IRigidContactPoints {
public:
struct Point {
enum class Flag {
_1 = 1 << 0,
_2 = 1 << 1,
};
void* _0;
void* _8;
sead::Vector3f _10;
sead::Vector3f _1c;
float scale;
void* _30;
void* _38;
void* _40;
void* _48;
void* _50;
void* _58;
void* _60;
sead::TypedBitFlag<Flag, u8> flags;
};
KSYS_CHECK_SIZE_NX150(Point, 0x70);
using Points = sead::Buffer<Point*>;
class IteratorEnd;
class Iterator {
public:
enum class Mode {
_0,
_1,
_2,
};
Iterator(const Points& points, int count);
Iterator& operator++() {
++mIdx;
return *this;
}
// FIXME: rename
void getData(sead::Vector3f* out, Mode mode) const;
sead::Vector3f getData(Mode mode) const;
const Point* getPoint() const { return mPoints[mIdx]; }
const Point* operator*() const { return getPoint(); }
friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
return lhs.mIdx == rhs.mIdx;
}
friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
return !operator==(lhs, rhs);
}
private:
friend class IteratorEnd;
int mIdx = 0;
const Point* const* mPoints = nullptr;
int mPointsNum = 0;
const Point* const* mPointsStart = nullptr;
};
class IteratorEnd {
public:
IteratorEnd(const Points& points, int count);
friend bool operator==(const Iterator& lhs, const IteratorEnd& rhs) {
return lhs.mIdx == rhs.mIdx;
}
friend bool operator==(const IteratorEnd& lhs, const Iterator& rhs) {
return lhs.mIdx == rhs.mIdx;
}
friend bool operator!=(const Iterator& lhs, const IteratorEnd& rhs) {
return !operator==(lhs, rhs);
}
friend bool operator!=(const IteratorEnd& lhs, const Iterator& rhs) {
return !operator==(lhs, rhs);
}
private:
int mIdx = 0;
const Point* const* mPoints = nullptr;
int mPointsNum = 0;
const Point* const* mPointsStart = nullptr;
};
static RigidContactPointsEx* make();
static void free(RigidContactPointsEx* instance);
@ -20,6 +111,9 @@ public:
bool registerLayerPair(ContactLayer layer1, ContactLayer layer2, bool enabled);
bool isPairUnknown(ContactLayer layer1, ContactLayer layer2) const;
auto begin() const { return Iterator(mPoints, _18); }
auto end() const { return IteratorEnd(mPoints, _18); }
private:
struct LayerEntry {
ContactLayer layer1;
@ -27,7 +121,7 @@ private:
bool enabled;
};
sead::Buffer<void*> mPoints{};
Points mPoints{};
sead::ObjArray<LayerEntry> mLayerEntries;
ContactLayerType mLayerType = ContactLayerType::Invalid;
void* _80 = nullptr;