A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectBase.cc
1#include "ObjectBase.hh"
2
3#include "game/field/ObjectDirector.hh"
4
5#include "game/system/CourseMap.hh"
6#include "game/system/ResourceManager.hh"
7#include "game/system/map/MapdataPointInfo.hh"
8
9#include <egg/math/Math.hh>
10
11#include <cstring>
12
13namespace Field {
14
16ObjectBase::ObjectBase(const System::MapdataGeoObj &params)
17 : m_drawMdl(nullptr), m_resFile(nullptr), m_id(static_cast<ObjectId>(params.id())),
18 m_pos(params.pos()), m_rot(params.rot() * DEG2RAD), m_scale(params.scale()),
19 m_transform(EGG::Matrix34f::ident), m_mapObj(&params) {
20 m_flags.setBit(eFlags::Position, eFlags::Rotation, eFlags::Scale);
21}
22
24ObjectBase::ObjectBase(const char *name, const EGG::Vector3f &pos, const EGG::Vector3f &rot,
25 const EGG::Vector3f &scale)
26 : m_drawMdl(nullptr), m_resFile(nullptr), m_pos(pos), m_rot(rot), m_scale(scale),
27 m_transform(EGG::Matrix34f::ident), m_mapObj(nullptr) {
28 m_flags.setBit(eFlags::Position, eFlags::Rotation, eFlags::Scale);
29 m_id = ObjectDirector::Instance()->flowTable().getIdFromName(name);
30}
31
33ObjectBase::~ObjectBase() {
34 delete m_resFile;
35 delete m_drawMdl;
36}
37
39void ObjectBase::calcModel() {
40 calcTransform();
41}
42
44const char *ObjectBase::getResources() const {
45 const auto &flowTable = ObjectDirector::Instance()->flowTable();
46 const auto *collisionSet = flowTable.set(flowTable.slot(m_id));
47 ASSERT(collisionSet);
48 return collisionSet->resources;
49}
50
52void ObjectBase::loadGraphics() {
53 const char *name = getResources();
54 if (strcmp(name, "-") == 0) {
55 return;
56 }
57
58 char filename[128];
59 snprintf(filename, sizeof(filename), "%s.brres", name);
60
61 auto *resMgr = System::ResourceManager::Instance();
62 const void *resFile = resMgr->getFile(filename, nullptr, System::ArchiveId::Course);
63 if (resFile) {
64 m_resFile = new Abstract::g3d::ResFile(resFile);
65 m_drawMdl = new Render::DrawMdl;
66 }
67}
68
70void ObjectBase::loadRail() {
71 if (!m_mapObj) {
72 return;
73 }
74
75 s16 pathId = m_mapObj->pathId();
76
77 if (pathId == -1) {
78 return;
79 }
80
81 auto *point = System::CourseMap::Instance()->getPointInfo(pathId);
82 f32 speed = static_cast<f32>(m_mapObj->setting(0));
83
84 if (point->setting(0) == 0) {
85 m_railInterpolator = new RailLinearInterpolator(speed, pathId);
86 } else {
87 m_railInterpolator = new RailSmoothInterpolator(speed, pathId);
88 }
89}
90
92[[nodiscard]] const char *ObjectBase::getName() const {
93 const auto &flowTable = ObjectDirector::Instance()->flowTable();
94 const auto *collisionSet = flowTable.set(flowTable.slot(id()));
95 ASSERT(collisionSet);
96 return collisionSet->name;
97}
98
100const char *ObjectBase::getKclName() const {
101 const auto &flowTable = ObjectDirector::Instance()->flowTable();
102 const auto *collisionSet = flowTable.set(flowTable.slot(id()));
103 ASSERT(collisionSet);
104 return collisionSet->resources;
105}
106
108void ObjectBase::calcTransform() {
109 if (m_flags.onBit(eFlags::Rotation)) {
110 m_transform.makeRT(m_rot, m_pos);
111 m_flags.resetBit(eFlags::Rotation, eFlags::Position);
112 } else if (m_flags.onBit(eFlags::Position)) {
113 m_transform.setBase(3, m_pos);
114 m_flags.setBit(eFlags::Matrix);
115 }
116}
117
119void ObjectBase::linkAnims(const std::span<const char *> &names,
120 const std::span<Render::AnmType> types) {
121 if (!m_drawMdl) {
122 return;
123 }
124
125 ASSERT(names.size() == types.size());
126
127 for (size_t i = 0; i < names.size(); ++i) {
128 m_drawMdl->linkAnims(i, m_resFile, names[i], types[i]);
129 }
130}
131
133void ObjectBase::setMatrixTangentTo(const EGG::Vector3f &up, const EGG::Vector3f &tangent) {
134 m_flags.setBit(eFlags::Matrix);
135 SetRotTangentHorizontal(m_transform, up, tangent);
136 m_transform.setBase(3, m_pos);
137}
138
141f32 ObjectBase::CheckPointAgainstLineSegment(const EGG::Vector3f &point, const EGG::Vector3f &a,
142 const EGG::Vector3f &b) {
143 return (b.x - a.x) * (point.z - a.z) - (point.x - a.x) * (b.z - a.z);
144}
145
148EGG::Vector3f ObjectBase::RotateXZByYaw(f32 angle, const EGG::Vector3f &v) {
149 f32 y = EGG::Mathf::SinFIdx(RAD2FIDX * (0.5f * angle));
150 f32 w = EGG::Mathf::CosFIdx(RAD2FIDX * (0.5f * angle));
151 EGG::Quatf quat = EGG::Quatf(w, 0.0f, y, 0.0f);
152 return quat.rotateVector(EGG::Vector3f(v.x, 0.0f, v.z));
153}
154
156EGG::Vector3f ObjectBase::RotateAxisAngle(f32 angle, const EGG::Vector3f &axis,
157 const EGG::Vector3f &v1) {
158 EGG::Matrix34f mat;
159 mat.setBase(3, EGG::Vector3f::zero);
160 mat.setAxisRotation(angle, axis);
161 return mat.ps_multVector(v1);
162}
163
165void ObjectBase::SetRotTangentHorizontal(EGG::Matrix34f &mat, const EGG::Vector3f &up,
166 const EGG::Vector3f &tangent) {
167 EGG::Vector3f vec = tangent - up * tangent.dot(up);
168 vec.normalise2();
169
170 mat.setBase(0, up.cross(vec));
171 mat.setBase(1, up);
172 mat.setBase(2, vec);
173}
174
176EGG::Matrix34f ObjectBase::OrthonormalBasis(const EGG::Vector3f &v) {
177 EGG::Vector3f z = v;
178
179 if (EGG::Mathf::abs(z.y) < 0.001f) {
180 z.y = 0.001f;
181 }
182
183 EGG::Vector3f h = EGG::Vector3f(v.x, 0.0f, v.z);
184 h.normalise2();
185
186 EGG::Vector3f x = (z.y > 0.0f) ? -h.cross(z) : h.cross(z);
187 x.normalise2();
188
189 EGG::Matrix34f mat;
190 mat.setBase(3, EGG::Vector3f::zero);
191 mat.setBase(0, x);
192 mat.setBase(1, z.cross(x));
193 mat.setBase(2, z);
194
195 return mat;
196}
197
199EGG::Matrix34f ObjectBase::RailOrthonormalBasis(const RailInterpolator &railInterpolator) {
200 EGG::Matrix34f mat = OrthonormalBasis(railInterpolator.curTangentDir());
201 mat.setBase(3, railInterpolator.curPos());
202 return mat;
203}
204
205} // namespace Field
Represents a binary resource file which contains object models, textures, and animations.
Definition ResFile.hh:15
A 3 x 4 matrix.
Definition Matrix.hh:8
void setBase(size_t col, const Vector3f &base)
Sets one column of a matrix.
Definition Matrix.cc:181
void setAxisRotation(f32 angle, const Vector3f &axis)
Rotates the matrix about an axis.
Definition Matrix.cc:167
Vector3f ps_multVector(const Vector3f &vec) const
Paired-singles impl. of multVector.
Definition Matrix.cc:224
EGG core library.
Definition Archive.cc:6
Pertains to collision.
A quaternion, used to represent 3D rotation.
Definition Quat.hh:12
Vector3f rotateVector(const Vector3f &vec) const
Rotates a vector based on the quat.
Definition Quat.cc:55
A 3D float vector.
Definition Vector.hh:87
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
Definition Vector.hh:186