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().getIdfFromName(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
140EGG::Vector3f ObjectBase::RotateAxisAngle(f32 angle, const EGG::Vector3f &axis,
141 const EGG::Vector3f &v1) {
142 EGG::Matrix34f mat;
143 mat.setBase(3, EGG::Vector3f::zero);
144 mat.setAxisRotation(angle, axis);
145 return mat.ps_multVector(v1);
146}
147
149void ObjectBase::SetRotTangentHorizontal(EGG::Matrix34f &mat, const EGG::Vector3f &up,
150 const EGG::Vector3f &tangent) {
151 EGG::Vector3f vec = tangent - up * tangent.dot(up);
152 vec.normalise2();
153
154 mat.setBase(0, up.cross(vec));
155 mat.setBase(1, up);
156 mat.setBase(2, vec);
157}
158
160EGG::Matrix34f ObjectBase::OrthonormalBasis(const EGG::Vector3f &v) {
161 EGG::Vector3f z = v;
162
163 if (EGG::Mathf::abs(z.y) < 0.001f) {
164 z.y = 0.001f;
165 }
166
167 EGG::Vector3f h = EGG::Vector3f(v.x, 0.0f, v.z);
168 h.normalise2();
169
170 EGG::Vector3f x = (z.y > 0.0f) ? -h.cross(z) : h.cross(z);
171 x.normalise2();
172
173 EGG::Matrix34f mat;
174 mat.setBase(3, EGG::Vector3f::zero);
175 mat.setBase(0, x);
176 mat.setBase(1, z.cross(x));
177 mat.setBase(2, z);
178
179 return mat;
180}
181
182} // 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 3D float vector.
Definition Vector.hh:87
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
Definition Vector.hh:186