diff --git a/src/engine/World.cpp b/src/engine/World.cpp index 5f469b255..8e20806ff 100644 --- a/src/engine/World.cpp +++ b/src/engine/World.cpp @@ -119,11 +119,11 @@ AActor* World::AddActor(AActor* actor) { Actors.push_back(actor); if (actor->Model != NULL) { - gEditor.AddObject(actor->Name, (FVector*) &actor->Pos, (IRotator*)&actor->Rot, nullptr, + gEditor.AddObject(actor->Name, (FVector*) &actor->Pos, (IRotator*)&actor->Rot, &actor->Scale, (Gfx*) LOAD_ASSET_RAW(actor->Model), 1.0f, Editor::GameObject::CollisionType::VTX_INTERSECT, 0.0f, (int32_t*) &actor->Type, 0); } else { - gEditor.AddObject(actor->Name, (FVector*) &actor->Pos, (IRotator*)&actor->Rot, nullptr, nullptr, 1.0f, Editor::GameObject::CollisionType::VTX_INTERSECT, 0.0f, (int32_t*)&actor->Type, 0); + gEditor.AddObject(actor->Name, (FVector*) &actor->Pos, (IRotator*)&actor->Rot, &actor->Scale, nullptr, 1.0f, Editor::GameObject::CollisionType::VTX_INTERSECT, 0.0f, (int32_t*)&actor->Type, 0); } return Actors.back(); } diff --git a/src/engine/actors/SpaghettiShip.h b/src/engine/actors/SpaghettiShip.h index 8758f368c..70bd047d7 100644 --- a/src/engine/actors/SpaghettiShip.h +++ b/src/engine/actors/SpaghettiShip.h @@ -21,6 +21,4 @@ public: FVector Spawn; IRotator WheelRot = {0, 0, 0}; -private: - f32 scale; }; diff --git a/src/engine/editor/Editor.cpp b/src/engine/editor/Editor.cpp index efe1d7ecf..ce3e7c7ad 100644 --- a/src/engine/editor/Editor.cpp +++ b/src/engine/editor/Editor.cpp @@ -77,6 +77,7 @@ namespace Editor { if (!isMouseDown && wasMouseDown) { // Mouse just released (Released state) eObjectPicker.eGizmo.SelectedHandle = Gizmo::GizmoHandle::None; + eObjectPicker.eGizmo.ManipulationStart = true; if (!isDragging) { eObjectPicker.SelectObject(eGameObjects); } diff --git a/src/engine/editor/Gizmo.cpp b/src/engine/editor/Gizmo.cpp index 86c90fa0d..10fd31919 100644 --- a/src/engine/editor/Gizmo.cpp +++ b/src/engine/editor/Gizmo.cpp @@ -149,48 +149,77 @@ f32 Gizmo::SnapToSurface(FVector* pos) { } void Gizmo::Rotate() { - float length = 180.0f; - float sensitivity = 0.2f; + FVector cam = FVector(cameras[0].pos[0], cameras[0].pos[1], cameras[0].pos[2]); - if (_selected->Rot == nullptr) { + if (_selected == nullptr || _selected->Rot == nullptr) { return; } - length = sqrt( - 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) - ); + // Store initial scale at the beginning of the drag + if (ManipulationStart) { + ManipulationStart = false; + InitialRotation = *_selected->Rot; // Store initial rotation + } - FVector cameraPos = { - cameras[0].pos[0] + _ray.x * length, - cameras[0].pos[1] + _ray.y * length, - cameras[0].pos[2] + _ray.z * length, - }; + // Initial click position + FVector clickPos = *_selected->Pos - _cursorOffset; - float angle = CalculateAngle(_cursorOffset, cameraPos) * 100; + // Calculate difference + FVector diff = (cam + _ray * PickDistance) - clickPos; - // printf("start %f %f %f end %f %f %f angle %f\n", _cursorOffset.x, _cursorOffset.y, _cursorOffset.z, cameraPos.x, cameraPos.y, cameraPos.z, angle); - // Depending on which axis or handle you want to rotate, apply rotation. - switch(SelectedHandle) { - case GizmoHandle::All_Axis: - _selected->Rot->pitch = _selected->Rot->pitch + angle; - _selected->Rot->yaw = _selected->Rot->yaw + angle; - break; + // Set rotation sensitivity + diff = diff * 100.0f; + + switch (SelectedHandle) { case GizmoHandle::X_Axis: - _selected->Rot->pitch = _selected->Rot->pitch + angle; + _selected->Rot->pitch = (uint16_t)InitialRotation.pitch + diff.x; break; case GizmoHandle::Y_Axis: - _selected->Rot->yaw = _selected->Rot->yaw + angle; + _selected->Rot->yaw = (uint16_t)InitialRotation.yaw + diff.y; break; case GizmoHandle::Z_Axis: - _selected->Rot->roll = _selected->Rot->roll + angle; + _selected->Rot->roll = (uint16_t)InitialRotation.roll + diff.z; break; } } void Gizmo::Scale() { + FVector cam = FVector(cameras[0].pos[0], cameras[0].pos[1], cameras[0].pos[2]); + if (_selected == nullptr || _selected->Scale == nullptr) { + return; + } + // Store initial scale at the beginning of the drag + if (ManipulationStart) { + ManipulationStart = false; + InitialScale = *_selected->Scale; + } + + // Initial click position + FVector clickPos = *_selected->Pos - _cursorOffset; + + // Calculate difference + FVector diff = (cam + _ray * PickDistance) - clickPos; + + // Lower scaling sensitivity + diff = diff * 0.01f; + + switch (SelectedHandle) { + case GizmoHandle::X_Axis: + _selected->Scale->x = InitialScale.x + -diff.x; + break; + case GizmoHandle::Y_Axis: + _selected->Scale->y = InitialScale.y + diff.y; + break; + case GizmoHandle::Z_Axis: + _selected->Scale->z = InitialScale.z + -diff.z; + break; + case GizmoHandle::All_Axis: + _selected->Scale->x = InitialScale.x + -diff.x; + _selected->Scale->y = InitialScale.y + diff.y; + _selected->Scale->z = InitialScale.z + -diff.z; + break; + } } void Gizmo::Draw() { diff --git a/src/engine/editor/Gizmo.h b/src/engine/editor/Gizmo.h index ad8aec724..e387ccc9d 100644 --- a/src/engine/editor/Gizmo.h +++ b/src/engine/editor/Gizmo.h @@ -47,6 +47,9 @@ public: TrackDimensions dimensions; bool Enabled; + bool ManipulationStart = true; + FVector InitialScale = {1, 1, 1}; + IRotator InitialRotation = {0, 0, 0}; GizmoHandle SelectedHandle; GameObject RedCollision; diff --git a/src/engine/editor/ObjectPicker.cpp b/src/engine/editor/ObjectPicker.cpp index 689433a24..c2e682a87 100644 --- a/src/engine/editor/ObjectPicker.cpp +++ b/src/engine/editor/ObjectPicker.cpp @@ -86,6 +86,7 @@ void ObjectPicker::DragHandle() { eGizmo._ray = ray.Direction; FVector clickPosition = ray.Origin + ray.Direction * t; eGizmo._cursorOffset = eGizmo.Pos - clickPosition; + eGizmo.PickDistance = t; return; // Stop checking objects if we selected a Gizmo handle } } @@ -98,6 +99,7 @@ void ObjectPicker::DragHandle() { eGizmo._ray = ray.Direction; FVector clickPosition = ray.Origin + ray.Direction * t; eGizmo._cursorOffset = eGizmo.Pos - clickPosition; + eGizmo.PickDistance = t; return; // Stop checking objects if we selected a Gizmo handle } } @@ -110,6 +112,7 @@ void ObjectPicker::DragHandle() { eGizmo._ray = ray.Direction; FVector clickPosition = ray.Origin + ray.Direction * t; eGizmo._cursorOffset = eGizmo.Pos - clickPosition; + eGizmo.PickDistance = t; return; // Stop checking objects if we selected a Gizmo handle } }