mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-07-08 22:45:12 -04:00
Add all axis move (freemove)
This commit is contained in:
@@ -226,6 +226,43 @@ bool IntersectRayTriangle(const Ray& ray, const Triangle& tri, const FVector& ob
|
||||
return t > EPSILON;
|
||||
}
|
||||
|
||||
bool IntersectRaySphere(const Ray& ray, const FVector& sphereCenter, float radius, float& t) {
|
||||
const float EPSILON = 1e-6f;
|
||||
|
||||
// Vector from ray origin to sphere center
|
||||
FVector oc = ray.Origin - sphereCenter;
|
||||
|
||||
// Quadratic equation coefficients
|
||||
float a = ray.Direction.Dot(ray.Direction);
|
||||
float b = 2.0f * oc.Dot(ray.Direction);
|
||||
float c = oc.Dot(oc) - (radius * radius);
|
||||
|
||||
// Compute discriminant
|
||||
float discriminant = (b * b) - (4 * a * c);
|
||||
|
||||
// No intersection if discriminant is negative
|
||||
if (discriminant < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute nearest intersection point
|
||||
float sqrtD = sqrtf(discriminant);
|
||||
float t0 = (-b - sqrtD) / (2.0f * a);
|
||||
float t1 = (-b + sqrtD) / (2.0f * a);
|
||||
|
||||
// Select the closest valid intersection
|
||||
if (t0 > EPSILON) {
|
||||
t = t0;
|
||||
return true;
|
||||
} else if (t1 > EPSILON) {
|
||||
t = t1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // Sphere is behind the ray origin
|
||||
}
|
||||
|
||||
|
||||
bool FindClosestObject(const Ray& ray, const std::vector<GameObject>& objects, GameObject& outObject, float& outDistance) {
|
||||
float closestDist = std::numeric_limits<float>::max();
|
||||
bool found = false;
|
||||
|
||||
@@ -49,6 +49,7 @@ void Copy(MtxF* src, MtxF* dest);
|
||||
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);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -42,67 +42,15 @@ void Gizmo::Load() {
|
||||
}
|
||||
|
||||
void Gizmo::Tick() {
|
||||
if (!Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(SelectedHandle) {
|
||||
case GizmoHandle::X_Axis:
|
||||
Gizmo::Translate();
|
||||
break;
|
||||
case GizmoHandle::Y_Axis:
|
||||
Gizmo::Translate();
|
||||
break;
|
||||
case GizmoHandle::Z_Axis:
|
||||
Gizmo::Translate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<FVector, FVector> Gizmo::GetBoundingBox(GizmoHandle handle) {
|
||||
FVector min = Pos + HandleOffsets[(int)handle] - FVector(HandleSize, HandleSize, HandleSize);
|
||||
FVector max = Pos + HandleOffsets[(int)handle] + FVector(HandleSize, HandleSize, HandleSize);
|
||||
return {min, max};
|
||||
}
|
||||
|
||||
void Gizmo::StartManipulation(GizmoHandle handle) {
|
||||
printf("HANDLE SELECTED %d\n", (s32)handle);
|
||||
auto wnd = GameEngine::Instance->context->GetWindow();
|
||||
|
||||
if (wnd->GetMouseState(Ship::LUS_MOUSE_BTN_LEFT)) {
|
||||
switch(handle) {
|
||||
case GizmoHandle::None:
|
||||
break;
|
||||
case GizmoHandle::Center:
|
||||
break;
|
||||
case GizmoHandle::X_Axis:
|
||||
break;
|
||||
case GizmoHandle::Y_Axis:
|
||||
break;
|
||||
case GizmoHandle::Z_Axis:
|
||||
break;
|
||||
}
|
||||
if (Enabled) {
|
||||
Gizmo::Translate();
|
||||
}
|
||||
}
|
||||
|
||||
// Makes the gizmo visible
|
||||
void Gizmo::Enable(GameObject* object, Ray ray) {
|
||||
static float length = 180.0f; // Default value
|
||||
|
||||
// static AActor* lastSelected = nullptr;
|
||||
// if (object != lastSelected) {
|
||||
// length = sqrt(
|
||||
// pow(object->Pos[0] - cameras[0].pos[0], 2) +
|
||||
// pow(object->Pos[1] - cameras[0].pos[1], 2) +
|
||||
// pow(object->Pos[2] - cameras[0].pos[2], 2)
|
||||
// );
|
||||
// lastSelected = object;
|
||||
// }
|
||||
|
||||
//_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;
|
||||
_ray = ray.Direction;
|
||||
Pos = FVector(
|
||||
@@ -129,9 +77,14 @@ void Gizmo::Translate() {
|
||||
);
|
||||
|
||||
switch(SelectedHandle) {
|
||||
case GizmoHandle::All_Axis:
|
||||
_selected->Pos->x = (cameras[0].pos[0] + _ray.x * PickDistance) + _cursorOffset.x;
|
||||
_selected->Pos->y = (cameras[0].pos[1] + _ray.y * PickDistance) + _cursorOffset.y;
|
||||
_selected->Pos->z = (cameras[0].pos[2] + _ray.z * PickDistance) + _cursorOffset.z;
|
||||
break;
|
||||
case GizmoHandle::X_Axis:
|
||||
_selected->Pos->x = (cameras[0].pos[0] + _ray.x * length) + _cursorOffset.x;
|
||||
break;
|
||||
break;
|
||||
case GizmoHandle::Y_Axis:
|
||||
_selected->Pos->y = (cameras[0].pos[1] + _ray.y * length) + _cursorOffset.y;
|
||||
break;
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
|
||||
enum class GizmoHandle {
|
||||
None,
|
||||
Center,
|
||||
All_Axis,
|
||||
X_Axis,
|
||||
Y_Axis,
|
||||
Z_Axis
|
||||
@@ -22,14 +22,11 @@ public:
|
||||
void Draw();
|
||||
void Load();
|
||||
|
||||
void StartManipulation(GizmoHandle handle);
|
||||
void Enable(GameObject* object, Ray ray);
|
||||
void Translate();
|
||||
void DrawHandles();
|
||||
|
||||
|
||||
std::pair<FVector, FVector> GetBoundingBox(GizmoHandle handle);
|
||||
|
||||
bool Enabled;
|
||||
GizmoHandle SelectedHandle;
|
||||
|
||||
@@ -38,7 +35,9 @@ public:
|
||||
GameObject BlueCollision;
|
||||
|
||||
FVector Pos; // Global scene view
|
||||
float _gizmoOffset = 5.0f;
|
||||
float _gizmoOffset = 8.0f;
|
||||
float AllAxisRadius = 4.0f; // Free move selection radius
|
||||
float PickDistance;
|
||||
FVector _cursorOffset;
|
||||
FVector RedPos = {0, 0, -_gizmoOffset}; // Local model view
|
||||
FVector GreenPos = {-_gizmoOffset, 0, 0}; // Local model view
|
||||
@@ -46,12 +45,6 @@ public:
|
||||
|
||||
float HandleSize = 2.0f;
|
||||
|
||||
FVector HandleOffsets[4] = {
|
||||
{0, 0, 0}, // Center Button
|
||||
{0, 0, -5}, // X-Axis (Red)
|
||||
{0, 5, 0}, // Y-Axis (Green)
|
||||
{-5, 0, 0} // Z-Axis (Blue)
|
||||
};
|
||||
FVector _ray;
|
||||
GameObject* _selected = nullptr;
|
||||
private:
|
||||
|
||||
@@ -67,14 +67,22 @@ 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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (IntersectRayTriangle(ray, *tri, pos, t)) {
|
||||
//eGizmo.StartManipulation(Gizmo::GizmoHandle::X_Axis);
|
||||
eGizmo.SelectedHandle = Gizmo::GizmoHandle::Z_Axis;
|
||||
eGizmo._ray = ray.Direction;
|
||||
|
||||
FVector clickPosition = ray.Origin + ray.Direction * t;
|
||||
eGizmo._cursorOffset = eGizmo.Pos - clickPosition;
|
||||
return; // Stop checking objects if we selected a Gizmo handle
|
||||
@@ -85,9 +93,10 @@ void ObjectPicker::DragHandle() {
|
||||
float t;
|
||||
FVector pos = FVector(eGizmo.Pos.x - eGizmo._gizmoOffset, eGizmo.Pos.y, eGizmo.Pos.z);
|
||||
if (IntersectRayTriangle(ray, *tri, pos, t)) {
|
||||
//eGizmo.StartManipulation(Gizmo::GizmoHandle::Y_Axis);
|
||||
eGizmo.SelectedHandle = Gizmo::GizmoHandle::X_Axis;
|
||||
eGizmo._ray = ray.Direction;
|
||||
FVector clickPosition = ray.Origin + ray.Direction * t;
|
||||
eGizmo._cursorOffset = eGizmo.Pos - clickPosition;
|
||||
return; // Stop checking objects if we selected a Gizmo handle
|
||||
}
|
||||
}
|
||||
@@ -98,6 +107,8 @@ void ObjectPicker::DragHandle() {
|
||||
if (IntersectRayTriangle(ray, *tri, pos, t)) {
|
||||
eGizmo.SelectedHandle = Gizmo::GizmoHandle::Y_Axis;
|
||||
eGizmo._ray = ray.Direction;
|
||||
FVector clickPosition = ray.Origin + ray.Direction * t;
|
||||
eGizmo._cursorOffset = eGizmo.Pos - clickPosition;
|
||||
return; // Stop checking objects if we selected a Gizmo handle
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user