3#include "game/system/RaceManager.hh"
4#include "game/system/ResourceManager.hh"
6#include <egg/math/Math.hh>
11ObjectKCL::ObjectKCL(
const System::MapdataGeoObj ¶ms)
12 :
ObjectDrivable(params), m_lastMtxUpdateFrame(-2000), m_lastScaleUpdateFrame(-2000) {}
15ObjectKCL::~ObjectKCL() {
16 EGG::egg_delete(m_objColMgr);
20void ObjectKCL::createCollision() {
22 snprintf(filepath,
sizeof(filepath),
"%s.kcl", getKclName());
24 auto *resMgr = System::ResourceManager::Instance();
26 EGG::egg_new<ObjColMgr>(resMgr->getFile(filepath,
nullptr, System::ArchiveId::Course));
30void ObjectKCL::calcCollisionTransform() {
35void ObjectKCL::initCollision() {
36 const EGG::Matrix34f &mat = getUpdatedMatrix(0);
37 EGG::Matrix34f matInv;
38 bool inverted = mat.ps_inverse(matInv);
41 m_objColMgr->setMtx(mat);
42 m_objColMgr->setInvMtx(matInv);
43 m_objColMgr->setScale(getScaleY(0));
45 EGG::Vector3f high = m_objColMgr->kclHighWorld();
46 EGG::Vector3f low = m_objColMgr->kclLowWorld();
48 m_kclMidpoint = (high + low).multInv(2.0f);
50 EGG::Vector3f highLowDiffAbs = (high - low).abs();
51 f32 maxDiff = std::max(highLowDiffAbs.x, highLowDiffAbs.z);
52 m_bboxHalfSideLength = maxDiff * 0.5f;
56bool ObjectKCL::checkPointPartial(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
57 KCLTypeMask mask, CollisionInfoPartial *info, KCLTypeMask *maskOut) {
58 if (!shouldCheckColNoPush()) {
62 return m_objColMgr->checkPointPartial(pos, prevPos, mask, info, maskOut);
66bool ObjectKCL::checkPointPartialPush(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
67 KCLTypeMask mask, CollisionInfoPartial *info, KCLTypeMask *maskOut) {
68 if (!shouldCheckColPush()) {
72 return m_objColMgr->checkPointPartialPush(pos, prevPos, mask, info, maskOut);
76bool ObjectKCL::checkPointFull(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
77 KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut) {
78 if (!shouldCheckColNoPush()) {
82 return m_objColMgr->checkPointFull(pos, prevPos, mask, info, maskOut);
86bool ObjectKCL::checkPointFullPush(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
87 KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut) {
88 if (!shouldCheckColPush()) {
92 return m_objColMgr->checkPointFullPush(pos, prevPos, mask, info, maskOut);
96bool ObjectKCL::checkSpherePartial(f32 radius,
const EGG::Vector3f &pos,
97 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
98 KCLTypeMask *maskOut, u32 timeOffset) {
99 if (!shouldCheckColNoPush()) {
103 calcScale(timeOffset);
106 return m_objColMgr->checkSpherePartial(radius, pos, prevPos, mask, info, maskOut);
110bool ObjectKCL::checkSpherePartialPush(f32 radius,
const EGG::Vector3f &pos,
111 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
112 KCLTypeMask *maskOut, u32 timeOffset) {
113 if (!shouldCheckColPush()) {
117 calcScale(timeOffset);
120 return m_objColMgr->checkSpherePartialPush(radius, pos, prevPos, mask, info, maskOut);
124bool ObjectKCL::checkSphereFull(f32 radius,
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
125 KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut, u32 timeOffset) {
126 if (!shouldCheckColNoPush()) {
130 calcScale(timeOffset);
133 return m_objColMgr->checkSphereFull(radius, pos, prevPos, mask, info, maskOut);
137bool ObjectKCL::checkSphereFullPush(f32 radius,
const EGG::Vector3f &pos,
138 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut,
140 return checkCollision(radius, pos, prevPos, mask, info, maskOut, timeOffset);
144void ObjectKCL::narrScLocal(f32 radius,
const EGG::Vector3f &pos, KCLTypeMask mask,
146 m_objColMgr->narrScLocal(radius, pos, mask);
150bool ObjectKCL::checkPointCachedPartial(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
151 KCLTypeMask mask, CollisionInfoPartial *info, KCLTypeMask *maskOut) {
152 if (!shouldCheckColNoPush()) {
156 return m_objColMgr->checkPointCachedPartial(pos, prevPos, mask, info, maskOut);
160bool ObjectKCL::checkPointCachedPartialPush(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
161 KCLTypeMask mask, CollisionInfoPartial *info, KCLTypeMask *maskOut) {
162 if (!shouldCheckColPush()) {
166 return m_objColMgr->checkPointCachedPartialPush(pos, prevPos, mask, info, maskOut);
170bool ObjectKCL::checkPointCachedFull(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
171 KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut) {
172 if (!shouldCheckColNoPush()) {
176 return m_objColMgr->checkPointCachedFull(pos, prevPos, mask, info, maskOut);
180bool ObjectKCL::checkPointCachedFullPush(
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
181 KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut) {
182 if (!shouldCheckColPush()) {
186 return m_objColMgr->checkPointCachedFullPush(pos, prevPos, mask, info, maskOut);
190bool ObjectKCL::checkSphereCachedPartial(f32 radius,
const EGG::Vector3f &pos,
191 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
192 KCLTypeMask *maskOut, u32 timeOffset) {
193 if (!shouldCheckColNoPush()) {
198 calcScale(timeOffset);
200 return m_objColMgr->checkSphereCachedPartial(radius, pos, prevPos, mask, info, maskOut);
204bool ObjectKCL::checkSphereCachedPartialPush(f32 radius,
const EGG::Vector3f &pos,
205 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
206 KCLTypeMask *maskOut, u32 timeOffset) {
207 if (!shouldCheckColPush()) {
212 calcScale(timeOffset);
214 return m_objColMgr->checkSphereCachedPartialPush(radius, pos, prevPos, mask, info, maskOut);
218bool ObjectKCL::checkSphereCachedFull(f32 radius,
const EGG::Vector3f &pos,
219 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut,
221 if (!shouldCheckColNoPush()) {
226 calcScale(timeOffset);
228 return m_objColMgr->checkSphereCachedFull(radius, pos, prevPos, mask, info, maskOut);
232bool ObjectKCL::checkSphereCachedFullPush(f32 radius,
const EGG::Vector3f &pos,
233 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut,
235 return checkCollisionCached(radius, pos, prevPos, mask, info, maskOut, timeOffset);
239void ObjectKCL::update(u32 timeOffset) {
240 u32 time = System::RaceManager::Instance()->timer() - timeOffset;
241 if (m_lastMtxUpdateFrame ==
static_cast<s32
>(time)) {
247 if (timeOffset == 0) {
251 mat = getUpdatedMatrix(timeOffset);
254 EGG::Matrix34f matInv;
255 mat.ps_inverse(matInv);
256 m_objColMgr->setMtx(mat);
257 m_objColMgr->setInvMtx(matInv);
259 m_lastMtxUpdateFrame = time;
263void ObjectKCL::calcScale(u32 timeOffset) {
264 u32 time = System::RaceManager::Instance()->timer() - timeOffset;
265 if (m_lastScaleUpdateFrame ==
static_cast<s32
>(time)) {
270 m_objColMgr->setScale(scale().y);
272 m_objColMgr->setScale(getScaleY(timeOffset));
275 m_lastScaleUpdateFrame = time;
279bool ObjectKCL::checkCollision(f32 radius,
const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos,
280 KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut, u32 timeOffset) {
281 if (!shouldCheckColPush()) {
286 calcScale(timeOffset);
288 return m_objColMgr->checkSphereFullPush(radius, pos, prevPos, mask, info, maskOut);
292bool ObjectKCL::checkCollisionCached(f32 radius,
const EGG::Vector3f &pos,
293 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut,
295 if (!shouldCheckColPush()) {
300 calcScale(timeOffset);
302 return m_objColMgr->checkSphereCachedFullPush(radius, pos, prevPos, mask, info, maskOut);