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 Field {
12
14 EGG::BoundBox3f bbox;
15 EGG::Vector3f tangentOff;
16};
17
19 EGG::BoundBox3f bbox;
20 EGG::Vector3f tangentOff;
21 EGG::Vector3f floorNrm;
22 EGG::Vector3f wallNrm;
23 EGG::Vector3f roadVelocity;
24 f32 floorDist;
25 f32 wallDist;
26 f32 movingFloorDist;
27 f32 perpendicularity;
28
29 void updateFloor(f32 dist, const EGG::Vector3f &fnrm) {
30 if (dist > floorDist) {
31 floorDist = dist;
32 floorNrm = fnrm;
33 }
34 }
35
36 void updateWall(f32 dist, const EGG::Vector3f &fnrm) {
37 if (dist > wallDist) {
38 wallDist = dist;
39 wallNrm = fnrm;
40 }
41 }
42
43 void reset() {
44 bbox.setZero();
45 movingFloorDist = -std::numeric_limits<f32>::min();
46 wallDist = -std::numeric_limits<f32>::min();
47 floorDist = -std::numeric_limits<f32>::min();
48 perpendicularity = 0.0f;
49 }
50
51 void update(f32 now_dist, const EGG::Vector3f &offset, const EGG::Vector3f &fnrm,
52 u32 kclAttributeTypeBit);
53 void transformInfo(CollisionInfo &rhs, const EGG::Matrix34f &mtx, const EGG::Vector3f &v);
54};
55
58class KColData {
59public:
60 enum class CollisionCheckType {
61 Edge,
62 Plane,
63 Movement,
64 };
65
68 KCollisionPrism(f32 height, u16 posIndex, u16 faceNormIndex, u16 edge1NormIndex,
69 u16 edge2NormIndex, u16 edge3NormIndex, u16 attribute);
70
71 f32 height;
72 u16 pos_i;
73 u16 fnrm_i;
74 u16 enrm1_i;
75 u16 enrm2_i;
76 u16 enrm3_i;
77 u16 attribute;
78 };
79 STATIC_ASSERT(sizeof(KCollisionPrism) == 0x10);
80
81 KColData(const void *file);
82 ~KColData();
83
84 void narrowScopeLocal(const EGG::Vector3f &pos, f32 radius, KCLTypeMask mask);
85 void narrowPolygon_EachBlock(const u16 *prismArray);
86
87 void computeBBox();
88 [[nodiscard]] bool checkPointCollision(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
89 [[nodiscard]] bool checkSphereCollision(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
90 [[nodiscard]] bool checkSphere(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
91 [[nodiscard]] bool checkSphereSingle(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut);
92
93 void lookupPoint(const EGG::Vector3f &pos, const EGG::Vector3f &prevPos, KCLTypeMask typeMask);
94 void lookupSphere(f32 radius, const EGG::Vector3f &pos, const EGG::Vector3f &prevPos,
95 KCLTypeMask typeMask);
96 void lookupSphereCached(const EGG::Vector3f &p1, const EGG::Vector3f &p2, u32 typeMask,
97 f32 radius);
98
99 [[nodiscard]] const u16 *searchBlock(const EGG::Vector3f &pos);
100
102 [[nodiscard]] const EGG::BoundBox3f &bbox() const {
103 return m_bbox;
104 }
105
106 [[nodiscard]] u16 prismCache(u32 idx) const {
107 return m_prismCache[idx];
108 }
110
111 [[nodiscard]] static EGG::Vector3f GetVertex(f32 height, const EGG::Vector3f &vertex1,
112 const EGG::Vector3f &fnrm, const EGG::Vector3f &enrm3, const EGG::Vector3f &enrm);
113
114private:
115 void preloadPrisms();
116 void preloadNormals();
117 void preloadVertices();
118
119 [[nodiscard]] bool checkCollision(const KCollisionPrism &prism, f32 *distOut,
120 EGG::Vector3f *fnrmOut, u16 *flagsOut, CollisionCheckType type);
121 [[nodiscard]] bool checkPointCollision(const KCollisionPrism &prism, f32 *distOut,
122 EGG::Vector3f *fnrmOut, u16 *flagsOut, bool movement);
123 [[nodiscard]] bool checkSphereMovement(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut);
124 [[nodiscard]] bool checkPointMovement(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut);
125 [[nodiscard]] bool checkPoint(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut);
126
127 const void *m_posData;
128 const void *m_nrmData;
129 const void *m_prismData;
130 const void *m_blockData;
131 f32 m_prismThickness;
132 EGG::Vector3f m_areaMinPos;
140 EGG::Vector3f m_pos;
141 EGG::Vector3f m_prevPos;
142 EGG::Vector3f m_movement;
143 f32 m_radius;
144 KCLTypeMask m_typeMask;
145 const u16 *m_prismIter;
146 EGG::BoundBox3f m_bbox;
147 std::array<u16, 256> m_prismCache;
148 u16 *m_prismCacheTop;
149 u16 *m_cachedPrismArray;
150 EGG::Vector3f m_cachedPos;
151 f32 m_cachedRadius;
152
155 std::span<KCollisionPrism> m_prisms;
156 std::span<EGG::Vector3f> m_nrms;
157 std::span<EGG::Vector3f> m_vertices;
158};
159
160} // namespace Field
A 3 x 4 matrix.
Definition Matrix.hh:8
Performs lookups for KCL triangles.
Definition KColData.hh:58
void preloadNormals()
Creates a copy of the normals in memory.
Definition KColData.cc:331
void preloadVertices()
Creates a copy of the vertices in memory.
Definition KColData.cc:347
bool checkSphereMovement(f32 *distOut, EGG::Vector3f *fnrmOut, u16 *attributeOut)
Iterates the local data block to check for directional collision.
Definition KColData.cc:615
u32 m_areaYWidthMask
The y dimension of the octree's bounding box.
Definition KColData.hh:134
u32 m_areaZWidthMask
The z dimension of the octree's bounding box.
Definition KColData.hh:135
f32 m_sphereRadius
Clamps the sphere we check collision against.
Definition KColData.hh:139
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:292
void preloadPrisms()
Creates a copy of the prisms in memory.
Definition KColData.cc:304
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:138
void computeBBox()
Calculates a EGG::BoundBox3f that describes the boundary of the track's KCL.
Definition KColData.cc:96
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:189
u32 m_areaXWidthMask
The x dimension of the octree's bounding box.
Definition KColData.hh:133
const u16 * searchBlock(const EGG::Vector3f &pos)
Finds the data block corresponding to the provided position.
Definition KColData.cc:234
u32 m_blockWidthShift
Used to initialize octree navigation.
Definition KColData.hh:136
u32 m_areaXYBlocksShift
Used to initialize octree navigation.
Definition KColData.hh:138
void narrowPolygon_EachBlock(const u16 *prismArray)
Definition KColData.cc:79
u32 m_areaXBlocksShift
Used to initialize octree navigation.
Definition KColData.hh:137
std::span< KCollisionPrism > m_prisms
Optimizes for time by avoiding unnecessary byteswapping. The Wii doesn't have this problem because bi...
Definition KColData.hh:155
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:200
bool checkCollision(const KCollisionPrism &prism, f32 *distOut, EGG::Vector3f *fnrmOut, u16 *flagsOut, CollisionCheckType type)
This is a combination of the three collision checks in the base game.
Definition KColData.cc:365
Pertains to collision.
A representation of a bounding cuboid.
Definition BoundBox.hh:30
A 3D float vector.
Definition Vector.hh:83