@@ -695,7 +695,47 @@ void editor::SceneRender::mouseReleaseEvent(float x, float y){
695695 }
696696}
697697
698- void editor::SceneRender::mouseDragEvent (float x, float y, float origX, float origY, Project* project, size_t sceneId, std::vector<Entity> selEntities, bool disableSelection, bool invertRotationSnap){
698+ Vector3 editor::SceneRender::getMatrixScale (const Matrix4& matrix){
699+ return Vector3 (
700+ Vector3 (matrix[0 ][0 ], matrix[0 ][1 ], matrix[0 ][2 ]).length (),
701+ Vector3 (matrix[1 ][0 ], matrix[1 ][1 ], matrix[1 ][2 ]).length (),
702+ Vector3 (matrix[2 ][0 ], matrix[2 ][1 ], matrix[2 ][2 ]).length ());
703+ }
704+
705+ bool editor::SceneRender::isCorner2DGizmoSide (Gizmo2DSideSelected side){
706+ return side == Gizmo2DSideSelected::NX_NY || side == Gizmo2DSideSelected::NX_PY ||
707+ side == Gizmo2DSideSelected::PX_NY || side == Gizmo2DSideSelected::PX_PY;
708+ }
709+
710+ bool editor::SceneRender::gizmo2DSideUsesNegativeX (Gizmo2DSideSelected side){
711+ return side == Gizmo2DSideSelected::NX_NY || side == Gizmo2DSideSelected::NX_PY;
712+ }
713+
714+ bool editor::SceneRender::gizmo2DSideUsesNegativeY (Gizmo2DSideSelected side){
715+ return side == Gizmo2DSideSelected::NX_NY || side == Gizmo2DSideSelected::PX_NY;
716+ }
717+
718+ Vector2 editor::SceneRender::lockObject2DAspectRatio (const Vector2& startSize, const Vector2& candidateSize){
719+ if (startSize.x <= 0 .0f || startSize.y <= 0 .0f ){
720+ return candidateSize;
721+ }
722+
723+ float scaleX = candidateSize.x / startSize.x ;
724+ float scaleY = candidateSize.y / startSize.y ;
725+ float chosenScale = (std::fabs (scaleX - 1 .0f ) >= std::fabs (scaleY - 1 .0f )) ? scaleX : scaleY;
726+
727+ if (!std::isfinite (chosenScale)){
728+ return candidateSize;
729+ }
730+
731+ if (chosenScale < 0 .0f ){
732+ chosenScale = 0 .0f ;
733+ }
734+
735+ return Vector2 (startSize.x * chosenScale, startSize.y * chosenScale);
736+ }
737+
738+ void editor::SceneRender::mouseDragEvent (float x, float y, float origX, float origY, Project* project, size_t sceneId, std::vector<Entity> selEntities, bool disableSelection, bool invertRotationSnap, bool preserveAspectRatio){
699739 mouseRay = camera->screenToRay (x, y);
700740
701741 if (TerrainEditWindow* terrainEditWindow = Backend::getApp ().getTerrainEditWindow ()){
@@ -912,6 +952,14 @@ void editor::SceneRender::mouseDragEvent(float x, float y, float origX, float or
912952 newTileH = tileStartHeight + localSizeDelta.y ;
913953 }
914954
955+ if (preserveAspectRatio && isCorner2DGizmoSide (side)) {
956+ Vector2 lockedSize = lockObject2DAspectRatio (Vector2 (tileStartWidth, tileStartHeight), Vector2 (newTileW, newTileH));
957+ newTileW = lockedSize.x ;
958+ newTileH = lockedSize.y ;
959+ newTilePos.x = gizmo2DSideUsesNegativeX (side) ? (tileMaxX - newTileW) : tileStartPosition.x ;
960+ newTilePos.y = gizmo2DSideUsesNegativeY (side) ? (tileMaxY - newTileH) : tileStartPosition.y ;
961+ }
962+
915963 if (displaySettings.snapToGrid ) {
916964 float spacing = displaySettings.gridSpacing2D ;
917965 if (spacing > 0 .0f ) {
@@ -1005,12 +1053,61 @@ void editor::SceneRender::mouseDragEvent(float x, float y, float origX, float or
10051053 bool isLayout = scene->getComponentArray <UILayoutComponent>()->hasEntity (entity);
10061054 bool isText = scene->getComponentArray <TextComponent>()->hasEntity (entity);
10071055
1008- Vector3 newPos = gizmoRMatrix.inverse () * ((rretrun.point + cursorStartOffset) - gizmoStartPosition);
1056+ Gizmo2DSideSelected side = toolslayer.getGizmo2DSideSelected ();
1057+ Vector3 deltaPos = gizmoRMatrix.inverse () * ((rretrun.point + cursorStartOffset) - gizmoStartPosition);
1058+ Vector3 deltaSize = gizmoRMatrix.inverse () * -(gizmoStartPosition - rretrun.point - cursorStartOffset);
1059+
1060+ Vector3 oScale = getMatrixScale (transform->modelMatrix );
1061+ if (oScale.x == 0 .0f ) oScale.x = 1 .0f ;
1062+ if (oScale.y == 0 .0f ) oScale.y = 1 .0f ;
1063+ Vector3 posOffset = Vector3::ZERO;
1064+ Vector2 sizeDeltaLocal = Vector2::ZERO;
1065+
1066+ if (side == Gizmo2DSideSelected::CENTER){
1067+ posOffset = deltaPos;
1068+ }else if (side == Gizmo2DSideSelected::NX){
1069+ posOffset.x = deltaPos.x ;
1070+ sizeDeltaLocal.x = -deltaSize.x / oScale.x ;
1071+ }else if (side == Gizmo2DSideSelected::NY){
1072+ posOffset.y = deltaPos.y ;
1073+ sizeDeltaLocal.y = -deltaSize.y / oScale.y ;
1074+ }else if (side == Gizmo2DSideSelected::PX){
1075+ sizeDeltaLocal.x = deltaSize.x / oScale.x ;
1076+ }else if (side == Gizmo2DSideSelected::PY){
1077+ sizeDeltaLocal.y = deltaSize.y / oScale.y ;
1078+ }else if (side == Gizmo2DSideSelected::NX_NY){
1079+ posOffset.x = deltaPos.x ;
1080+ posOffset.y = deltaPos.y ;
1081+ sizeDeltaLocal.x = -deltaSize.x / oScale.x ;
1082+ sizeDeltaLocal.y = -deltaSize.y / oScale.y ;
1083+ }else if (side == Gizmo2DSideSelected::NX_PY){
1084+ posOffset.x = deltaPos.x ;
1085+ sizeDeltaLocal.x = -deltaSize.x / oScale.x ;
1086+ sizeDeltaLocal.y = deltaSize.y / oScale.y ;
1087+ }else if (side == Gizmo2DSideSelected::PX_NY){
1088+ posOffset.y = deltaPos.y ;
1089+ sizeDeltaLocal.x = deltaSize.x / oScale.x ;
1090+ sizeDeltaLocal.y = -deltaSize.y / oScale.y ;
1091+ }else if (side == Gizmo2DSideSelected::PX_PY){
1092+ sizeDeltaLocal.x = deltaSize.x / oScale.x ;
1093+ sizeDeltaLocal.y = deltaSize.y / oScale.y ;
1094+ }
1095+
1096+ if (preserveAspectRatio && isCorner2DGizmoSide (side)){
1097+ Vector2 freeformSizeDeltaLocal = sizeDeltaLocal;
1098+ Vector2 lockedSize = lockObject2DAspectRatio (objectSizeOffset[entity], objectSizeOffset[entity] + sizeDeltaLocal);
1099+ sizeDeltaLocal = lockedSize - objectSizeOffset[entity];
1100+ if (gizmo2DSideUsesNegativeX (side)){
1101+ posOffset.x = (freeformSizeDeltaLocal.x != 0 .0f ) ? (posOffset.x * (sizeDeltaLocal.x / freeformSizeDeltaLocal.x )) : 0 .0f ;
1102+ }
1103+ if (gizmo2DSideUsesNegativeY (side)){
1104+ posOffset.y = (freeformSizeDeltaLocal.y != 0 .0f ) ? (posOffset.y * (sizeDeltaLocal.y / freeformSizeDeltaLocal.y )) : 0 .0f ;
1105+ }
1106+ }
10091107
1010- Vector3 newSize = gizmoRMatrix. inverse () * -(gizmoStartPosition - rretrun. point - cursorStartOffset );
1108+ Vector3 newPos = gizmoStartPosition + (gizmoRMatrix * posOffset );
10111109
1012- if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::CENTER){
1013- newPos = gizmoStartPosition + (gizmoRMatrix * newPos);
1110+ if (side == Gizmo2DSideSelected::CENTER){
10141111 // Snap absolute world position to grid (must be done after newPos becomes world-space)
10151112 if (displaySettings.snapToGrid ) {
10161113 float spacing = displaySettings.gridSpacing2D ;
@@ -1019,31 +1116,6 @@ void editor::SceneRender::mouseDragEvent(float x, float y, float origX, float or
10191116 newPos.y = std::round (newPos.y / spacing) * spacing;
10201117 }
10211118 }
1022- newSize = Vector3 (0 , 0 , 0 );
1023- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::NX){
1024- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (newPos.x , 0 , 0 ));
1025- newSize = Vector3 (-newSize.x , 0 , 0 );
1026- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::NY){
1027- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (0 , newPos.y , 0 ));
1028- newSize = Vector3 (0 , -newSize.y , 0 );
1029- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::PX){
1030- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (0 , 0 , 0 ));
1031- newSize = Vector3 (newSize.x , 0 , 0 );
1032- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::PY){
1033- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (0 , 0 , 0 ));
1034- newSize = Vector3 (0 , newSize.y , 0 );
1035- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::NX_NY){
1036- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (newPos.x , newPos.y , 0 ));
1037- newSize = Vector3 (-newSize.x , -newSize.y , 0 );
1038- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::NX_PY){
1039- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (newPos.x , 0 , 0 ));
1040- newSize = Vector3 (-newSize.x , newSize.y , 0 );
1041- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::PX_NY){
1042- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (0 , newPos.y , 0 ));
1043- newSize = Vector3 (newSize.x , -newSize.y , 0 );
1044- }else if (toolslayer.getGizmo2DSideSelected () == Gizmo2DSideSelected::PX_PY){
1045- newPos = gizmoStartPosition + (gizmoRMatrix * Vector3 (0 , 0 , 0 ));
1046- newSize = Vector3 (newSize.x , newSize.y , 0 );
10471119 }
10481120
10491121 Matrix4 gizmoMatrix = Matrix4::translateMatrix (newPos) * gizmoRMatrix * Matrix4::scaleMatrix (Vector3 (1 ,1 ,1 ));
@@ -1053,12 +1125,7 @@ void editor::SceneRender::mouseDragEvent(float x, float y, float origX, float or
10531125 objMatrix = transformParent->modelMatrix .inverse () * objMatrix;
10541126 }
10551127
1056- Vector3 oScale = Vector3 (1 .0f , 1 .0f , 1 .0f );
1057- oScale.x = Vector3 (objMatrix[0 ][0 ], objMatrix[0 ][1 ], objMatrix[0 ][2 ]).length ();
1058- oScale.y = Vector3 (objMatrix[1 ][0 ], objMatrix[1 ][1 ], objMatrix[1 ][2 ]).length ();
1059- oScale.z = Vector3 (objMatrix[2 ][0 ], objMatrix[2 ][1 ], objMatrix[2 ][2 ]).length ();
1060-
1061- Vector2 size = objectSizeOffset[entity] + Vector2 (newSize.x / oScale.x , newSize.y / oScale.y );
1128+ Vector2 size = objectSizeOffset[entity] + sizeDeltaLocal;
10621129 Vector3 pos = Vector3 (objMatrix[3 ][0 ], objMatrix[3 ][1 ], objMatrix[3 ][2 ]);
10631130
10641131 if (size.x < 0 ) size.x = 0 ;
@@ -1077,13 +1144,12 @@ void editor::SceneRender::mouseDragEvent(float x, float y, float origX, float or
10771144 }
10781145 }
10791146
1080- if (toolslayer. getGizmo2DSideSelected () != Gizmo2DSideSelected::NONE){
1147+ if (side != Gizmo2DSideSelected::NONE){
10811148 MultiPropertyCmd* multiCmd = new MultiPropertyCmd ();
10821149 if (isLayout){
10831150 multiCmd->addPropertyCmd <unsigned int >(project, sceneProject->id , entity, ComponentType::UILayoutComponent, " width" , static_cast <unsigned int >(size.x ));
10841151 multiCmd->addPropertyCmd <unsigned int >(project, sceneProject->id , entity, ComponentType::UILayoutComponent, " height" , static_cast <unsigned int >(size.y ));
10851152 if (isText){
1086- Gizmo2DSideSelected side = toolslayer.getGizmo2DSideSelected ();
10871153 if (side == Gizmo2DSideSelected::NX || side == Gizmo2DSideSelected::PX ||
10881154 side == Gizmo2DSideSelected::NX_NY || side == Gizmo2DSideSelected::NX_PY ||
10891155 side == Gizmo2DSideSelected::PX_NY || side == Gizmo2DSideSelected::PX_PY) {
0 commit comments