From 7a31679c2d22ca0c638e89b660bb747ecc466dba Mon Sep 17 00:00:00 2001 From: MegaMech <7255464+MegaMech@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:31:24 -0700 Subject: [PATCH] Editor use vtx collision --- src/engine/Actor.h | 2 + src/engine/CoreMath.h | 26 +++++-- src/engine/World.cpp | 26 +++++-- src/engine/World.h | 2 +- src/engine/editor/Collision.cpp | 94 ++++++++++++++++++++++++++ src/engine/editor/Collision.h | 19 ++++++ src/engine/editor/Editor.cpp | 32 +++++++-- src/engine/editor/Editor.h | 14 ++-- src/engine/editor/EditorMath.cpp | 70 +++++++++++++++++-- src/engine/editor/EditorMath.h | 26 +++++++ src/engine/editor/Gizmo.cpp | 43 ++++++++---- src/engine/editor/Gizmo.h | 10 ++- src/engine/editor/ObjectPicker.cpp | 105 ++++++++++++++++++++--------- src/engine/editor/ObjectPicker.h | 15 +++-- src/port/Game.cpp | 7 +- src/port/Game.h | 7 +- src/racing/actors.c | 2 +- 17 files changed, 405 insertions(+), 95 deletions(-) create mode 100644 src/engine/editor/Collision.cpp create mode 100644 src/engine/editor/Collision.h diff --git a/src/engine/Actor.h b/src/engine/Actor.h index a74ed74e0..c7185874e 100644 --- a/src/engine/Actor.h +++ b/src/engine/Actor.h @@ -25,6 +25,8 @@ public: /* 0x30 */ Collision Unk30; uint8_t uuid[16]; + Gfx* Model = NULL; + virtual ~AActor() = default; // Virtual destructor for proper cleanup in derived classes explicit AActor(); diff --git a/src/engine/CoreMath.h b/src/engine/CoreMath.h index 81bb9e2ea..a21c095fe 100644 --- a/src/engine/CoreMath.h +++ b/src/engine/CoreMath.h @@ -15,13 +15,6 @@ struct FVector { float x, y, z; #ifdef __cplusplus - FVector& operator=(const FVector& other) { - x = other.x; - y = other.y; - z = other.z; - return *this; - } - // Operator to add two FVector objects FVector operator+(const FVector& other) const { return FVector(x + other.x, y + other.y, z + other.z); @@ -32,6 +25,25 @@ struct FVector { return FVector(x - other.x, y - other.y, z - other.z); } + float Dot(const FVector& other) const { + return x * other.x + y * other.y + z * other.z; + } + + FVector Cross(const FVector& other) const { + return FVector( + y * other.z - z * other.y, + z * other.x - x * other.z, + x * other.y - y * other.x + ); + } + + FVector Normalize() const { + float len = std::sqrt(x * x + y * y + z * z); + return FVector( + x / len, y / len, z / len + ); + } + FVector() : x(0), y(0), z(0) {} FVector(float x, float y, float z) : x(x), y(y), z(z) {} #endif // __cplusplus diff --git a/src/engine/World.cpp b/src/engine/World.cpp index a63c22b10..6f59f00cd 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -6,14 +6,16 @@ #include "TrainCrossing.h" #include #include "objects/Object.h" +#include "port/Game.h" extern "C" { - #include "camera.h" - #include "objects.h" - #include "main.h" - #include "defines.h" - #include "audio/external.h" - #include "menus.h" +#include "camera.h" +#include "objects.h" +#include "main.h" +#include "defines.h" +#include "audio/external.h" +#include "menus.h" +#include "common_data.h" } World::World() {} @@ -112,11 +114,21 @@ void World::PreviousCourse() { AActor* World::AddActor(AActor* actor) { Actors.push_back(actor); + + gEditor.AddObject((FVector*) &actor->Pos, actor->Model, CollisionType::VTX_INTERSECT, 0.0f); + return Actors.back(); } -struct Actor* World::AddBaseActor() { +struct Actor* World::AddBaseActor(s16 actorType) { Actors.push_back(new AActor()); + + AActor* actor = Actors.back(); + if (actorType == ACTOR_ITEM_BOX) { + printf("ADD ITEM BOX\n"); + actor->Model = (Gfx*)LOAD_ASSET_RAW(itemBoxQuestionMarkModel); + } + gEditor.AddObject((FVector*) &actor->Pos, actor->Model, CollisionType::VTX_INTERSECT, 0.0f); // Skip C++ vtable to access variables in C return reinterpret_cast(reinterpret_cast(Actors.back()) + sizeof(void*)); } diff --git a/src/engine/World.h b/src/engine/World.h index 9490293b7..4581d6ee4 100644 --- a/src/engine/World.h +++ b/src/engine/World.h @@ -48,7 +48,7 @@ public: void AddCourse(Course* course); AActor* AddActor(AActor* actor); - struct Actor* AddBaseActor(); + struct Actor* AddBaseActor(s16 actorType); AActor* GetActor(size_t index); void TickActors(); diff --git a/src/engine/editor/Collision.cpp b/src/engine/editor/Collision.cpp new file mode 100644 index 000000000..af9a9bd3c --- /dev/null +++ b/src/engine/editor/Collision.cpp @@ -0,0 +1,94 @@ +#include "Collision.h" + + +void GenerateCollisionMesh(GameObject& object, Gfx* model) { + int8_t opcode; + uintptr_t lo; + uintptr_t hi; + + Gfx* ptr = model; + Vtx* vtx = NULL; + size_t i = 0; + bool run = true; + while (run) { + i++; + lo = ptr->words.w0; + hi = ptr->words.w1; + opcode = (EDITOR_GFX_GET_OPCODE(lo) >> 24); + + switch(opcode) { + case G_DL: + GenerateCollisionMesh(object, (Gfx*)hi); + break; + case G_VTX: + vtx = (Vtx*)ptr->words.w1; + break; + case G_TRI1: { + if (vtx == NULL) { + ptr++; + continue; + } + uint32_t v1 = ((hi & 0x00FF0000) >> 16) / 2; + uint32_t v2 = ((hi & 0x0000FF00) >> 8) / 2; + uint32_t v3 = (hi & 0x000000FF) / 2; + + FVector p1 = FVector(vtx[v1].v.ob[0], vtx[v1].v.ob[1], vtx[v1].v.ob[2]); + FVector p2 = FVector(vtx[v2].v.ob[0], vtx[v2].v.ob[1], vtx[v2].v.ob[2]); + FVector p3 = FVector(vtx[v3].v.ob[0], vtx[v3].v.ob[1], vtx[v3].v.ob[2]); + + object.Triangles.push_back({p1, p2, p3}); + break; + } + case G_TRI2: { + if (vtx == NULL) { + ptr++; + continue; + } + uint32_t v1 = ((lo & 0x00FF0000) >> 16) / 2; + uint32_t v2 = ((lo & 0x0000FF00) >> 8) / 2; + uint32_t v3 = (lo & 0x000000FF) / 2; + + // This is actually triangle 2; vert 1,2,3. + uint32_t v4 = ((hi & 0x00FF0000) >> 16) / 2; + uint32_t v5 = ((hi & 0x0000FF00) >> 8) / 2; + uint32_t v6 = (hi & 0x000000FF) / 2; + + FVector p1 = FVector(vtx[v1].v.ob[0], vtx[v1].v.ob[1], vtx[v1].v.ob[2]); + FVector p2 = FVector(vtx[v2].v.ob[0], vtx[v2].v.ob[1], vtx[v2].v.ob[2]); + FVector p3 = FVector(vtx[v3].v.ob[0], vtx[v3].v.ob[1], vtx[v3].v.ob[2]); + + FVector p4 = FVector(vtx[v4].v.ob[0], vtx[v4].v.ob[1], vtx[v4].v.ob[2]); + FVector p5 = FVector(vtx[v5].v.ob[0], vtx[v5].v.ob[1], vtx[v5].v.ob[2]); + FVector p6 = FVector(vtx[v6].v.ob[0], vtx[v6].v.ob[1], vtx[v6].v.ob[2]); + + object.Triangles.push_back({p1, p2, p3}); + object.Triangles.push_back({p4, p5, p6}); + break; + } + case G_QUAD: { + if (vtx == NULL) { + ptr++; + continue; + } + uint32_t v1 = ((hi & 0x00FF0000) >> 16) / 2; + uint32_t v2 = ((hi & 0x0000FF00) >> 8) / 2; + uint32_t v3 = (hi & 0x000000FF) / 2; + uint32_t v4 = ((hi & 0xFF000000) >> 24) / 2; + + FVector p1 = FVector(vtx[v1].v.ob[0], vtx[v1].v.ob[1], vtx[v1].v.ob[2]); + FVector p2 = FVector(vtx[v2].v.ob[0], vtx[v2].v.ob[1], vtx[v2].v.ob[2]); + FVector p3 = FVector(vtx[v3].v.ob[0], vtx[v3].v.ob[1], vtx[v3].v.ob[2]); + FVector p4 = FVector(vtx[v4].v.ob[0], vtx[v4].v.ob[1], vtx[v4].v.ob[2]); + + object.Triangles.push_back({p1, p2, p3}); + object.Triangles.push_back({p1, p3, p4}); + break; + } + case G_ENDDL: + run = false; + break; + } + + ptr++; + } +} diff --git a/src/engine/editor/Collision.h b/src/engine/editor/Collision.h new file mode 100644 index 000000000..6637051b8 --- /dev/null +++ b/src/engine/editor/Collision.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#include "EditorMath.h" + +/** + * @file Editor Collision + * + * Most actors use cylinder collision. + * Proper vtx intersection tests are necessary for object picking + * + * Therefore, generate a full collision mesh for actors + */ + +#define EDITOR_GFX_GET_OPCODE(var) ((uint32_t) ((var) & 0xFF000000)) + +void GenerateCollisionMesh(GameObject& object, Gfx* model); diff --git a/src/engine/editor/Editor.cpp b/src/engine/editor/Editor.cpp index 9cf08a689..0de8d2884 100644 --- a/src/engine/editor/Editor.cpp +++ b/src/engine/editor/Editor.cpp @@ -5,6 +5,8 @@ #include "../World.h" #include "Editor.h" +#include "Collision.h" + #include "port/Engine.h" #include #include @@ -30,20 +32,36 @@ Editor::Editor() { // gsSPSetFB(gDisplayListHead++, &test); } -void Editor::Tick() { - auto wnd = GameEngine::Instance->context->GetWindow(); - - - // GetMouseState - if (wnd->MouseClick(Ship::LUS_MOUSE_BTN_LEFT)) { - eObjectPicker.SelectObject(); +void Editor::Load() { + eObjectPicker.Load(); + for (auto& object : eGameObjects) { + GenerateCollisionMesh(object, object.Model); } } +void Editor::Tick() { + auto wnd = GameEngine::Instance->context->GetWindow(); + + // GetMouseState + if (wnd->MouseClick(Ship::LUS_MOUSE_BTN_LEFT)) { + eObjectPicker.SelectObject(eGameObjects); + } +} + void Editor::Draw() { eObjectPicker.Draw(); } +void Editor::AddObject(FVector* pos, Gfx* model, CollisionType collision, float boundingBoxSize) { + + if (model != NULL) { + eGameObjects.push_back({pos, model, {}, collision, boundingBoxSize}); + GenerateCollisionMesh(eGameObjects.back(), model); + } else { // to bounding box or sphere collision + eGameObjects.push_back({pos, model, {}, CollisionType::BOUNDING_BOX, 2.0f}); + } +} + void Editor::DrawObj(float length) { Mat4 mtx; Vec3f pos2 = { _ray[0], _ray[1], _ray[2] }; diff --git a/src/engine/editor/Editor.h b/src/engine/editor/Editor.h index 3126bf7bd..86be459d2 100644 --- a/src/engine/editor/Editor.h +++ b/src/engine/editor/Editor.h @@ -5,23 +5,24 @@ #include "engine/objects/Flagpole.h" #include "ObjectPicker.h" -class AShip; +class ObjectPicker; class Editor { public: Editor(); + + ObjectPicker eObjectPicker; + std::vector eGameObjects; + void Tick(); void Draw(); void MouseClick(); + void Load(); + void AddObject(FVector* pos, Gfx* model, CollisionType collision, float boundingBoxSize); private: bool _draw = false; - AShip* object; Vec3f _ray; - AActor* _selected; - AActor* _lastSelected; - - s32 _colourIdFramebuffer = -1; s32 Inverse(MtxF* src, MtxF* dest); void Copy(MtxF* src, MtxF* dest); @@ -29,7 +30,6 @@ private: void DrawObj(float length); - ObjectPicker eObjectPicker; Vtx box_Cube_mesh_vtx_cull[8] = { diff --git a/src/engine/editor/EditorMath.cpp b/src/engine/editor/EditorMath.cpp index 64d39c938..cd2b3f3b4 100644 --- a/src/engine/editor/EditorMath.cpp +++ b/src/engine/editor/EditorMath.cpp @@ -4,14 +4,18 @@ #include "port/Game.h" #include "port/Engine.h" +#include +#include +#include + extern "C" { - #include "common_structs.h" - #include "main.h" - #include "defines.h" - #include "actors.h" - #include "math_util.h" - #include "math_util_2.h" - #include "camera.h" +#include "common_structs.h" +#include "main.h" +#include "defines.h" +#include "actors.h" +#include "math_util.h" +#include "math_util_2.h" +#include "camera.h" } FVector ScreenRayTrace() { @@ -186,3 +190,55 @@ void Clear(MtxF* mf) { mf->yw = 0.0f; mf->zw = 0.0f; } + +bool IntersectRayTriangle(const Ray& ray, const Triangle& tri, float& t) { + const float EPSILON = 1e-6f; + + FVector edge1 = tri.v1 - tri.v0; + FVector edge2 = tri.v2 - tri.v0; + FVector h = ray.Direction.Cross(edge2); + float a = edge1.Dot(h); + + if (std::abs(a) < EPSILON) + return false; // Ray is parallel to triangle + + float f = 1.0f / a; + FVector s = ray.Origin - tri.v0; + float u = f * s.Dot(h); + + if (u < 0.0f || u > 1.0f) + return false; + + FVector q = s.Cross(edge1); + float v = f * ray.Direction.Dot(q); + + if (v < 0.0f || u + v > 1.0f) + return false; + + t = f * edge2.Dot(q); + return t > EPSILON; +} + +bool FindClosestObject(const Ray& ray, const std::vector& objects, GameObject& outObject, float& outDistance) { + float closestDist = std::numeric_limits::max(); + bool found = false; + + for (const auto& obj : objects) { + for (const auto& tri : obj.Triangles) { + float t; + if (IntersectRayTriangle(ray, tri, t) && t < closestDist) { + closestDist = t; + outObject = obj; + found = true; + } + } + } + + if (found) { + outDistance = closestDist; + return true; + } + + return false; +} + diff --git a/src/engine/editor/EditorMath.h b/src/engine/editor/EditorMath.h index 165b28ec5..5a123b726 100644 --- a/src/engine/editor/EditorMath.h +++ b/src/engine/editor/EditorMath.h @@ -7,6 +7,29 @@ extern "C" { #include "common_structs.h" } +enum class CollisionType { + VTX_INTERSECT, + BOUNDING_BOX, + BOUNDING_SPHERE +}; + +struct Ray { + FVector Origin; + FVector Direction; +}; + +struct Triangle { + FVector v0, v1, v2; +}; + +struct GameObject { + FVector* Pos; + Gfx* Model; + std::vector Triangles; + CollisionType Collision; + float BoundingBoxSize; +}; + /** * Projects 2D cursor into the game world * @@ -23,4 +46,7 @@ s32 Inverse(MtxF* src, MtxF* dest); void Copy(MtxF* src, MtxF* dest); void Clear(MtxF* mf); +bool IntersectRayTriangle(const Ray& ray, const Triangle& tri, float& t); + + diff --git a/src/engine/editor/Gizmo.cpp b/src/engine/editor/Gizmo.cpp index 97445464b..9341cb23b 100644 --- a/src/engine/editor/Gizmo.cpp +++ b/src/engine/editor/Gizmo.cpp @@ -26,6 +26,21 @@ extern "C" { Gizmo::Gizmo() { } +void Gizmo::Load() { + RedCollision.Pos = &Pos; + RedCollision.Model = handle_Cylinder_mesh; + + GreenCollision.Pos = &Pos; + GreenCollision.Model = handle_Cylinder_mesh; + + BlueCollision.Pos = &Pos; + BlueCollision.Model = handle_Cylinder_mesh; + + GenerateCollisionMesh(RedCollision, RedCollision.Model); + GenerateCollisionMesh(GreenCollision, GreenCollision.Model); + GenerateCollisionMesh(BlueCollision, BlueCollision.Model); +} + void Gizmo::Tick() { } @@ -57,7 +72,7 @@ void Gizmo::StartManipulation(GizmoHandle handle) { } } -void Gizmo::Enable(Vec3f* object, FVector ray) { +void Gizmo::Enable(GameObject* object, Ray ray) { static float length = 180.0f; // Default value // static AActor* lastSelected = nullptr; @@ -73,12 +88,14 @@ void Gizmo::Enable(Vec3f* object, FVector ray) { //_selected->Pos[0] = cameras[0].pos[0] + ray.x * length; //object->Pos[1] = cameras[0].pos[1] + ray.y * length; //_selected->Pos[2] = cameras[0].pos[2] + ray.z * length; - _selected = &object[0]; - _ray = ray; + + + _selected = object; + _ray = ray.Direction; Pos = FVector( - object[0][0], - object[0][1], - object[0][2] + object->Pos->x, + object->Pos->y, + object->Pos->z ); } @@ -89,18 +106,18 @@ void Gizmo::Translate() { //FVector ray = ScreenRayTrace(); length = sqrt( - pow(_selected[0][0] - cameras[0].pos[0], 2) + - pow(_selected[0][1] - cameras[0].pos[1], 2) + - pow(_selected[0][2] - cameras[0].pos[2], 2) + pow(_selected->Pos->x - cameras[0].pos[0], 2) + + pow(_selected->Pos->y - cameras[0].pos[1], 2) + + pow(_selected->Pos->z - cameras[0].pos[2], 2) ); //_selected->Pos[0] = cameras[0].pos[0] + ray.x * length; - _selected[0][0] = cameras[0].pos[1] + _ray.y * length; + _selected->Pos->x = cameras[0].pos[1] + _ray.y * length; //_selected->Pos[2] = cameras[0].pos[2] + ray.z * length; Pos = FVector( - _selected[0][0], - _selected[0][1], - _selected[0][2] + _selected->Pos->x, + _selected->Pos->y, + _selected->Pos->z ); } } diff --git a/src/engine/editor/Gizmo.h b/src/engine/editor/Gizmo.h index a8cc60a9a..a2275972e 100644 --- a/src/engine/editor/Gizmo.h +++ b/src/engine/editor/Gizmo.h @@ -2,6 +2,7 @@ #include #include +#include "Collision.h" #include "engine/objects/Flagpole.h" class Gizmo { @@ -19,9 +20,10 @@ public: void Tick(); void Draw(); + void Load(); void StartManipulation(GizmoHandle handle); - void Enable(Vec3f* object, FVector ray); + void Enable(GameObject* object, Ray ray); void Translate(); void DrawHandles(); @@ -31,6 +33,10 @@ public: bool Enabled; GizmoHandle SelectedHandle; + GameObject RedCollision; + GameObject GreenCollision; + GameObject BlueCollision; + FVector Pos; // Global scene view float _gizmoOffset = 5.0f; FVector RedPos = {0, 0, -_gizmoOffset}; // Local model view @@ -48,7 +54,7 @@ public: private: bool _draw = false; FVector _ray; - Vec3f* _selected; + GameObject* _selected; Lights1 handle_f3dlite_material_lights = gdSPDefLights1( diff --git a/src/engine/editor/ObjectPicker.cpp b/src/engine/editor/ObjectPicker.cpp index bc16b9db4..636c4b1a2 100644 --- a/src/engine/editor/ObjectPicker.cpp +++ b/src/engine/editor/ObjectPicker.cpp @@ -29,13 +29,19 @@ ObjectPicker::ObjectPicker() { } -void ObjectPicker::SelectObject() { - FVector ray = ScreenRayTrace(); +void ObjectPicker::Load() { + eGizmo.Load(); +} - ObjectPicker::FindObject(ray); +void ObjectPicker::SelectObject(std::vector& objects) { + Ray ray; + ray.Origin = FVector(cameras[0].pos[0], cameras[0].pos[1], cameras[0].pos[2]); + ray.Direction = ScreenRayTrace(); + + ObjectPicker::FindObject(ray, objects); if (_selected != nullptr) { - eGizmo.Enable(&_selected->Pos, ray); + eGizmo.Enable(_selected, ray); eGizmo.Enabled = true; } else { //eGizmo.Disable(); @@ -49,54 +55,87 @@ void ObjectPicker::Draw() { } } -void ObjectPicker::FindObject(FVector ray) { +void ObjectPicker::FindObject(Ray ray, std::vector& objects) { // Is the gizmo being clicked? if (eGizmo.Enabled) { Gizmo::GizmoHandle handle = Gizmo::GizmoHandle::None; - for (size_t i = 0; i < 4; i++) { - float t; - auto [boxMin, boxMax] = eGizmo.GetBoundingBox((Gizmo::GizmoHandle) i); - if (QueryCollisionRayActor(cameras[0].pos, &ray.x, &boxMin.x, &boxMax.x, &t)) { - handle = (Gizmo::GizmoHandle) i; + for (auto tri = eGizmo.RedCollision.Triangles.begin(); tri < eGizmo.RedCollision.Triangles.end(); tri++) { + float t; + if (IntersectRayTriangle(ray, *tri, t)) { + handle = Gizmo::GizmoHandle::X_Axis; break; } } - + + for (auto tri = eGizmo.GreenCollision.Triangles.begin(); tri < eGizmo.GreenCollision.Triangles.end(); tri++) { + float t; + if (IntersectRayTriangle(ray, *tri, t)) { + handle = Gizmo::GizmoHandle::Y_Axis; + break; + } + } + + for (auto tri = eGizmo.BlueCollision.Triangles.begin(); tri < eGizmo.BlueCollision.Triangles.end(); tri++) { + float t; + if (IntersectRayTriangle(ray, *tri, t)) { + handle = Gizmo::GizmoHandle::Z_Axis; + break; + } + } + if (handle != Gizmo::GizmoHandle::None) { eGizmo.StartManipulation(handle); return; // Stop checking objects if we selected a Gizmo handle } } - - s32 type = 0; + + //s32 type = 0; bool found = false; - for (auto& actor : gWorldInstance.Actors) { - float boundingBox = actor->BoundingBoxSize; + for (auto& object : objects) { + float boundingBox = object.BoundingBoxSize; if (boundingBox == 0.0f) { boundingBox = 2.0f; } float t; - float max = 2.0f; - float min = -2.0f; - Vec3f boxMin = { actor->Pos[0] + boundingBox * min, - actor->Pos[1] + boundingBox * min, - actor->Pos[2] + boundingBox * min }; - Vec3f boxMax = { actor->Pos[0] + actor->BoundingBoxSize * max, - actor->Pos[1] + actor->BoundingBoxSize * max, - actor->Pos[2] + actor->BoundingBoxSize * max }; + switch(object.Collision) { + case CollisionType::VTX_INTERSECT: + for (const auto& tri : object.Triangles) { + if (IntersectRayTriangle(ray, tri, t)) { + printf("\nSELECTED OBJECT\n\n"); + _selected = &object; + } + } + break; + case CollisionType::BOUNDING_BOX: { + float max = 2.0f; + float min = -2.0f; + Vec3f boxMin = { object.Pos->x + boundingBox * min, + object.Pos->y + boundingBox * min, + object.Pos->z + boundingBox * min }; - if (QueryCollisionRayActor(cameras[0].pos, &ray.x, boxMin, boxMax, &t)) { - // if (actor == _selected) { - // _selected = nullptr; - // break; - // } - found = true; - //foundActor = &actor; - type = actor->Type; - _selected = actor; - break; + Vec3f boxMax = { object.Pos->x + boundingBox * max, + object.Pos->y + boundingBox * max, + object.Pos->z + boundingBox * max }; + + if (QueryCollisionRayActor(&ray.Origin.x, &ray.Direction.x, boxMin, boxMax, &t)) { + // if (actor == _selected) { + // _selected = nullptr; + // break; + // } + printf("FOUND BOUNDING BOX OBJECT\n"); + found = true; + //foundActor = &actor; + //type = object.Type; + _selected = &object; + break; + } + break; + } + case CollisionType::BOUNDING_SPHERE: + printf("Editor::ObjectPicker.cpp Bounding sphere collision type not yet supported\n"); + break; } } if (found) { diff --git a/src/engine/editor/ObjectPicker.h b/src/engine/editor/ObjectPicker.h index 5c4679abe..b8b0e0c46 100644 --- a/src/engine/editor/ObjectPicker.h +++ b/src/engine/editor/ObjectPicker.h @@ -2,6 +2,7 @@ #include #include +#include "Collision.h" #include "engine/objects/Flagpole.h" #include "Gizmo.h" @@ -9,20 +10,20 @@ class ObjectPicker { public: ObjectPicker(); - void SelectObject(); + void SelectObject(std::vector& objects); void Draw(); - void FindObject(FVector ray); + void FindObject(Ray ray, std::vector& objects); + void Load(); private: bool _draw = false; Vec3f _ray; - AActor* _selected; - AActor* _lastSelected; + GameObject* _selected; + GameObject* _lastSelected; s32 Inverse(MtxF* src, MtxF* dest); void Copy(MtxF* src, MtxF* dest); void Clear(MtxF* mf); void DrawObj(float length); - Gizmo eGizmo; - -}; \ No newline at end of file + Gizmo eGizmo; +}; diff --git a/src/port/Game.cpp b/src/port/Game.cpp index a33258346..3816589c7 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -44,7 +44,9 @@ #include "Smoke.h" #include "engine/HM_Intro.h" + #include "engine/editor/Editor.h" +#include "engine/editor/EditorMath.h" extern "C" { #include "main.h" @@ -667,8 +669,8 @@ void CM_CleanWorld(void) { gWorldInstance.Reset(); } -struct Actor* CM_AddBaseActor(void) { - return (struct Actor*) gWorldInstance.AddBaseActor(); +struct Actor* CM_AddBaseActor(s16 actorType) { + return (struct Actor*) gWorldInstance.AddBaseActor(actorType); } size_t CM_GetActorSize() { @@ -824,6 +826,7 @@ extern "C" } thread5_game_loop(); + gEditor.Load(); while (WindowIsRunning()) { push_frame(); } diff --git a/src/port/Game.h b/src/port/Game.h index cadf48b91..0a5c63c7f 100644 --- a/src/port/Game.h +++ b/src/port/Game.h @@ -6,6 +6,7 @@ #include "engine/HM_Intro.h" #ifdef __cplusplus +#include "engine/editor/Editor.h" class Course; extern "C" { #endif @@ -14,6 +15,10 @@ extern "C" { extern s32 gTrophyIndex; +#ifdef __cplusplus +extern Editor gEditor; +#endif + Properties* CM_GetProps(); Properties* CM_GetPropsCourseId(s32 courseId); @@ -134,7 +139,7 @@ void SetCourseByClass(void* course); struct Actor* CM_GetActor(size_t index); void CM_DeleteActor(size_t index); -struct Actor* CM_AddBaseActor(void); +struct Actor* CM_AddBaseActor(s16 actorType); size_t CM_GetActorSize(); size_t CM_FindActorIndex(struct Actor* actor); void CM_ActorCollision(Player* player, struct Actor* actor); diff --git a/src/racing/actors.c b/src/racing/actors.c index 9fc8059ef..e9f46929d 100644 --- a/src/racing/actors.c +++ b/src/racing/actors.c @@ -1400,7 +1400,7 @@ s16 add_actor_to_empty_slot(Vec3f pos, Vec3s rot, Vec3f velocity, s16 actorType) //} } gNumActors++; - struct Actor* actor = CM_AddBaseActor(); + struct Actor* actor = CM_AddBaseActor(actorType); actor_init(actor, pos, rot, velocity, actorType); return (s16) CM_GetActorSize() - 1; // Return current index; }