mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-07-10 07:07:17 -04:00
Failed attempt at transforming collision
This commit is contained in:
@@ -143,6 +143,16 @@ struct IRotator {
|
||||
yaw = y * (UINT16_MAX / 360);
|
||||
roll = r * (UINT16_MAX / 360);
|
||||
}
|
||||
|
||||
// Convert to radians as FVector
|
||||
[[nodiscard]] FVector ToRadians() const {
|
||||
constexpr float scale = 2.0f * M_PI / 65536.0f;
|
||||
return FVector(
|
||||
pitch * scale,
|
||||
yaw * scale,
|
||||
roll * scale
|
||||
);
|
||||
}
|
||||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
#include "Collision.h"
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
#include <libultra/gbi.h>
|
||||
#include "Matrix.h"
|
||||
|
||||
extern "C" {
|
||||
#include "main.h"
|
||||
#include "other_textures.h"
|
||||
}
|
||||
|
||||
namespace Editor {
|
||||
void GenerateCollisionMesh(GameObject* object, Gfx* model, float scale) {
|
||||
int8_t opcode;
|
||||
@@ -16,7 +25,6 @@ namespace Editor {
|
||||
hi = ptr->words.w1;
|
||||
|
||||
opcode = (EDITOR_GFX_GET_OPCODE(lo) >> 24);
|
||||
|
||||
switch(opcode) {
|
||||
case G_DL:
|
||||
GenerateCollisionMesh(object, (Gfx*)hi, scale);
|
||||
@@ -25,15 +33,25 @@ namespace Editor {
|
||||
ptr++;
|
||||
GenerateCollisionMesh(object, (Gfx*)ResourceGetDataByCrc(((uint64_t)(ptr->words.w0 << 32)) + ptr->words.w1), scale);
|
||||
break;
|
||||
case G_DL_OTR_FILEPATH:
|
||||
// printf("otr filepath: %s\n", (const char*)hi);
|
||||
GenerateCollisionMesh(object, (Gfx*)ResourceGetDataByName((const char*)hi), scale);
|
||||
break;
|
||||
case G_VTX:
|
||||
vtx = (Vtx*)ptr->words.w1;
|
||||
break;
|
||||
case G_VTX_OTR_HASH: {
|
||||
const uintptr_t offset = hi;
|
||||
ptr++;
|
||||
vtx = (Vtx*)ResourceGetDataByCrc(((uint64_t)(ptr->words.w0 << 32)) + ptr->words.w1);
|
||||
break;
|
||||
}
|
||||
case G_VTX_OTR_FILEPATH: {
|
||||
const const char* filePath = (const char*)hi;
|
||||
ptr++;
|
||||
size_t vtxDataOff = ptr->words.w1 & 0xFFFF;
|
||||
vtx = ( (Vtx*)ResourceGetDataByName(filePath) ) + vtxDataOff;
|
||||
break;
|
||||
}
|
||||
case G_TRI1: {
|
||||
if (vtx == NULL) {
|
||||
ptr++;
|
||||
@@ -50,6 +68,25 @@ namespace Editor {
|
||||
object->Triangles.push_back({p1, p2, p3});
|
||||
break;
|
||||
}
|
||||
case G_TRI1_OTR: {
|
||||
if (vtx == NULL) {
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The shift values here are different than the above. No idea why. But it has to be this way.
|
||||
uint32_t v1 = (lo & 0x0000FFFF);
|
||||
uint32_t v2 = (hi >> 16);
|
||||
uint32_t v3 = (hi & 0x0000FFFF);
|
||||
|
||||
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++;
|
||||
@@ -103,4 +140,49 @@ namespace Editor {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<GameObject*, std::vector<Vtx>> gDebugObjVtxCache;
|
||||
|
||||
// Render a collision model
|
||||
void DebugCollision(GameObject* obj, FVector pos, IRotator rot, FVector scale, const std::vector<Triangle>& triangles) {
|
||||
if (obj == NULL || triangles.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
|
||||
|
||||
auto& vtxBuffer = gDebugObjVtxCache[obj];
|
||||
if (vtxBuffer.empty()) {
|
||||
for (const auto& tri : triangles) {
|
||||
vtxBuffer.push_back({(s16)tri.v0.x, (s16)tri.v0.y, (s16)tri.v0.z, 0, {0, 0}, {255, 255, 255, 255}});
|
||||
vtxBuffer.push_back({(s16)tri.v1.x, (s16)tri.v1.y, (s16)tri.v1.z, 0, {0, 0}, {255, 255, 255, 255}});
|
||||
vtxBuffer.push_back({(s16)tri.v2.x, (s16)tri.v2.y, (s16)tri.v2.z, 0, {0, 0}, {255, 255, 255, 255}});
|
||||
}
|
||||
}
|
||||
|
||||
// Setup matrix and render state
|
||||
Mat4 mtx;
|
||||
ApplyMatrixTransformations(mtx, pos, rot, scale);
|
||||
Editor_AddMatrix(mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_FOG);
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetCombineMode(gDisplayListHead++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
|
||||
gSPTexture(gDisplayListHead++, 0, 0, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2);
|
||||
uint32_t hash = (uint32_t)((uintptr_t)obj ^ ((uintptr_t)obj >> 16));
|
||||
u8 r = (hash >> 16) & 0xFF;
|
||||
u8 g = (hash >> 8) & 0xFF;
|
||||
u8 b = hash & 0xFF;
|
||||
|
||||
gDPSetPrimColor(gDisplayListHead++, 0, 0, r, g, b, 255);
|
||||
|
||||
// Render triangles in batches of 3
|
||||
for (size_t i = 0; i + 2 < vtxBuffer.size(); i += 3) {
|
||||
gSPVertex(gDisplayListHead++, (uintptr_t)&vtxBuffer[i], 3, 0);
|
||||
gSP1Triangle(gDisplayListHead++, 0, 1, 2, 0);
|
||||
}
|
||||
|
||||
gSPSetGeometryMode(gDisplayListHead++, G_CULL_BACK | G_ZBUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,5 @@
|
||||
|
||||
namespace Editor {
|
||||
void GenerateCollisionMesh(GameObject* object, Gfx* model, float scale);
|
||||
void DebugCollision(GameObject* obj, FVector pos, IRotator rot, FVector scale, const std::vector<Triangle>& triangles);
|
||||
}
|
||||
@@ -133,9 +133,6 @@ s32 Inverse(MtxF* src, MtxF* dest) {
|
||||
// Reaching row = 4 means the column is either all 0 or a duplicate column.
|
||||
// Therefore src is a singular matrix (0 determinant).
|
||||
|
||||
// osSyncPrintf(VT_COL(YELLOW, BLACK));
|
||||
// osSyncPrintf("Skin_Matrix_InverseMatrix():逆行列つくれません\n");
|
||||
// osSyncPrintf(VT_RST);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -215,9 +212,9 @@ bool IntersectRayTriangle(const Ray& ray, const Triangle& tri, const FVector& ob
|
||||
const float EPSILON = 1e-6f;
|
||||
|
||||
// Adjust the triangle vertices by the object's position
|
||||
FVector v0 = tri.v0 + objectPos;
|
||||
FVector v1 = tri.v1 + objectPos;
|
||||
FVector v2 = tri.v2 + objectPos;
|
||||
FVector v0 = TransformPoint(tri.v0);
|
||||
FVector v1 = TransformPoint(tri.v1);
|
||||
FVector v2 = TransformPoint(tri.v2);
|
||||
|
||||
DebugPoss = v0;
|
||||
|
||||
@@ -246,6 +243,37 @@ bool IntersectRayTriangle(const Ray& ray, const Triangle& tri, const FVector& ob
|
||||
return t > EPSILON;
|
||||
}
|
||||
|
||||
// Apply location, rotation, and scale transformations.
|
||||
FVector TransformPoint(const FVector& point, const FVector& pos, const IRotator& n64Rot, const FVector& scale) {
|
||||
FVector rot = n64Rot.ToRadians();
|
||||
|
||||
// Apply scale
|
||||
FVector scaled = FVector(point.x * scale.x, point.y * scale.y, point.z * scale.z);
|
||||
|
||||
// Apply rotation (ZXY order, typical in games)
|
||||
float cz = cos(rot.z), sz = sin(rot.z);
|
||||
float cx = cos(rot.x), sx = sin(rot.x);
|
||||
float cy = cos(rot.y), sy = sin(rot.y);
|
||||
|
||||
// Rotate around Z axis
|
||||
float x1 = scaled.x * cz - scaled.y * sz;
|
||||
float y1 = scaled.x * sz + scaled.y * cz;
|
||||
float z1 = scaled.z;
|
||||
|
||||
// Rotate around X axis
|
||||
float y2 = y1 * cx - z1 * sx;
|
||||
float z2 = y1 * sx + z1 * cx;
|
||||
float x2 = x1;
|
||||
|
||||
// Rotate around Y axis
|
||||
float x3 = x2 * cy + z2 * sy;
|
||||
float y3 = y2;
|
||||
float z3 = -x2 * sy + z2 * cy;
|
||||
|
||||
// Apply translation
|
||||
return FVector(x3 + pos.x, y3 + pos.y, z3 + pos.z);
|
||||
}
|
||||
|
||||
bool IntersectRaySphere(const Ray& ray, const FVector& sphereCenter, float radius, float& t) {
|
||||
const float EPSILON = 1e-6f;
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ void Clear(MtxF* mf);
|
||||
|
||||
bool IntersectRayTriangle(const Ray& ray, const Triangle& tri, const FVector& objectPos, float& t);
|
||||
bool IntersectRaySphere(const Ray& ray, const FVector& sphereCenter, float radius, float& t);
|
||||
FVector TransformPoint(const FVector& point, const FVector& pos, const IRotator& n64Rot, const FVector& scale);
|
||||
|
||||
void Editor_MatrixIdentity(Mat4 mtx);
|
||||
void Editor_AddMatrix(Mat4 mtx, int32_t flags);
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
|
||||
#include "EditorMath.h"
|
||||
#include "Gizmo.h"
|
||||
#include "Collision.h"
|
||||
#include "port/Engine.h"
|
||||
#include <controller/controldevice/controller/mapping/keyboard/KeyboardScancodes.h>
|
||||
#include <window/Window.h>
|
||||
|
||||
|
||||
#include "engine/actors/Ship.h"
|
||||
#include "port/Game.h"
|
||||
#include "Handle.h"
|
||||
@@ -26,18 +28,34 @@ extern "C" {
|
||||
namespace Editor {
|
||||
|
||||
void Gizmo::Load() {
|
||||
/* Translate handle collision */
|
||||
RedCollision.Pos = &Pos;
|
||||
RedCollision.Model = handle_Cylinder_mesh;
|
||||
RedCollision.Model = (Gfx*)"__OTR__editor/gizmo/translate_handle_red";
|
||||
|
||||
GreenCollision.Pos = &Pos;
|
||||
GreenCollision.Model = handle_Cylinder_mesh;
|
||||
GreenCollision.Model = (Gfx*)"__OTR__editor/gizmo/translate_handle_green";
|
||||
|
||||
BlueCollision.Pos = &Pos;
|
||||
BlueCollision.Model = handle_Cylinder_mesh;
|
||||
BlueCollision.Model = (Gfx*)"__OTR__editor/gizmo/translate_handle_blue";
|
||||
|
||||
GenerateCollisionMesh(&RedCollision, RedCollision.Model, 0.05f);
|
||||
GenerateCollisionMesh(&GreenCollision, GreenCollision.Model, 0.05f);
|
||||
GenerateCollisionMesh(&BlueCollision, BlueCollision.Model, 0.05f);
|
||||
/* Rotate handle Collision */
|
||||
RedRotateCollision.Pos = &Pos;
|
||||
RedRotateCollision.Model = (Gfx*)"__OTR__editor/gizmo/rot_handle_red";
|
||||
|
||||
GreenRotateCollision.Pos = &Pos;
|
||||
GreenRotateCollision.Model = (Gfx*)"__OTR__editor/gizmo/rot_handle_green";
|
||||
|
||||
BlueRotateCollision.Pos = &Pos;
|
||||
BlueRotateCollision.Model = (Gfx*)"__OTR__editor/gizmo/rot_handle_blue";
|
||||
|
||||
//GenerateCollisionMesh(&RedCollision, (Gfx*)(handle_Cylinder_mesh), 1);
|
||||
GenerateCollisionMesh(&RedCollision, (Gfx*)LOAD_ASSET_RAW(RedCollision.Model), 0.5f);
|
||||
GenerateCollisionMesh(&GreenCollision, (Gfx*)LOAD_ASSET_RAW(GreenCollision.Model), 0.5f);
|
||||
GenerateCollisionMesh(&BlueCollision, (Gfx*)LOAD_ASSET_RAW(BlueCollision.Model), 0.5f);
|
||||
|
||||
GenerateCollisionMesh(&RedRotateCollision, (Gfx*)LOAD_ASSET_RAW(RedRotateCollision.Model), 0.15f);
|
||||
GenerateCollisionMesh(&GreenRotateCollision, (Gfx*)LOAD_ASSET_RAW(GreenRotateCollision.Model), 0.15f);
|
||||
GenerateCollisionMesh(&BlueRotateCollision, (Gfx*)LOAD_ASSET_RAW(BlueRotateCollision.Model), 0.15f);
|
||||
}
|
||||
|
||||
void Gizmo::Tick() {
|
||||
@@ -169,7 +187,6 @@ void Gizmo::Rotate() {
|
||||
|
||||
// Set rotation sensitivity
|
||||
diff = diff * 100.0f;
|
||||
|
||||
switch (SelectedHandle) {
|
||||
case GizmoHandle::X_Axis:
|
||||
_selected->Rot->pitch = (uint16_t)InitialRotation.pitch + diff.x;
|
||||
@@ -227,6 +244,12 @@ void Gizmo::Scale() {
|
||||
void Gizmo::Draw() {
|
||||
if (Enabled) {
|
||||
DrawHandles();
|
||||
DebugCollision(&RedCollision, Pos, {0, 0, 0}, {0.05f, 0.05f, 0.05f}, RedCollision.Triangles);
|
||||
DebugCollision(&BlueCollision, Pos, {90, 0, 0}, {0.05f, 0.05f, 0.05f}, BlueCollision.Triangles);
|
||||
DebugCollision(&GreenCollision, Pos, {0, 90, 0}, {0.05f, 0.05f, 0.05f}, GreenCollision.Triangles);
|
||||
DebugCollision(&RedRotateCollision, Pos, {0, 0, 0}, {0.15f, 0.15f, 0.15f}, RedRotateCollision.Triangles);
|
||||
//DebugCollision((uintptr_t)_selected, Pos, BlueRotateCollision.Triangles);
|
||||
//DebugCollision((uintptr_t)_selected, Pos, GreenRotateCollision.Triangles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +274,7 @@ void Gizmo::DrawHandles() {
|
||||
_gizmoOffset = 8.0f;
|
||||
greenRot = {0, 90, 0};
|
||||
blueRot = {90, 0, 0};
|
||||
scale = {0.05f, 0.05f, 0.05f};
|
||||
scale = {1, 1, 1};
|
||||
break;
|
||||
case TranslationMode::Rotate:
|
||||
center = nullptr; // No All_Axis drag button for Rotation
|
||||
@@ -259,7 +282,7 @@ void Gizmo::DrawHandles() {
|
||||
greenHandle = "__OTR__editor/gizmo/rot_handle_green";
|
||||
redHandle = "__OTR__editor/gizmo/rot_handle_red";
|
||||
_gizmoOffset = 0.0f;
|
||||
scale = {0.2f, 0.2f, 0.2f};
|
||||
scale = {0.15f, 0.15f, 0.15f};
|
||||
break;
|
||||
case TranslationMode::Scale:
|
||||
center = "__OTR__editor/gizmo/center_handle";
|
||||
|
||||
@@ -56,9 +56,13 @@ public:
|
||||
GameObject GreenCollision;
|
||||
GameObject BlueCollision;
|
||||
|
||||
GameObject RedRotateCollision;
|
||||
GameObject GreenRotateCollision;
|
||||
GameObject BlueRotateCollision;
|
||||
|
||||
FVector Pos; // Global scene view
|
||||
IRotator Rot = {0, 0, 0};
|
||||
float AllAxisRadius = 4.0f; // Free move selection radius
|
||||
float AllAxisRadius = 3.0f; // Free move selection radius
|
||||
float PickDistance;
|
||||
FVector _cursorOffset;
|
||||
float _gizmoOffset = 8.0f;
|
||||
|
||||
@@ -69,18 +69,23 @@ void ObjectPicker::DragHandle() {
|
||||
// Is the gizmo being dragged?
|
||||
if (eGizmo.Enabled) {
|
||||
float t;
|
||||
if (IntersectRaySphere(ray, eGizmo.Pos, eGizmo.AllAxisRadius, t)) {
|
||||
eGizmo.SelectedHandle = Gizmo::GizmoHandle::All_Axis;
|
||||
eGizmo._ray = ray.Direction;
|
||||
FVector clickPosition = ray.Origin + ray.Direction * t;
|
||||
eGizmo._cursorOffset = eGizmo.Pos - clickPosition;
|
||||
eGizmo.PickDistance = t;
|
||||
return;
|
||||
|
||||
// No all_axis grab for rotate
|
||||
if (static_cast<Gizmo::TranslationMode>(CVarGetInteger("eGizmoMode", 0)) != Gizmo::TranslationMode::Rotate) {
|
||||
if (IntersectRaySphere(ray, eGizmo.Pos, eGizmo.AllAxisRadius, t)) {
|
||||
eGizmo.SelectedHandle = Gizmo::GizmoHandle::All_Axis;
|
||||
eGizmo._ray = ray.Direction;
|
||||
FVector clickPosition = ray.Origin + ray.Direction * t;
|
||||
eGizmo._cursorOffset = eGizmo.Pos - clickPosition;
|
||||
eGizmo.PickDistance = t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto tri = eGizmo.RedCollision.Triangles.begin(); tri < eGizmo.RedCollision.Triangles.end(); tri++) {
|
||||
float t;
|
||||
FVector pos = FVector(eGizmo.Pos.x, eGizmo.Pos.y, eGizmo.Pos.z - eGizmo._gizmoOffset);
|
||||
//FVector pos = TransformPoint(*tri, FVector(eGizmo.Pos.x, eGizmo.Pos.y, eGizmo.Pos.z - eGizmo._gizmoOffset), {0, 90, 0}, {1, 1, 1});
|
||||
|
||||
if (IntersectRayTriangle(ray, *tri, pos, t)) {
|
||||
eGizmo.SelectedHandle = Gizmo::GizmoHandle::Z_Axis;
|
||||
eGizmo._ray = ray.Direction;
|
||||
@@ -93,7 +98,7 @@ void ObjectPicker::DragHandle() {
|
||||
|
||||
for (auto tri = eGizmo.GreenCollision.Triangles.begin(); tri < eGizmo.GreenCollision.Triangles.end(); tri++) {
|
||||
float t;
|
||||
FVector pos = FVector(eGizmo.Pos.x - eGizmo._gizmoOffset, eGizmo.Pos.y, eGizmo.Pos.z);
|
||||
FVector pos = TransformPoint(FVector(eGizmo.Pos.x - eGizmo._gizmoOffset, eGizmo.Pos.y, eGizmo.Pos.z), {90, 0, 0}, {1, 1, 1});
|
||||
if (IntersectRayTriangle(ray, *tri, pos, t)) {
|
||||
eGizmo.SelectedHandle = Gizmo::GizmoHandle::X_Axis;
|
||||
eGizmo._ray = ray.Direction;
|
||||
|
||||
Reference in New Issue
Block a user