@@ -1211,7 +1211,7 @@ class UISampleApp final : public examples::SimpleWindowedApplication
12111211projection.endInputProcessing ();
12121212
12131213if (vCount)
1214- camera->manipulate ({ virtualEvents.data (), vCount }, ICamera::Local );
1214+ camera->manipulate ({ virtualEvents.data (), vCount });
12151215}
12161216
12171217m_ui.manager ->update (params);
@@ -1350,7 +1350,6 @@ class UISampleApp final : public examples::SimpleWindowedApplication
13501350
13511351const bool isCameraGimbalTarget = modelIx; // I assume scene demo model is 0th ix, left are planar cameras
13521352ICamera* const targetGimbalManipulationCamera = isCameraGimbalTarget ? m_planarProjections[modelIx - 1u ]->getCamera () : nullptr ;
1353- bool discard = isCameraGimbalTarget && mCurrentGizmoOperation != ImGuizmo::TRANSLATE; // discard WiP stuff
13541353
13551354// if we try to manipulate a camera which appears to be the same camera we see scene from then obvsly it doesn't make sense to manipulate its gizmo so we skip it
13561355// EDIT: it actually makes some sense if you assume render planar view is rendered with ortho projection, but we would need to add imguizmo controller virtual map
@@ -1373,98 +1372,94 @@ class UISampleApp final : public examples::SimpleWindowedApplication
13731372
13741373imguizmoModel.outTRS = imguizmoModel.inTRS ;
13751374{
1376- const bool success = ImGuizmo::Manipulate (&imguizmoPlanar.view [0 ][0 ], &imguizmoPlanar.projection [0 ][0 ], mCurrentGizmoOperation , mCurrentGizmoMode , &imguizmoModel.outTRS [0 ][0 ], &imguizmoModel.outDeltaTRS [0 ][0 ], useSnap ? &snap[0 ] : nullptr );
1375+ const bool success = ImGuizmo::Manipulate (&imguizmoPlanar.view [0 ][0 ], &imguizmoPlanar.projection [0 ][0 ], ImGuizmo::OPERATION::UNIVERSAL , mCurrentGizmoMode , &imguizmoModel.outTRS [0 ][0 ], &imguizmoModel.outDeltaTRS [0 ][0 ], useSnap ? &snap[0 ] : nullptr );
13771376
13781377if (success)
13791378{
1380- ++manipulationCounter;
1381- discard |= manipulationCounter > 1 ;
1382-
1383- /*
1384-
1385- NOTE to self & TODO: I must be killing ImGuizmo last invocation cache or something with my delta events (or at least I dont
1386- see now where I'm *maybe* using its API incorrectly, the problem is I get translation parts in delta matrix when doing
1387- rotations hence it glitches my cameras -> on the other hand I can see it kinda correctly outputs the delta matrix when
1388- gc model is bound
1389-
1390- auto postprocessDeltaManipulation = [](const float32_t4x4& inDeltaMatrix, float32_t4x4& outDeltaMatrix, ImGuizmo::OPERATION operation) -> void
1379+ if (targetGimbalManipulationCamera)
13911380{
1392- struct
1393- {
1394- float32_t3 dTranslation, dRotation, dScale;
1395- } world;
1381+ boundCameraToManipulate = smart_refctd_ptr<ICamera>(targetGimbalManipulationCamera);
1382+ boundPlanarCameraIxToManipulate = modelIx - 1u ;
13961383
1397- ImGuizmo::DecomposeMatrixToComponents(&inDeltaMatrix[0][0], &world.dTranslation[0], &world.dRotation[0], &world.dScale[0] );
1384+ auto & gimbal = (ICamera::CGimbal&)targetGimbalManipulationCamera-> getGimbal ( );
13981385
1399- if (operation == ImGuizmo::TRANSLATE)
1400- {
1401- world.dRotation = float32_t3(0, 0, 0);
1402- }
1403- else if (operation == ImGuizmo::ROTATE)
1386+ struct
14041387{
1405- world.dTranslation = float32_t3(0, 0, 0);
1406- }
1407-
1408- ImGuizmo::RecomposeMatrixFromComponents(&world.dTranslation[0], &world.dRotation[0], &world.dScale[0], &outDeltaMatrix[0][0]);
1409- };
1410-
1411- postprocessDeltaManipulation(imguizmoModel.outDeltaTRS, imguizmoModel.outDeltaTRS, mCurrentGizmoOperation);
1412- */
1388+ float32_t3 t, r, s;
1389+ } out, delta;
14131390
1414- if (!discard)
1415- {
1416- if (targetGimbalManipulationCamera)
1391+ ImGuizmo::DecomposeMatrixToComponents (&imguizmoModel.outTRS [0 ][0 ], &out.t [0 ], &out.r [0 ], &out.s [0 ]);
1392+ ImGuizmo::DecomposeMatrixToComponents (&imguizmoModel.outDeltaTRS [0 ][0 ], &delta.t [0 ], &delta.r [0 ], &delta.s [0 ]);
14171393{
1418- boundCameraToManipulate = smart_refctd_ptr<ICamera>(targetGimbalManipulationCamera);
1419- boundPlanarCameraIxToManipulate = modelIx - 1u ;
1420-
1421- /*
1422- testing imguizmo controller for target camera, we use delta world imguizmo TRS matrix to generate virtual events
1423- */
1424-
1394+ std::vector<CVirtualGimbalEvent> virtualEvents;
1395+
1396+ auto requestMagnitudeUpdateWithScalar = [&](float signPivot, float dScalar, float dMagnitude, auto positive, auto negative)
14251397{
1426- static std::vector<CVirtualGimbalEvent> virtualEvents (0x45 );
1427- uint32_t vCount = {};
1428-
1429- targetGimbalManipulationCamera->beginInputProcessing (m_nextPresentationTimestamp);
1398+ if (dScalar != signPivot)
14301399{
1431- targetGimbalManipulationCamera->process (nullptr , vCount);
1432-
1433- if (virtualEvents.size () < vCount)
1434- virtualEvents.resize (vCount);
1400+ auto & ev = virtualEvents.emplace_back ();
1401+ auto code = (dScalar > signPivot) ? positive : negative;
14351402
1436- IGimbalController::SUpdateParameters params;
1437- params.imguizmoEvents = { { imguizmoModel.outDeltaTRS } };
1438- targetGimbalManipulationCamera->process (virtualEvents.data (), vCount, params);
1403+ ev.type = code;
1404+ ev.magnitude += dMagnitude;
14391405}
1440- targetGimbalManipulationCamera->endInputProcessing ();
1406+ };
1407+
1408+ // Delta translation impulse
1409+ requestMagnitudeUpdateWithScalar (0 .f , delta.t [0 ], std::abs (delta.t [0 ]), CVirtualGimbalEvent::VirtualEventType::MoveRight, CVirtualGimbalEvent::VirtualEventType::MoveLeft);
1410+ requestMagnitudeUpdateWithScalar (0 .f , delta.t [1 ], std::abs (delta.t [1 ]), CVirtualGimbalEvent::VirtualEventType::MoveUp, CVirtualGimbalEvent::VirtualEventType::MoveDown);
1411+ requestMagnitudeUpdateWithScalar (0 .f , delta.t [2 ], std::abs (delta.t [2 ]), CVirtualGimbalEvent::VirtualEventType::MoveForward, CVirtualGimbalEvent::VirtualEventType::MoveBackward);
1412+
1413+ // Delta rotation impulse
1414+ requestMagnitudeUpdateWithScalar (0 .f , delta.r [0 ], std::abs (delta.r [0 ]), CVirtualGimbalEvent::VirtualEventType::TiltUp, CVirtualGimbalEvent::VirtualEventType::TiltDown);
1415+ requestMagnitudeUpdateWithScalar (0 .f , delta.r [1 ], std::abs (delta.r [1 ]), CVirtualGimbalEvent::VirtualEventType::PanRight, CVirtualGimbalEvent::VirtualEventType::PanLeft);
1416+ requestMagnitudeUpdateWithScalar (0 .f , delta.r [2 ], std::abs (delta.r [2 ]), CVirtualGimbalEvent::VirtualEventType::RollRight, CVirtualGimbalEvent::VirtualEventType::RollLeft);
1417+
1418+ // Delta scale impulse
1419+ requestMagnitudeUpdateWithScalar (1 .f , delta.s [0 ], std::abs (delta.s [0 ]), CVirtualGimbalEvent::VirtualEventType::ScaleXInc, CVirtualGimbalEvent::VirtualEventType::ScaleXDec);
1420+ requestMagnitudeUpdateWithScalar (1 .f , delta.s [1 ], std::abs (delta.s [1 ]), CVirtualGimbalEvent::VirtualEventType::ScaleYInc, CVirtualGimbalEvent::VirtualEventType::ScaleYDec);
1421+ requestMagnitudeUpdateWithScalar (1 .f , delta.s [2 ], std::abs (delta.s [2 ]), CVirtualGimbalEvent::VirtualEventType::ScaleZInc, CVirtualGimbalEvent::VirtualEventType::ScaleZDec);
1422+
1423+ constexpr auto TESSTTSS = CVirtualGimbalEvent::All;
1424+ const auto impulse = gimbal.accumulate <TESSTTSS>(virtualEvents);
1425+
1426+ assert (impulse.dVirtualTranslate == float64_t3 (delta.t ));
1427+ assert (impulse.dVirtualRotation == float64_t3 (delta.r ));
1428+ assert (impulse.dVirtualScale == float64_t3 (delta.s ));
14411429
1442- if (vCount)
1443- {
1444- const float pMoveSpeed = targetGimbalManipulationCamera->getMoveSpeedScale ();
1445- const float pRotationSpeed = targetGimbalManipulationCamera->getRotationSpeedScale ();
1430+ const auto vCount = virtualEvents.size ();
14461431
1447- // I start to think controller should be able to set sensitivity to scale magnitudes of generated events
1448- // in order for camera to not keep any magnitude scalars like move or rotation speed scales
1432+ if (vCount)
1433+ {
1434+ const float pMoveSpeed = targetGimbalManipulationCamera->getMoveSpeedScale ();
1435+ const float pRotationSpeed = targetGimbalManipulationCamera->getRotationSpeedScale ();
14491436
1450- targetGimbalManipulationCamera-> setMoveSpeedScale ( 1 );
1451- targetGimbalManipulationCamera-> setRotationSpeedScale ( 1 );
1437+ // I start to think controller should be able to set sensitivity to scale magnitudes of generated events
1438+ // in order for camera to not keep any magnitude scalars like move or rotation speed scales
14521439
1453- // NOTE: generated events from ImGuizmo controller are always in world space!
1454- targetGimbalManipulationCamera->manipulate ({ virtualEvents. data (), vCount }, ICamera::World );
1440+ targetGimbalManipulationCamera-> setMoveSpeedScale ( 1 );
1441+ targetGimbalManipulationCamera->setRotationSpeedScale ( 1 );
14551442
1456- targetGimbalManipulationCamera->setMoveSpeedScale (pMoveSpeed);
1457- targetGimbalManipulationCamera->setRotationSpeedScale (pRotationSpeed);
1458- }
1443+ /*
1444+ new = old * delta
1445+ delta^(-1) * new = old
1446+ */
1447+
1448+ const auto referenceFrame = getCastedMatrix<float64_t >(mul (inverse (imguizmoModel.outDeltaTRS ), imguizmoModel.outTRS ));
1449+ targetGimbalManipulationCamera->manipulate ({ virtualEvents.data (), vCount }, &referenceFrame);
1450+
1451+ targetGimbalManipulationCamera->setMoveSpeedScale (pMoveSpeed);
1452+ targetGimbalManipulationCamera->setRotationSpeedScale (pRotationSpeed);
14591453}
1454+
14601455}
1461- else
1462- {
1463- // again, for scene demo model full affine transformation without limits is assumed
1464- m_model = float32_t3x4 ( hlsl::transpose (imguizmoModel. outTRS ));
1465- boundCameraToManipulate = nullptr ;
1466- boundPlanarCameraIxToManipulate = std:: nullopt ;
1467- }
1456+ }
1457+ else
1458+ {
1459+ // again, for scene demo model full affine transformation without limits is assumed
1460+ m_model = float32_t3x4 ( hlsl::transpose (imguizmoModel. outTRS )) ;
1461+ boundCameraToManipulate = nullptr ;
1462+ boundPlanarCameraIxToManipulate = std:: nullopt ;
14681463}
14691464}
14701465
@@ -2102,8 +2097,7 @@ class UISampleApp final : public examples::SimpleWindowedApplication
21022097boundCameraToManipulate->setMoveSpeedScale (1 );
21032098boundCameraToManipulate->setRotationSpeedScale (1 );
21042099
2105- // NOTE: generated events from ImGuizmo controller are always in world space!
2106- boundCameraToManipulate->manipulate ({ virtualEvents.data (), vCount }, ICamera::World);
2100+ boundCameraToManipulate->manipulate ({ virtualEvents.data (), vCount });
21072101
21082102boundCameraToManipulate->setMoveSpeedScale (pmSpeed);
21092103boundCameraToManipulate->setRotationSpeedScale (prSpeed);
0 commit comments