A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
KColData.hh
1#pragma once
2
4
5#include <egg/math/BoundBox.hh>
6#include <egg/math/Matrix.hh>
7
8// Credit: em-eight/mkw
9// Credit: stblr/Hanachan
10
11namespace Kinoko::Field {
12
14 EGG::BoundBox3f bbox;
15 EGG::Vector3f tangentOff;
16
17 void update(const EGG::Vector3f &offset) {
18 bbox.min = bbox.min.minimize(offset);
19 bbox.max = bbox.max.maximize(offset);
20 }
21};
22
24 EGG::BoundBox3f bbox;
25 EGG::Vector3f tangentOff;
26 EGG::Vector3f floorNrm;
27 EGG::Vector3f wallNrm;
28 EGG::Vector3f roadVelocity;
29 f32 floorDist;
30 f32 wallDist;
31 f32 movingFloorDist;
32 f32 perpendicularity;
33
34 void updateFloor(f32 dist, const EGG::Vector3f &fnrm) {
35 if (dist > floorDist) {
36 floorDist = dist;
37 floorNrm = fnrm;
38 }
39 }
40
41 void updateWall(f32 dist, const EGG::Vector3f &fnrm) {
42 if (dist > wallDist) {
43 wallDist = dist;
44 wallNrm = fnrm;
45 }
46 }
47
48 void reset() {
49 bbox.setZero();
50 movingFloorDist = -std::numeric_limits<f32>::min();
51 wallDist = -std::numeric_limits<f32>::min();
52 floorDist = -std::numeric_limits<f32>::min();
53 perpendicularity = 0.0f;
54 }
55
56 void update(f32 now_dist, const EGG::Vector3f &offset, const EGG::Vector3f &fnrm,
57 u32 kclAttributeTypeBit);
58 void transformInfo(CollisionInfo &rhs, const EGG::Matrix34f &mtx, const EGG::Vector3f &v);
59};
60
63class KColData {
64public:
65 enum class CollisionCheckType {
66 Edge,
67 Plane,
68 Movement,
69 };
70
73 KCollisionPrism(f32 height, u16 posIndex, u16 faceNormIndex, u16 edge1NormIndex,
74 u16 edge2NormIndex, u16 edge3NormIndex, u16 attribute);
75
76 f32 height;
77 u16 pos_i;
78 u16 fnrm_i;
79 u16 enrm1_i;
80 u16 enrm2_i;
81 u16 enrm3_i;
82 u16 attribute;
83 };
84 STATIC_ASSERT(sizeof(KCollisionPrism) == 0x10);
85
86 KColData(const void *file);
87 ~KColData();
88
89 void narrowScopeLocal(const EGG::Vector3f &pos, f32 radius, KCLTypeMask mask);
90 void narrowPolygon_EachBlock(const u16 *prismArray);
91
92 void computeBBox();
93 [[nodiscard]] bool checkPointCollision(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
94 [[nodiscard]] bool checkSphereCollision(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
95 [[nodiscard]] bool checkSphere(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
96 [[nodiscard]] bool checkSphereSingle(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
97
98 void lookupPoint(const EGG::Vector3f &pos, const EGG::Vector3f &prevPos, KCLTypeMask typeMask);
99 void lookupSphere(f32 radius, const EGG::Vector3f &pos, const EGG::Vector3f &prevPos,
100 KCLTypeMask typeMask);
101 void lookupSphereCached(const EGG::Vector3f &p1, const EGG::Vector3f &p2, u32 typeMask,
102 f32 radius);
103
104 [[nodiscard]] const u16 *searchBlock(const EGG::Vector3f &pos);
105
107 [[nodiscard]] const EGG::BoundBox3f &bbox() const {
108 return m_bbox;
109 }
110
111 [[nodiscard]] u16 prismCache(u32 idx) const {
112 return m_prismCache[idx];
113 }
114
115 [[nodiscard]] std::span<const KCollisionPrism> prisms() const {
116 return m_prisms.view();
117 }
118
119 [[nodiscard]] std::span<const EGG::Vector3f> nrms() const {
120 return m_nrms.view();
121 }
122
123 [[nodiscard]] std::span<const EGG::Vector3f> vertices() const {
124 return m_vertices.view();
125 }
127
128 [[nodiscard]] static EGG::Vector3f GetVertex(f32 height, const EGG::Vector3f &vertex1,
129 const EGG::Vector3f &fnrm, const EGG::Vector3f &enrm3, const EGG::Vector3f &enrm);
130
131private:
132 void preloadPrisms();
133 void preloadNormals();
134 void preloadVertices();
135
136 template <CollisionCheckType Type>
137 [[nodiscard]] bool checkCollision(const KCollisionPrism &prism, f32 *distOut,
138 EGG::Vector3f *fnrmOut, u16 *flagsOut);
139
140 [[nodiscard]] bool checkPointCollision(const KCollisionPrism &prism, f32 *distOut,
141 EGG::Vector3f *fnrmOut, u16 *flagsOut, bool movement);
142 [[nodiscard]] bool checkSphereMovement(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut);
143 [[nodiscard]] bool checkPointMovement(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut);
144 [[nodiscard]] bool checkPoint(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut);
145
146 const void *m_posData;
147 const void *m_nrmData;
148 const void *m_prismData;
149 const void *m_blockData;
150 f32 m_prismThickness;
151 EGG::Vector3f m_areaMinPos;
159 EGG::Vector3f m_pos;
160 EGG::Vector3f m_prevPos;
161 EGG::Vector3f m_movement;
162 f32 m_radius;
163 KCLTypeMask m_typeMask;
164 const u16 *m_prismIter;
165 EGG::BoundBox3f m_bbox;
166 std::array<u16, 256> m_prismCache;
167 u16 *m_prismCacheTop;
168 u16 *m_cachedPrismArray;
169 EGG::Vector3f m_cachedPos;
170 f32 m_cachedRadius;
171
177};
178
179} // namespace Kinoko::Field
A 3 x 4 matrix.
Definition Matrix.hh:10
Performs lookups for KCL triangles.
Definition KColData.hh:63
void narrowPolygon_EachBlock(const u16 *prismArray)
Definition KColData.cc:75
owning_span< KCollisionPrism > m_prisms
Optimizes for time by avoiding unnecessary byteswapping. The Wii doesn't have this problem because bi...
Definition KColData.hh:174
void lookupSphere(f32 radius, const EGG::Vector3f &pos, const EGG::Vector3f &prevPos, KCLTypeMask typeMask)
Sets members in preparation of a subsequent sphere collision check call.
Definition KColData.cc:196
u32 m_areaYWidthMask
The y dimension of the octree's bounding box.
Definition KColData.hh:153
const u16 * searchBlock(const EGG::Vector3f &pos)
Finds the data block corresponding to the provided position.
Definition KColData.cc:230
bool checkSphere(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut)
Iterates the list of looked-up triangles to see if we are colliding.
Definition KColData.cc:134
u32 m_areaXWidthMask
The x dimension of the octree's bounding box.
Definition KColData.hh:152
void preloadNormals()
Creates a copy of the normals in memory.
Definition KColData.cc:327
bool checkSphereMovement(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut)
Iterates the local data block to check for directional collision.
Definition KColData.cc:612
static EGG::Vector3f GetVertex(f32 height, const EGG::Vector3f &vertex1, const EGG::Vector3f &fnrm, const EGG::Vector3f &enrm3, const EGG::Vector3f &enrm)
Computes a prism vertex based off of the triangle's normal vectors.
Definition KColData.cc:288
u32 m_areaXBlocksShift
Used to initialize octree navigation.
Definition KColData.hh:156
u32 m_blockWidthShift
Used to initialize octree navigation.
Definition KColData.hh:155
f32 m_sphereRadius
Clamps the sphere we check collision against.
Definition KColData.hh:158
void preloadPrisms()
Creates a copy of the prisms in memory.
Definition KColData.cc:300
void lookupPoint(const EGG::Vector3f &pos, const EGG::Vector3f &prevPos, KCLTypeMask typeMask)
Sets members in preparation of a subsequent point collision check call.
Definition KColData.cc:185
void computeBBox()
Calculates a EGG::BoundBox3f that describes the boundary of the track's KCL.
Definition KColData.cc:92
void preloadVertices()
Creates a copy of the vertices in memory.
Definition KColData.cc:343
u32 m_areaZWidthMask
The z dimension of the octree's bounding box.
Definition KColData.hh:154
u32 m_areaXYBlocksShift
Used to initialize octree navigation.
Definition KColData.hh:157
bool checkCollision(const KCollisionPrism &prism, f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut)
This is a combination of the three collision checks in the base game.
Definition KColData.cc:362
A contiguous storage container that manages the lifecycle of a buffer of a given size.
Definition Types.hh:29
Pertains to collision.
A representation of a bounding cuboid.
Definition BoundBox.hh:37
A 3D float vector.
Definition Vector.hh:107
constexpr Vector3f minimize(const Vector3f &rhs) const
Returns a vector whose elements are the min of the elements of both vectors.
Definition Vector.hh:327
constexpr Vector3f maximize(const Vector3f &rhs) const
Returns a vector whose elements are the max of the elements of both vectors.
Definition Vector.hh:315