summaryrefslogtreecommitdiff
path: root/src/engine/editor
diff options
context:
space:
mode:
authorMegaMech <MegaMech@users.noreply.github.com>2025-12-13 11:50:28 -0700
committerGitHub <noreply@github.com>2025-12-13 11:50:28 -0700
commitb934e98fc34964970ab5efacb2fb7c3372ae0b1a (patch)
treecd96e5fabec7fdcc098d0de33b3b7e2754fb6cd5 /src/engine/editor
parente6acb59ef4797ce27ddc9e21982c3f4e40824b52 (diff)
Refactor Track Class To Instantiate On Track Load (#587)
* Initial Commit * First compilation of Registry template * Further changes * wip changes * Impl TrackBrowser and Registry Info * Remove const from TInfo * Prep GetWorld * Name refactor * Refactor gWorldInstance to GetWorld() * wip * Should work now * Data menu work again * Fix editor staying open after program close * Rename LoadLevel to LoadTrackDataFromJson * More changes * Add statue * Add search to content browser using tags * Fix statue pos and register tags * Fix actor loading * Fix delete all bug which deleted cameras * reduce some boiler plate in actor and object * Remove unused rulesets * Search bar for all tabs * fix data screen * fix actor spawning * temp editor fix * Clean up * improve extra mode transformation * fix podium crash * Fix editor clicking * Fix editor clicking 2 * fix extra in custom track * Fix FI for three actors * Fix divide by zero error * Ids managed by Registry * Add scary comment --------- Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com> Co-authored-by: coco875 <pereira.jannin@gmail.com>
Diffstat (limited to 'src/engine/editor')
-rw-r--r--src/engine/editor/Collision.cpp6
-rw-r--r--src/engine/editor/Editor.cpp83
-rw-r--r--src/engine/editor/Editor.h39
-rw-r--r--src/engine/editor/EditorMath.cpp6
-rw-r--r--src/engine/editor/Gizmo.cpp8
-rw-r--r--src/engine/editor/Light.cpp2
-rw-r--r--src/engine/editor/ObjectPicker.cpp12
-rw-r--r--src/engine/editor/SceneManager.cpp179
-rw-r--r--src/engine/editor/SceneManager.h14
9 files changed, 253 insertions, 96 deletions
diff --git a/src/engine/editor/Collision.cpp b/src/engine/editor/Collision.cpp
index 5a6d734ba..f79865899 100644
--- a/src/engine/editor/Collision.cpp
+++ b/src/engine/editor/Collision.cpp
@@ -7,6 +7,7 @@
#include "engine/Actor.h"
#include "engine/objects/Object.h"
#include "engine/editor/GameObject.h"
+#include "port/Game.h"
extern "C" {
#include "main.h"
@@ -24,11 +25,6 @@ namespace Editor {
size_t i = 0;
bool run = true;
- //! @attention Objects will not be clickable if editor is enabled mid-race.
- if (CVarGetInteger("gEditorEnabled", false) == true) {
- return;
- }
-
while (run) {
i++;
lo = ptr->words.w0;
diff --git a/src/engine/editor/Editor.cpp b/src/engine/editor/Editor.cpp
index 911cc9a8c..698a6cc40 100644
--- a/src/engine/editor/Editor.cpp
+++ b/src/engine/editor/Editor.cpp
@@ -12,6 +12,7 @@
#include <ship/controller/controldevice/controller/mapping/keyboard/KeyboardScancodes.h>
#include <ship/window/Window.h>
+#include "engine/TrackBrowser.h"
#include "engine/actors/Ship.h"
#include "port/Game.h"
@@ -24,7 +25,10 @@ extern "C" {
}
namespace Editor {
+ Editor* Editor::Instance;
+
Editor::Editor() {
+ Instance = this;
}
Editor::~Editor() {
@@ -43,28 +47,65 @@ namespace Editor {
printf("Editor: Loading Complete!\n");
}
+ void Editor::Enable() {
+ bEditorEnabled = true;
+ bIsEditorPaused = true;
+ CVarSetInteger("gFreecam", true);
+ CM_SetFreeCamera(true);
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Tools")->Show();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Scene Explorer")->Show();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Content Browser")->Show();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Track Properties")->Show();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Properties")->Show();
+ }
+
+ void Editor::Disable() {
+ bEditorEnabled = false;
+ bIsEditorPaused = false;
+ CVarSetInteger("gFreecam", false);
+ CM_SetFreeCamera(false);
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Tools")->Hide();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Scene Explorer")->Hide();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Content Browser")->Hide();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Track Properties")->Hide();
+ Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Properties")->Hide();
+ }
+
+ bool Editor::IsEnabled() {
+ return bEditorEnabled;
+ }
+
+ void Editor::Play() {
+ bIsEditorPaused = false;
+ }
+
+ void Editor::Pause() {
+ bIsEditorPaused = true;
+ }
+
+ bool Editor::IsPaused() {
+ return bIsEditorPaused;
+ }
+
+ void Editor::TogglePlayState() {
+ bIsEditorPaused = !bIsEditorPaused;
+ }
+
void Editor::GenerateCollision() {
- // for (auto& actor : gWorldInstance.Actors) {
+ // for (auto& actor : GetWorld()->Actors) {
// GenerateCollisionMesh(actor, (Gfx*)actor->Model, 1.0f);
// }
}
void Editor::Tick() {
- if (CVarGetInteger("gEditorEnabled", 0) == true) {
+ if (Editor_IsEnabled() == true) {
bEditorEnabled = true;
} else {
bEditorEnabled = false;
- gIsEditorPaused = false; // Prevents game being paused with the editor closed.
+ bIsEditorPaused = false; // Prevents game being paused with the editor closed.
return;
}
- // Set camera
- if (CVarGetInteger("gFreecam", 0) == true) {
- eCamera = &cameras[CAMERA_FREECAM];
- } else {
- eCamera = &cameras[0];
- }
-
auto wnd = GameEngine::Instance->context->GetWindow();
static bool wasMouseDown = false;
@@ -111,7 +152,6 @@ namespace Editor {
if (!isDragging) {
eObjectPicker.SelectObject(eGameObjects);
}
-
}
wasMouseDown = isMouseDown; // Update previous state
@@ -197,3 +237,24 @@ namespace Editor {
eObjectPicker.eGizmo.dimensions.MaxZ = maxZ + 1000;
}
}
+
+/** C BRIDGE FUNCTIONS **/
+
+extern "C" void Editor_Launch(const char* resourceName) {
+#if not defined(__SWITCH__) and not defined(__WIIU__)
+ TrackBrowser::Instance->SetTrack(std::string(resourceName));
+ gEditor.Enable();
+#endif
+}
+
+extern "C" void Editor_SetLevelDimensions(s16 minX, s16 maxX, s16 minZ, s16 maxZ, s16 minY, s16 maxY) {
+ gEditor.SetLevelDimensions(minX, maxX, minZ, maxZ, minY, maxY);
+}
+
+extern "C" bool Editor_IsEnabled() {
+ return gEditor.IsEnabled();
+}
+
+extern "C" bool Editor_IsPaused() {
+ return gEditor.IsPaused();
+}
diff --git a/src/engine/editor/Editor.h b/src/engine/editor/Editor.h
index 38af5b915..77169de46 100644
--- a/src/engine/editor/Editor.h
+++ b/src/engine/editor/Editor.h
@@ -1,12 +1,12 @@
-#ifndef __EDITOR_H__
-#define __EDITOR_H__
+#ifndef EDITOR_H
+#define EDITOR_H
#include <libultraship/libultraship.h>
#include <libultra/gbi.h>
-#include "GameObject.h"
#ifdef __cplusplus
+#include "GameObject.h"
extern "C" {
#include "camera.h"
}
@@ -17,15 +17,23 @@ namespace Editor {
class Editor {
public:
+ static Editor* Instance;
Editor();
~Editor();
ObjectPicker eObjectPicker;
std::vector<GameObject*> eGameObjects;
-
+
+ void Load();
+ void Enable();
+ void Disable();
+ bool IsEnabled();
+ void Play();
+ void Pause();
+ bool IsPaused();
+ void TogglePlayState();
void Tick();
void Draw();
- void Load();
void GenerateCollision();
GameObject* AddObject(FVector pos, IRotator rot, FVector scale, const char* model, float collScale, GameObject::CollisionType collision, float boundingBoxSize);
void AddLight(const char* name, FVector* pos, s8* rot);
@@ -36,10 +44,9 @@ public:
void SetLevelDimensions(s16 minX, s16 maxX, s16 minZ, s16 maxZ, s16 minY, s16 maxY);
void ClearMatrixPool();
void DeleteObject();
- bool bEditorEnabled = false;
-
- Camera* eCamera = &cameras[0];
private:
+ bool bIsEditorPaused = false;
+ bool bEditorEnabled = false;
bool _draw = false;
Vec3f _ray;
@@ -47,9 +54,19 @@ private:
void Copy(MtxF* src, MtxF* dest);
void Clear(MtxF* mf);
};
-}
+} // namespace Editor
+#endif // __cplusplus
+
+
+#ifdef __cplusplus
+#define EXTERN_C extern "C"
+#else
+#define EXTERN_C
#endif
-void SetLevelDimensions(s16 minX, s16 maxX, s16 minZ, s16 maxZ, s16 minY, s16 maxY);
+EXTERN_C void Editor_Launch(const char* resourceName);
+EXTERN_C void Editor_SetLevelDimensions(s16 minX, s16 maxX, s16 minZ, s16 maxZ, s16 minY, s16 maxY);
+EXTERN_C bool Editor_IsEnabled();
+EXTERN_C bool Editor_IsPaused();
-#endif // __EDITOR_H__
+#endif // EDITOR_H
diff --git a/src/engine/editor/EditorMath.cpp b/src/engine/editor/EditorMath.cpp
index 93d826ace..620aa2b48 100644
--- a/src/engine/editor/EditorMath.cpp
+++ b/src/engine/editor/EditorMath.cpp
@@ -42,7 +42,7 @@ bool IsInGameScreen() {
FVector ScreenRayTrace() {
auto wnd = GameEngine::Instance->context->GetWindow();
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
Ship::Coords mouse = wnd->GetMousePos();
auto gfx_current_game_window_viewport = GetInterpreter()->mGameWindowViewport;
@@ -62,7 +62,7 @@ FVector ScreenRayTrace() {
Mat4 perspMtx;
u16 perspNorm;
- guPerspectiveF(perspMtx, &perspNorm, gCameraFOV[0], OTRGetAspectRatio(), CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
+ guPerspectiveF(perspMtx, &perspNorm, 40, OTRGetAspectRatio(), CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f);
Mat4 inversePerspMtx;
if (InverseMatrix((float*)&perspMtx, (float*)&inversePerspMtx) != 2) {
@@ -412,7 +412,7 @@ void SetRotatorFromDirection(FVector direction, IRotator* rot) {
}
FVector GetPositionAheadOfCamera(f32 dist) {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
FVector pos = FVector(camera->pos[0], camera->pos[1], camera->pos[2]);
f32 pitch = (camera->rot[2] / 65535.0f) * 360.0f;
diff --git a/src/engine/editor/Gizmo.cpp b/src/engine/editor/Gizmo.cpp
index 6cb4c74a8..4d3c86d25 100644
--- a/src/engine/editor/Gizmo.cpp
+++ b/src/engine/editor/Gizmo.cpp
@@ -112,7 +112,7 @@ void Gizmo::Translate() {
static float length = 180.0f; // Default value
std::visit([this](auto* obj) {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
float x, y, z = 0;
if (nullptr == obj) {
return;
@@ -217,7 +217,7 @@ f32 Gizmo::SnapToSurface(const FVector pos) {
void Gizmo::Rotate() {
std::visit([this](auto* obj) {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
FVector cam = FVector(camera->pos[0], camera->pos[1], camera->pos[2]);
IRotator rot;
@@ -269,7 +269,7 @@ void Gizmo::Rotate() {
void Gizmo::Scale() {
std::visit([this](auto* obj) {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
FVector cam = FVector(camera->pos[0], camera->pos[1], camera->pos[2]);
if (nullptr == obj) {
return;
@@ -398,7 +398,7 @@ void Gizmo::DrawHandles() {
Editor_AddMatrix(mainMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
if (center) {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
Mat4 CenterMtx;
Editor_MatrixIdentity(CenterMtx);
diff --git a/src/engine/editor/Light.cpp b/src/engine/editor/Light.cpp
index 6aa332d6e..53dc00864 100644
--- a/src/engine/editor/Light.cpp
+++ b/src/engine/editor/Light.cpp
@@ -57,7 +57,7 @@ size_t LightObject::NumLights = 0;
SetDirectionFromRotator(Rot, Direction);
}
void LightObject::Draw() {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
Mat4 mtx_sun;
Editor_MatrixIdentity(mtx_sun);
gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH);
diff --git a/src/engine/editor/ObjectPicker.cpp b/src/engine/editor/ObjectPicker.cpp
index 0d88db35c..cbce7dd09 100644
--- a/src/engine/editor/ObjectPicker.cpp
+++ b/src/engine/editor/ObjectPicker.cpp
@@ -35,7 +35,7 @@ void ObjectPicker::Tick() {
}
void ObjectPicker::SelectObject(std::vector<GameObject*> objects) {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
Ray ray;
ray.Origin = FVector(camera->pos[0], camera->pos[1], camera->pos[2]);
@@ -59,7 +59,7 @@ void ObjectPicker::SelectObject(std::vector<GameObject*> objects) {
}
void ObjectPicker::DragHandle() {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
Ray ray;
ray.Origin = FVector(camera->pos[0], camera->pos[1], camera->pos[2]);
ray.Direction = ScreenRayTrace();
@@ -136,7 +136,7 @@ void ObjectPicker::Draw() {
}, _selected);
if (Debug) {
- Camera* camera = gEditor.eCamera;
+ Camera* camera = gScreenOneCtx->camera;
Mat4 CursorMtx;
IRotator rot = IRotator(0,0,0);
FVector scale = FVector(1, 1, 1);
@@ -249,7 +249,7 @@ std::pair<AActor*, float> ObjectPicker::CheckAActorRay(Ray ray) {
AActor* hitActor = nullptr;
float hitDistance = FLT_MAX;
- for (auto actor : gWorldInstance.Actors) {
+ for (const auto& actor : GetWorld()->Actors) {
if ((actor->bPendingDestroy) && (!actor->IsMod())) {
continue;
}
@@ -265,7 +265,7 @@ std::pair<AActor*, float> ObjectPicker::CheckAActorRay(Ray ray) {
if (IntersectRayTriangleAndTransform(ray, FVector(actor->Pos[0], actor->Pos[1], actor->Pos[2]), tri, t)) {
if (t < hitDistance) {
hitDistance = t;
- hitActor = static_cast<AActor*>(actor);
+ hitActor = actor.get();
}
}
}
@@ -283,7 +283,7 @@ std::pair<AActor*, float> ObjectPicker::CheckAActorRay(Ray ray) {
if (QueryCollisionRayActor(&ray.Origin.x, &ray.Direction.x, boxMin, boxMax, &t)) {
if (t < hitDistance) {
hitDistance = t;
- hitActor = static_cast<AActor*>(actor);
+ hitActor = actor.get();
}
}
}
diff --git a/src/engine/editor/SceneManager.cpp b/src/engine/editor/SceneManager.cpp
index 0165f5c81..135079a57 100644
--- a/src/engine/editor/SceneManager.cpp
+++ b/src/engine/editor/SceneManager.cpp
@@ -7,6 +7,7 @@
#include <iostream>
#include <fstream>
+#include <memory>
#include <optional> // Must be before json.hpp
#include <nlohmann/json.hpp>
#include "port/Engine.h"
@@ -21,28 +22,23 @@
#include "engine/objects/Thwomp.h"
#include "engine/objects/Snowman.h"
#include "engine/cameras/TourCamera.h"
+#include "port/resource/type/TrackPathPointData.h"
extern "C" {
#include "common_structs.h"
#include "actors.h"
#include "actor_types.h"
+#include "code_80005FD0.h"
}
namespace Editor {
- std::shared_ptr<Ship::Archive> CurrentArchive;
- std::string SceneFile = "";
-
- void SaveLevel() {
- if ((!CurrentArchive) || (SceneFile.empty())) {
- SPDLOG_INFO("[SceneManager] [SaveLevel] Could not save scene file, SceneFile or CurrentArchive not set");
- return;
- }
+ void SaveLevel(Track* track) {
nlohmann::json data;
/**
* Save track properties, static mesh actors, actors, and tour camera
*/
- data["Props"] = gWorldInstance.GetTrack()->Props.to_json();
+ data["Props"] = track->Props.to_json();
nlohmann::json staticMesh;
SaveStaticMeshActors(staticMesh);
@@ -54,12 +50,17 @@ namespace Editor {
data["Actors"] = actors;
- if (gWorldInstance.GetTrack()->TourShots.size() != 0) {
+ if (track->TourShots.size() != 0) {
nlohmann::json tour;
- SaveTour(tour);
+ SaveTour(track, tour);
data["Tour"] = tour;
}
+ if (nullptr == track->Archive) {
+ SPDLOG_INFO("[SceneManager] [SaveLevel] Track archive nullptr");
+ return;
+ }
+
/**
* Write data to file
*/
@@ -68,11 +69,14 @@ namespace Editor {
std::vector<uint8_t> bytes; // Turn the str into raw data
bytes.assign(jsonStr.begin(), jsonStr.end());
+ const TrackInfo* info = gTrackRegistry.GetInfo(track->ResourceName);
+ std::string sceneFile = info->Path + "/scene.json";
+
// Write file to disk
- bool wrote = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->WriteFile(CurrentArchive, SceneFile, bytes);
+ bool wrote = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->WriteFile(track->Archive, sceneFile, bytes);
if (wrote) {
// Tell the cache this file needs to be reloaded
- auto resource = GameEngine::Instance->context->GetResourceManager()->GetCachedResource(SceneFile);
+ auto resource = GameEngine::Instance->context->GetResourceManager()->GetCachedResource(sceneFile);
if (resource) {
resource->Dirty();
}
@@ -84,11 +88,18 @@ namespace Editor {
}
}
- /** Do not use gWorldInstance.CurrentCourse during loading! The current track is not guaranteed! **/
- void LoadLevel(Track* track, std::string sceneFile) {
- SceneFile = sceneFile;
- if ((nullptr == track) || (nullptr == track->RootArchive)) {
- SPDLOG_INFO("[SceneManager] [LoadLevel] Failed to load scenefile, track or rootarchive were null");
+ /** Do not use GetWorld()->CurrentCourse during loading! The current track is not guaranteed! **/
+ void LoadTrackDataFromJson(Track* track, const std::string& trackPath) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Loading track scenefile...");
+
+ if (trackPath.empty()) {
+ SPDLOG_INFO(" Unable to load track. trackPath empty.");
+ return;
+ }
+
+ std::string sceneFile = trackPath + "/scene.json";
+ if ((nullptr == track) || (nullptr == track->Archive)) {
+ SPDLOG_INFO(" Failed to load scenefile, track or archive were null");
return;
}
@@ -97,7 +108,7 @@ namespace Editor {
* the init data needs to be manually populated
*/
auto initData = std::make_shared<Ship::ResourceInitData>();
- initData->Parent = track->RootArchive;
+ initData->Parent = track->Archive;
initData->Format = RESOURCE_FORMAT_BINARY;
initData->ByteOrder = Ship::Endianness::Little;
initData->Type = static_cast<uint32_t>(Ship::ResourceType::Json);
@@ -109,56 +120,80 @@ namespace Editor {
// Check that the data is valid
if (data.is_null() || !data.is_object() || data.empty()) {
- SPDLOG_INFO("[SceneManager] [LoadLevel] Scenefile corrupted or contained no data");
+ SPDLOG_INFO(" Scenefile corrupted or contained no data");
return;
}
- SPDLOG_INFO("[SceneManager] [LoadLevel] Loading track scenefile...");
+ SPDLOG_INFO(" Loading Props, Actors, Static Mesh Actors, and Tour...");
// Load the Props, and populate actors
LoadProps(track, data);
+ LoadPaths(track, trackPath);
+ LoadMinimap(track, trackPath);
LoadActors(track, data);
LoadStaticMeshActors(track, data);
LoadTour(track, data);
- SPDLOG_INFO("[SceneManager] [LoadLevel] Scene File Loaded!");
+ SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Scene File Loaded!");
+ }
+
+ void LoadTrackInfo(TrackInfo& info, std::shared_ptr<Ship::Archive> archive, std::string sceneFile) {
+ if (nullptr == archive) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Failed to load scenefile, track or rootarchive were null");
+ return;
+ }
+
+ /*
+ * Manually loading a custom asset file (scene.json) with no extractor class means that
+ * the init data needs to be manually populated
+ */
+ auto initData = std::make_shared<Ship::ResourceInitData>();
+ initData->Parent = archive;
+ initData->Format = RESOURCE_FORMAT_BINARY;
+ initData->ByteOrder = Ship::Endianness::Little;
+ initData->Type = static_cast<uint32_t>(Ship::ResourceType::Json);
+ initData->ResourceVersion = 0;
+
+ // Load the scene file and return the json data
+ nlohmann::json data = std::static_pointer_cast<Ship::Json>(
+ GameEngine::Instance->context->GetResourceManager()->LoadResource(sceneFile, true, initData))->Data;
+
+ // Check that the data is valid
+ if (data.is_null() || !data.is_object() || data.empty()) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackInfo] Scenefile corrupted or contained no data");
+ return;
+ }
+
+ LoadTrackInfoData(info, data);
+
+ SPDLOG_INFO("[SceneManager] [LoadTrackInfo] Loaded track info!");
}
void Load_AddStaticMeshActor(const nlohmann::json& actorJson) {
- gWorldInstance.StaticMeshActors.push_back(new StaticMeshActor("", FVector(0, 0, 0), IRotator(0, 0, 0), FVector(1, 1, 1), "", nullptr));
- auto actor = gWorldInstance.StaticMeshActors.back();
+ GetWorld()->StaticMeshActors.push_back(std::make_unique<StaticMeshActor>("", FVector(0, 0, 0), IRotator(0, 0, 0), FVector(1, 1, 1), "", nullptr));
+ auto& actor = GetWorld()->StaticMeshActors.back();
actor->from_json(actorJson);
printf("After from_json: Pos(%f, %f, %f), Name: %s, Model: %s\n",
actor->Pos.x, actor->Pos.y, actor->Pos.z, actor->Name.c_str(), actor->Model.c_str());
}
- void SetSceneFile(std::shared_ptr<Ship::Archive> archive, std::string sceneFile) {
- CurrentArchive = archive;
- SceneFile = sceneFile;
- }
-
- // Called from ContentBrowser.cpp
void LoadMinimap(Track* track, std::string filePath) {
+ std::string minimapPath = filePath + "/minimap.png";
SPDLOG_INFO(" Loading {} minimap...", filePath);
- if (nullptr == track->RootArchive) {
- SPDLOG_INFO("[SceneManager] [LoadMinimap] Root archive is nullptr");
- SetDefaultMinimap(track);
- return;
- }
/*
* Manually loading a custom asset file with no extractor class means that
* the init data needs to be manually populated
*/
auto initData = std::make_shared<Ship::ResourceInitData>();
- initData->Parent = track->RootArchive;
+ initData->Parent = track->Archive;
initData->Format = RESOURCE_FORMAT_BINARY;
initData->ByteOrder = Ship::Endianness::Little;
initData->Type = static_cast<uint32_t>(MK64::ResourceType::Minimap);
initData->ResourceVersion = 0;
std::shared_ptr<MK64::Minimap> ptr = std::static_pointer_cast<MK64::Minimap>(
- GameEngine::Instance->context->GetResourceManager()->LoadResource(filePath, true, initData));
+ GameEngine::Instance->context->GetResourceManager()->LoadResource(minimapPath, true, initData));
if (ptr) {
SPDLOG_INFO(" Minimap Loaded!");
@@ -180,7 +215,7 @@ namespace Editor {
}
void SaveActors(nlohmann::json& actorList) {
- for (const auto& actor : gWorldInstance.Actors) {
+ for (const auto& actor : GetWorld()->Actors) {
SpawnParams params{};
bool alreadyProcessed = false;
@@ -234,7 +269,7 @@ namespace Editor {
}
}
- for (const auto& object : gWorldInstance.Objects) {
+ for (const auto& object : GetWorld()->Objects) {
SpawnParams params;
object->SetSpawnParams(params);
@@ -247,17 +282,17 @@ namespace Editor {
}
void SaveStaticMeshActors(nlohmann::json& actorList) {
- for (const auto& mesh : gWorldInstance.StaticMeshActors) {
+ for (const auto& mesh : GetWorld()->StaticMeshActors) {
actorList.push_back(mesh->to_json());
}
}
- void SaveTour(nlohmann::json& tour) {
- tour["Enabled"] = gWorldInstance.GetTrack()->bTourEnabled;
+ void SaveTour(Track* track, nlohmann::json& tour) {
+ tour["Enabled"] = track->bTourEnabled;
// Camera shots
tour["Shots"] = nlohmann::json::array();
- for (const auto& shot : gWorldInstance.GetTrack()->TourShots) {
+ for (const auto& shot : track->TourShots) {
tour["Shots"].push_back(ToJson(shot));
}
}
@@ -276,8 +311,58 @@ namespace Editor {
}
}
+ void LoadPaths(Track* track, const std::string& trackPath) {
+ std::string path_file = (trackPath + "/data_paths").c_str();
+
+ auto res = std::dynamic_pointer_cast<MK64::Paths>(ResourceLoad(path_file.c_str()));
+
+ if (res != nullptr) {
+ auto& paths = res->PathList;
+
+ size_t i = 0;
+ u16* ptr = &track->Props.PathSizes.unk0;
+ for (auto& path : paths) {
+ if (i >= ARRAY_COUNT(track->Props.PathTable2)) {
+ printf("[Track.cpp] The game can only import 5 paths. Found more than 5. Skipping the rest\n");
+ break; // Only 5 paths allowed. 4 track, 1 vehicle
+ }
+ ptr[i] = path.size();
+ track->Props.PathTable2[i] = (TrackPathPoint*) path.data();
+
+ i += 1;
+ }
+ }
+ gVehiclePathSize = track->Props.PathSizes.unk0; // This is likely incorrect.
+ }
+
+ void LoadTrackInfoData(TrackInfo& info, nlohmann::json& data) {
+ if (!data.contains("Props") || !data["Props"].is_object()) {
+ SPDLOG_INFO("[SceneManager] [LoadTrackInfoData] Track is missing props data. Is the scene.json file corrupt?");
+ return;
+ }
+
+ try {
+ nlohmann::json& j = data.at("Props");
+
+ info.ResourceName = j.at("ResourceName").get<std::string>();
+ info.Name = j.at("Name").get<std::string>();
+ info.DebugName = j.at("DebugName").get<std::string>();
+ info.Length = j.at("TrackLength").get<std::string>();
+
+ printf("[SceneManager] [LoadTrackInfoData] ResourceName: %s, Name: %s, DebugName: %s, Length: %s\n",
+ info.ResourceName.c_str(),
+ info.Name.c_str(),
+ info.DebugName.c_str(),
+ info.Length.c_str()
+ );
+ } catch(const std::exception& e) {
+ std::cerr << " Error parsing track properties: " << e.what() << std::endl;
+ std::cerr << " Is your scene.json file out of date?" << std::endl;
+ }
+ }
+
void LoadActors(Track* track, nlohmann::json& data) {
- if (!data.contains("Actors") || !data["Actors"].is_object()) {
+ if (!data.contains("Actors") || !data["Actors"].is_array()) {
SPDLOG_INFO(" This track contains no actors");
return;
}
@@ -294,12 +379,12 @@ namespace Editor {
}
void LoadStaticMeshActors(Track* track, nlohmann::json& data) {
- if (!data.contains("StaticMeshActors") || !data["StaticMeshActors"].is_object()) {
+ if (!data.contains("StaticMeshActors") || !data["StaticMeshActors"].is_array()) {
SPDLOG_INFO(" This track contains no StaticMeshActors!");
return;
}
- gWorldInstance.StaticMeshActors.clear(); // Clear existing actors, if any
+ GetWorld()->StaticMeshActors.clear(); // Clear existing actors, if any
for (const auto& actorJson : data["StaticMeshActors"]) {
Load_AddStaticMeshActor(actorJson);
@@ -308,7 +393,7 @@ namespace Editor {
void LoadTour(Track* track, nlohmann::json& data) {
if (!data.contains("Tour") || !data["Tour"].is_object()) {
- SPDLOG_INFO(" This track does not contain a camera tour");
+ SPDLOG_INFO(" This track does not contain a camera tour");
return;
}
diff --git a/src/engine/editor/SceneManager.h b/src/engine/editor/SceneManager.h
index f7b3a50bb..48b52a1e2 100644
--- a/src/engine/editor/SceneManager.h
+++ b/src/engine/editor/SceneManager.h
@@ -7,28 +7,26 @@
#include <nlohmann/json.hpp>
namespace Editor {
- void SaveLevel();
- void LoadLevel(Track* track, std::string sceneFile);
+ void SaveLevel(Track* track);
+ void LoadTrackDataFromJson(Track* track, const std::string& trackPath);
+ void LoadTrackInfo(TrackInfo& info, std::shared_ptr<Ship::Archive> archive, std::string sceneFile);
void Load_AddStaticMeshActor(const nlohmann::json& actorJson);
- void SetSceneFile(std::shared_ptr<Ship::Archive> archive, std::string sceneFile);
void LoadMinimap(Track* track, std::string filePath);
void SetDefaultMinimap(Track* track);
void SaveActors(nlohmann::json& actorList);
void SaveStaticMeshActors(nlohmann::json& actorList);
- void SaveTour(nlohmann::json& tour);
+ void SaveTour(Track* track, nlohmann::json& tour);
void LoadProps(Track* track, nlohmann::json& data);
+ void LoadPaths(Track* track, const std::string& trackPath);
+ void LoadTrackInfoData(TrackInfo& info, nlohmann::json& data);
void LoadActors(Track* track, nlohmann::json& data);
void LoadStaticMeshActors(Track* track, nlohmann::json& data);
void LoadTour(Track* track, nlohmann::json& data);
void SpawnActors(std::vector<std::pair<std::string, SpawnParams>> spawnList);
- extern std::shared_ptr<Ship::Archive> CurrentArchive; // This is used to retrieve and write the scene data file
- extern std::string SceneFile;
-
-
inline nlohmann::json ToJson(const FVector& v) {
return {
{"x", v.x},