1#include "MapdataArea.hh"
3#include "game/system/CourseMap.hh"
8MapdataAreaBase::MapdataAreaBase(
const SData *data, s16 index) : m_rawData(data), m_index(index) {
10 CourseMap::Instance()->version() > 2200 ?
sizeof(SData) :
sizeof(SData) - 4);
13 m_sqBoundingSphereRadius = 0.0f;
14 m_ellipseAspectRatio = 0.0f;
15 m_ellipseRadiusSq = 0.0f;
16 m_dimensions = EGG::Vector3f::zero;
17 m_right = EGG::Vector3f::zero;
18 m_up = EGG::Vector3f::zero;
19 m_forward = EGG::Vector3f::zero;
24 m_type =
static_cast<Type
>(stream.read_s8());
26 m_priority = stream.read_u8();
27 m_position.read(stream);
28 m_rotation.read(stream);
31 for (
auto ¶m : m_params) {
32 param = stream.read_s16();
35 if (CourseMap::Instance()->version() > 2200) {
36 m_railId = stream.read_s8();
41MapdataPointInfo *MapdataAreaBase::getPointInfo()
const {
43 auto *courseMap = CourseMap::Instance();
44 if (courseMap->version() < 2200) {
48 return courseMap->getPointInfo(m_railId);
52MapdataAreaBox::MapdataAreaBox(
const SData *data, s16 index) : MapdataAreaBase(data, index) {
53 m_dimensions.x = 0.5f * (10000.0f * m_scale.x);
54 m_dimensions.y = 10000.0f * m_scale.y;
55 m_dimensions.z = 0.5f * (10000.0f * m_scale.z);
57 m_ellipseAspectRatio = 0.0f;
58 m_ellipseRadiusSq = 0.0f;
59 m_sqBoundingSphereRadius = m_dimensions.squaredLength();
61 EGG::Quatf rotation = EGG::Quatf::FromRPY(DEG2RAD * m_rotation.x, DEG2RAD * m_rotation.y,
62 DEG2RAD * m_rotation.z);
70bool MapdataAreaBox::testImpl(
const EGG::Vector3f &pos)
const {
73 f32 u = relPos.
dot(m_up);
74 if (u > m_dimensions.y || u < 0.0f) {
78 f32 r = relPos.
dot(m_right);
79 if (r > m_dimensions.x || r < -m_dimensions.x) {
83 f32 f = relPos.
dot(m_forward);
84 if (f > m_dimensions.z || f < -m_dimensions.z) {
92MapdataAreaCylinder::MapdataAreaCylinder(
const SData *data, s16 index)
93 : MapdataAreaBase(data, index) {
94 m_dimensions = m_scale * 5000.0f;
95 m_ellipseRadiusSq = m_dimensions.x * m_dimensions.x;
96 m_sqBoundingSphereRadius = m_dimensions.x * m_dimensions.x + m_dimensions.z * m_dimensions.z;
97 m_ellipseAspectRatio = m_scale.x / m_scale.z;
99 EGG::Quatf rotation = EGG::Quatf::FromRPY(DEG2RAD * m_rotation.x, DEG2RAD * m_rotation.y,
100 DEG2RAD * m_rotation.z);
108bool MapdataAreaCylinder::testImpl(
const EGG::Vector3f &pos)
const {
111 if (relPos.
dot(m_up) > m_dimensions.y) {
115 f32 f = m_ellipseAspectRatio * relPos.
dot(m_forward);
116 f32 r = relPos.
dot(m_right);
117 if (r * r + f * f < m_ellipseRadiusSq) {
125MapdataAreaAccessor::MapdataAreaAccessor(
const MapSectionHeader *header)
126 : MapdataAccessorBase<MapdataAreaBase, MapdataAreaBase::SData>(header) {
127 init(
reinterpret_cast<const MapdataAreaBase::SData *
>(m_sectionHeader + 1),
128 parse<u16>(m_sectionHeader->count));
131 std::span<MapdataAreaBase *>(
new MapdataAreaBase *[m_entryCount], m_entryCount);
135MapdataAreaAccessor::~MapdataAreaAccessor() {
136 delete m_sortedEntries.data();
139void MapdataAreaAccessor::init(
const MapdataAreaBase::SData *start,
u16 count) {
141 m_entryCount = count;
142 m_entries =
new MapdataAreaBase *[count];
145 for (
u16 i = 0; i < count; ++i) {
147 const MapdataAreaBase::SData *data = CourseMap::Instance()->version() > 2200 ?
149 reinterpret_cast<const MapdataAreaBase::SData *
>(
150 reinterpret_cast<uintptr_t
>(start) +
151 i * (
sizeof(MapdataAreaBase::SData) - 4));
154 MapdataAreaBase::Shape shape =
static_cast<MapdataAreaBase::Shape
>(data->shape);
157 case MapdataAreaBase::Shape::Box:
158 m_entries[i] =
new MapdataAreaBox(data, i);
160 case MapdataAreaBase::Shape::Cylinder:
161 m_entries[i] =
new MapdataAreaCylinder(data, i);
164 PANIC(
"Invalid area shape!");
171void MapdataAreaAccessor::sort() {
172 for (
size_t i = 0; i < m_entryCount; ++i) {
173 m_sortedEntries[i] = get(i);
176 for (
size_t i = 1; i < m_entryCount; ++i) {
178 for (; j > 0 && m_sortedEntries[j - 1]->priority() < m_sortedEntries[i]->priority(); --j) {
179 m_sortedEntries[j] = m_sortedEntries[j - 1];
A stream of data stored in memory.
A stream of data, abstracted to allow for continuous seeking.
High-level handling for generic system operations, such as input reading, race configuration,...
A quaternion, used to represent 3D rotation.
Vector3f rotateVector(const Vector3f &vec) const
Rotates a vector based on the quat.
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.