Skip to content

Commit 6c4fe1e

Browse files
committed
Full gizmo implementation
1 parent 2944c49 commit 6c4fe1e

17 files changed

Lines changed: 1377 additions & 66 deletions

HeatSpectra/App.cpp

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ void App::applyGizmoTranslation() {
163163
else if (lastPick.gizmoAxis == PickedGizmoAxis::Z) hitAxis = GizmoAxis::Z;
164164

165165
if (hitAxis != GizmoAxis::None) {
166+
// Auto-detect mode based on stencil value: 3-5 = translate, 6-8 = rotate
167+
if (lastPick.stencilValue >= 3 && lastPick.stencilValue <= 5) {
168+
gizmo->setMode(GizmoMode::Translate);
169+
} else if (lastPick.stencilValue >= 6 && lastPick.stencilValue <= 8) {
170+
gizmo->setMode(GizmoMode::Rotate);
171+
}
172+
166173
// Start drag using original click position
167174
PickingRequest pickReq = modelSelection->getLastPickRequest();
168175
glm::vec3 gizmoPosition = gizmo->calculateGizmoPosition(*resourceManager, *modelSelection);
@@ -174,6 +181,7 @@ void App::applyGizmoTranslation() {
174181
gizmo->startDrag(hitAxis, rayOrigin, rayDir, cachedGizmoPosition);
175182
modelStartPosition = cachedGizmoPosition;
176183
accumulatedTranslation = glm::vec3(0.0f);
184+
accumulatedRotation = 0.0f;
177185

178186
modelSelection->clearLastPickedResult();
179187
}
@@ -183,23 +191,52 @@ void App::applyGizmoTranslation() {
183191
if (!isDraggingGizmo || !modelSelection || !resourceManager)
184192
return;
185193

186-
glm::vec3 currentTranslation = accumulatedTranslation;
187-
glm::vec3 deltaTranslation = currentTranslation - lastAppliedTranslation;
188-
189-
if (glm::length(deltaTranslation) < 1e-6)
190-
return;
191-
192-
// Apply incremental translation to all selected models
193194
const auto& selectedIDs = modelSelection->getSelectedModelIDsRenderThread();
194-
for (uint32_t id : selectedIDs) {
195-
if (id == 1) {
196-
resourceManager->getVisModel().translate(deltaTranslation);
197-
} else if (id == 2) {
198-
resourceManager->getHeatModel().translate(deltaTranslation);
195+
196+
if (gizmo->getMode() == GizmoMode::Translate) {
197+
glm::vec3 currentTranslation = accumulatedTranslation;
198+
glm::vec3 deltaTranslation = currentTranslation - lastAppliedTranslation;
199+
200+
if (glm::length(deltaTranslation) < 1e-6)
201+
return;
202+
203+
// Apply incremental translation to all selected models
204+
for (uint32_t id : selectedIDs) {
205+
if (id == 1) {
206+
resourceManager->getVisModel().translate(deltaTranslation);
207+
} else if (id == 2) {
208+
resourceManager->getHeatModel().translate(deltaTranslation);
209+
}
210+
}
211+
212+
lastAppliedTranslation = currentTranslation;
213+
}
214+
else if (gizmo->getMode() == GizmoMode::Rotate) {
215+
float currentRotation = accumulatedRotation;
216+
float deltaRotation = currentRotation - lastAppliedRotation;
217+
218+
if (fabs(deltaRotation) < 0.01f)
219+
return;
220+
221+
// Get rotation axis
222+
glm::vec3 rotationAxis;
223+
GizmoAxis activeAxis = gizmo->getActiveAxis();
224+
if (activeAxis == GizmoAxis::X) rotationAxis = glm::vec3(1, 0, 0);
225+
else if (activeAxis == GizmoAxis::Y) rotationAxis = glm::vec3(0, 1, 0);
226+
else if (activeAxis == GizmoAxis::Z) rotationAxis = glm::vec3(0, 0, 1);
227+
else return;
228+
229+
// Apply incremental rotation to all selected models around gizmo center
230+
for (uint32_t id : selectedIDs) {
231+
if (id == 1) {
232+
resourceManager->getVisModel().rotate(glm::radians(deltaRotation), rotationAxis, cachedGizmoPosition);
233+
} else if (id == 2) {
234+
resourceManager->getHeatModel().rotate(glm::radians(deltaRotation), rotationAxis, cachedGizmoPosition);
235+
}
199236
}
237+
238+
lastAppliedRotation = currentRotation;
200239
}
201-
202-
lastAppliedTranslation = currentTranslation;
203240
}
204241

205242
void App::handleMouseMove(float mouseX, float mouseY) {
@@ -212,11 +249,15 @@ void App::handleMouseMove(float mouseX, float mouseY) {
212249
glm::vec3 rayOrigin = camera.getPosition();
213250
glm::vec3 rayDir = camera.screenToWorldRay(mouseX, mouseY, swapChainExtent.width, swapChainExtent.height);
214251

215-
// Use cached gizmo position
216-
glm::vec3 newTranslation = gizmo->calculateTranslationDelta(rayOrigin, rayDir, cachedGizmoPosition, gizmo->getActiveAxis());
217-
218-
// Store accumulated translation
219-
accumulatedTranslation = newTranslation;
252+
// Auto-detect based on active mode
253+
if (gizmo->getMode() == GizmoMode::Translate) {
254+
glm::vec3 newTranslation = gizmo->calculateTranslationDelta(rayOrigin, rayDir, cachedGizmoPosition, gizmo->getActiveAxis());
255+
accumulatedTranslation = newTranslation;
256+
}
257+
else if (gizmo->getMode() == GizmoMode::Rotate) {
258+
float angle = gizmo->calculateRotationDelta(rayOrigin, rayDir, cachedGizmoPosition, gizmo->getActiveAxis());
259+
accumulatedRotation = angle;
260+
}
220261
}
221262
}
222263

@@ -228,6 +269,8 @@ void App::handleMouseRelease(int button, float mouseX, float mouseY) {
228269
gizmo->endDrag();
229270
accumulatedTranslation = glm::vec3(0.0f);
230271
lastAppliedTranslation = glm::vec3(0.0f);
272+
accumulatedRotation = 0.0f;
273+
lastAppliedRotation = 0.0f;
231274
}
232275
}
233276

HeatSpectra/App.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class App {
9696
glm::vec3 modelStartPosition{0.0f};
9797
glm::vec3 accumulatedTranslation{0.0f}; // UI thread writes total translation
9898
glm::vec3 lastAppliedTranslation{0.0f}; // Render thread tracks what's been applied
99+
float accumulatedRotation = 0.0f; // UI thread writes total rotation angle (degrees)
100+
float lastAppliedRotation = 0.0f; // Render thread tracks applied rotation
99101
glm::vec3 cachedGizmoPosition{0.0f}; // Cached during drag to prevent stuttering
100102
bool isShuttingDown;
101103

HeatSpectra/GBuffer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,11 +1336,11 @@ void GBuffer::createIntrinsicOverlayPipeline(VkExtent2D extent) {
13361336
dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
13371337
dynamicState.pDynamicStates = dynamicStates.data();
13381338

1339-
// Push constant for translation offset
1339+
// Push constant for model matrix
13401340
VkPushConstantRange pushConstantRange{};
13411341
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
13421342
pushConstantRange.offset = 0;
1343-
pushConstantRange.size = sizeof(glm::vec3);
1343+
pushConstantRange.size = sizeof(glm::mat4);
13441344

13451345
VkPipelineLayoutCreateInfo layoutInfo{};
13461346
layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
@@ -1641,14 +1641,14 @@ void GBuffer::recordCommandBuffer(ResourceManager& resourceManager, HeatSystem&
16411641
// Reset depth bias
16421642
vkCmdSetDepthBias(commandBuffer, 0.0f, 0.0f, 0.0f);
16431643

1644-
// Draw commonsub model with visModel's translation offset
1644+
// Draw commonsub model with visModel's full transformation
16451645
if (drawCommonSubdivision) {
16461646
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, intrinsicOverlayPipeline);
16471647

1648-
// Pass visModel's translation offset so commonSub follows it
1649-
glm::vec3 offset = resourceManager.getVisModel().getTranslationOffset();
1648+
// Pass visModel's full model matrix so commonSub follows translation AND rotation
1649+
glm::mat4 modelMatrix = resourceManager.getVisModel().getModelMatrix();
16501650
vkCmdPushConstants(commandBuffer, intrinsicOverlayPipelineLayout,
1651-
VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::vec3), &offset);
1651+
VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &modelMatrix);
16521652

16531653
vkCmdSetDepthBias(commandBuffer, 0.1f, 0.0f, 0.1f);
16541654

0 commit comments

Comments
 (0)