Add all axis move (freemove)

This commit is contained in:
MegaMech
2025-03-04 12:49:32 -07:00
parent 0d02f8c3af
commit 6dfa748392
5 changed files with 65 additions and 70 deletions
+37
View File
@@ -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;
+1
View File
@@ -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);
+9 -56
View File
@@ -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;
+4 -11
View File
@@ -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:
+14 -3
View File
@@ -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
}
}