mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-07-08 06:30:56 -04:00
Editor use vtx collision
This commit is contained in:
@@ -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();
|
||||
|
||||
+19
-7
@@ -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
|
||||
|
||||
+19
-7
@@ -6,14 +6,16 @@
|
||||
#include "TrainCrossing.h"
|
||||
#include <memory>
|
||||
#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<struct Actor*>(reinterpret_cast<char*>(Actors.back()) + sizeof(void*));
|
||||
}
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
|
||||
#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);
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "../World.h"
|
||||
|
||||
#include "Editor.h"
|
||||
#include "Collision.h"
|
||||
|
||||
#include "port/Engine.h"
|
||||
#include <controller/controldevice/controller/mapping/keyboard/KeyboardScancodes.h>
|
||||
#include <window/Window.h>
|
||||
@@ -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] };
|
||||
|
||||
@@ -5,23 +5,24 @@
|
||||
#include "engine/objects/Flagpole.h"
|
||||
#include "ObjectPicker.h"
|
||||
|
||||
class AShip;
|
||||
class ObjectPicker;
|
||||
|
||||
class Editor {
|
||||
public:
|
||||
Editor();
|
||||
|
||||
|
||||
ObjectPicker eObjectPicker;
|
||||
std::vector<GameObject> 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] = {
|
||||
|
||||
@@ -4,14 +4,18 @@
|
||||
#include "port/Game.h"
|
||||
#include "port/Engine.h"
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
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<GameObject>& objects, GameObject& outObject, float& outDistance) {
|
||||
float closestDist = std::numeric_limits<float>::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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Triangle> 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);
|
||||
|
||||
|
||||
|
||||
|
||||
+30
-13
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#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(
|
||||
|
||||
@@ -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<GameObject>& 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<GameObject>& 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) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#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<GameObject>& objects);
|
||||
void Draw();
|
||||
void FindObject(FVector ray);
|
||||
void FindObject(Ray ray, std::vector<GameObject>& 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;
|
||||
|
||||
};
|
||||
Gizmo eGizmo;
|
||||
};
|
||||
|
||||
+5
-2
@@ -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();
|
||||
}
|
||||
|
||||
+6
-1
@@ -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);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user