1#include "ObjectBase.hh"
3#include "game/field/ObjectDirector.hh"
5#include "game/system/CourseMap.hh"
6#include "game/system/ResourceManager.hh"
7#include "game/system/map/MapdataPointInfo.hh"
9#include <egg/math/Math.hh>
16ObjectBase::ObjectBase(
const System::MapdataGeoObj ¶ms)
17 : m_drawMdl(nullptr), m_resFile(nullptr), m_id(static_cast<ObjectId>(params.id())),
18 m_railInterpolator(nullptr), m_mapObj(¶ms), m_pos(params.pos()), m_scale(params.scale()),
19 m_rot(params.rot() * DEG2RAD), m_rotLock(true), m_transform(EGG::Matrix34f::ident) {
20 m_flags.setBit(eFlags::Position, eFlags::Rotation, eFlags::Scale);
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_railInterpolator(nullptr), m_mapObj(nullptr),
27 m_pos(pos), m_scale(scale), m_rot(rot), m_rotLock(true), m_transform(EGG::Matrix34f::ident) {
28 m_flags.setBit(eFlags::Position, eFlags::Rotation, eFlags::Scale);
29 m_id = ObjectDirector::Instance()->flowTable().getIdFromName(name);
33ObjectBase::~ObjectBase() {
36 delete m_railInterpolator;
40void ObjectBase::calcModel() {
45const char *ObjectBase::getResources()
const {
46 const auto &flowTable = ObjectDirector::Instance()->flowTable();
47 const auto *collisionSet = flowTable.set(flowTable.slot(
id()));
49 return collisionSet->resources;
53void ObjectBase::loadGraphics() {
54 const char *name = getResources();
55 if (strcmp(name,
"-") == 0) {
60 snprintf(filename,
sizeof(filename),
"%s.brres", name);
62 auto *resMgr = System::ResourceManager::Instance();
63 const void *resFile = resMgr->getFile(filename,
nullptr, System::ArchiveId::Course);
65 m_resFile =
new Abstract::g3d::ResFile(resFile);
66 m_drawMdl =
new Render::DrawMdl;
71void ObjectBase::loadRail() {
76 s16 pathId = m_mapObj->pathId();
82 auto *point = System::CourseMap::Instance()->getPointInfo(pathId);
83 f32 speed =
static_cast<f32
>(m_mapObj->setting(0));
85 if (point->setting(0) == 0) {
86 m_railInterpolator =
new RailLinearInterpolator(speed, pathId);
88 m_railInterpolator =
new RailSmoothInterpolator(speed, pathId);
93[[nodiscard]]
const char *ObjectBase::getName()
const {
94 const auto &flowTable = ObjectDirector::Instance()->flowTable();
95 const auto *collisionSet = flowTable.set(flowTable.slot(
id()));
97 return collisionSet->name;
101const char *ObjectBase::getKclName()
const {
102 const auto &flowTable = ObjectDirector::Instance()->flowTable();
103 const auto *collisionSet = flowTable.set(flowTable.slot(
id()));
104 ASSERT(collisionSet);
105 return collisionSet->resources;
109void ObjectBase::calcTransform() {
110 if (m_flags.onBit(eFlags::Rotation)) {
111 m_transform.makeRT(m_rot, m_pos);
112 m_flags.resetBit(eFlags::Rotation, eFlags::Position);
113 }
else if (m_flags.onBit(eFlags::Position)) {
114 m_transform.setBase(3, m_pos);
115 m_flags.setBit(eFlags::Matrix);
119void ObjectBase::calcRotLock() {
122 m_rot = m_transform.calcRPY();
127void ObjectBase::linkAnims(
const std::span<const char *> &names,
128 const std::span<Render::AnmType> types) {
133 ASSERT(names.size() == types.size());
135 for (
size_t i = 0; i < names.size(); ++i) {
136 m_drawMdl->linkAnims(i, m_resFile, names[i], types[i]);
141void ObjectBase::setMatrixTangentTo(
const EGG::Vector3f &up,
const EGG::Vector3f &tangent) {
143 m_flags.setBit(eFlags::Matrix);
144 SetRotTangentHorizontal(m_transform, up, tangent);
145 m_transform.setBase(3, m_pos);
149void ObjectBase::setMatrixFromOrthonormalBasisAndPos(
const EGG::Vector3f &v) {
150 m_flags.setBit(eFlags::Matrix);
151 m_transform = OrthonormalBasis(v);
152 m_transform.setBase(3, m_pos);
159 return (b.x - a.x) * (point.z - a.z) - (point.x - a.x) * (b.z - a.z);
165 f32 y = EGG::Mathf::SinFIdx(RAD2FIDX * (0.5f * angle));
166 f32 w = EGG::Mathf::CosFIdx(RAD2FIDX * (0.5f * angle));
175 mat.
setBase(3, EGG::Vector3f::zero);
192EGG::Matrix34f ObjectBase::OrthonormalBasis(
const EGG::Vector3f &v) {
195 if (EGG::Mathf::abs(z.y) < 0.001f) {
199 EGG::Vector3f h = EGG::Vector3f(v.x, 0.0f, v.z);
202 EGG::Vector3f x = (z.y > 0.0f) ? -h.cross(z) : h.cross(z);
206 mat.
setBase(3, EGG::Vector3f::zero);
208 mat.setBase(1, z.cross(x));
215EGG::Matrix34f ObjectBase::RailOrthonormalBasis(
const RailInterpolator &railInterpolator) {
216 EGG::Matrix34f mat = OrthonormalBasis(railInterpolator.curTangentDir());
217 mat.setBase(3, railInterpolator.curPos());
222EGG::Vector3f ObjectBase::AdjustVecForward(f32 sidewaysScalar, f32 forwardScalar, f32 minSpeed,
223 const EGG::Vector3f &src, EGG::Vector3f forward) {
224 if (forward.y > 0.0f) {
226 auto [mag, tmp] = forward.ps_normalized();
235 EGG::Vector3f proj = forward * src.ps_dot(forward);
236 EGG::Vector3f sideways = (src - proj) * sidewaysScalar;
238 EGG::Vector3f newForward = proj * -forwardScalar;
239 if (newForward.squaredLength() < minSpeed * minSpeed) {
240 newForward = forward * minSpeed;
243 return sideways + newForward;
constexpr void setAxisRotation(f32 angle, const EGG::Vector3f &axis)
Rotates the matrix about an axis.
constexpr Vector3f ps_multVector(const Vector3f &vec) const
Paired-singles impl. of multVector.
constexpr void setBase(size_t col, const Vector3f &base)
Sets one column of a matrix.
static f32 CheckPointAgainstLineSegment(const EGG::Vector3f &point, const EGG::Vector3f &a, const EGG::Vector3f &b)
Calculates on what side of line segment ab point lies.
static EGG::Vector3f RotateXZByYaw(f32 angle, const EGG::Vector3f &v)
Rotates a vector around the Y-axis and returns the XZ-plane portion of the vector.
A quaternion, used to represent 3D rotation.
constexpr Vector3f rotateVector(const Vector3f &vec) const
Rotates a vector based on the quat.
constexpr f32 dot(const Vector3f &rhs) const
The dot product between two vectors.