/// <summary>The actual logic of the translation action.</summary> private void CalculatePosition() { #region #Color(darkcyan); Camera sceneCam = SceneView.lastActiveSceneView.camera; // Prevent a glitch that inverts movement in some cases. Vector3 camViewPlaneNormal = sceneCam.transform.forward; Vector3 Z_Difference = sceneCam.transform.position - OrigAvgPivot; float dot = Vector3.Dot(Z_Difference, camViewPlaneNormal); // Raw mouse coordinates have y flipped from what unity uses. Vector2 mousePos = BA.CurrentEvent.mousePosition; mousePos.y = sceneCam.pixelHeight - mousePos.y; if (BA.SlowDownTransformsThisFrame) { MouseOffset += (mousePos - LastMousePos) * 0.9f; } Vector2 toNewMouse = mousePos - OriginalMousePos - MouseOffset; if (dot > 0 && !sceneCam.orthographic) { toNewMouse *= -1; } LastMousePos = mousePos; Vector2 objInSP = sceneCam.WorldToScreenPoint(OrigAvgPivot); Vector2 newObjPosInSP = objInSP + toNewMouse; Vector3 moveTo = Vector3.zero; Plane movePlane = new Plane(); Ray rayToNewPos = sceneCam.ScreenPointToRay(newObjPosInSP); rayToNewPos.origin -= rayToNewPos.direction * 100; if (BA.TransformSpace == Space.World) { if (BA.TransformLock == Lock.None) { movePlane = new Plane(camViewPlaneNormal, OrigAvgPivot); moveTo = CastRayAndGetPosition(movePlane, rayToNewPos); } else if (BA.TransformLock == Lock.X_Axis || BA.TransformLock == Lock.Y_Axis || BA.TransformLock == Lock.Z_Axis) { Vector3 planeNormal = camViewPlaneNormal; moveTo = OrigAvgPivot; if (BA.TransformLock == Lock.X_Axis) { planeNormal.x = 0; } else if (BA.TransformLock == Lock.Y_Axis) { planeNormal.y = 0; } else { planeNormal.z = 0; } moveTo = GetGlobalProjectedAxisMotion(planeNormal.normalized, rayToNewPos, sceneCam); } else { if (BA.TransformLock == Lock.YZ_Plane) { movePlane = new Plane(Vector3.Cross(Vector3.up, Vector3.forward), OrigAvgPivot); } else if (BA.TransformLock == Lock.XZ_Plane) { movePlane = new Plane(Vector3.Cross(Vector3.right, Vector3.forward), OrigAvgPivot); } else { movePlane = new Plane(Vector3.Cross(Vector3.right, Vector3.up), OrigAvgPivot); } moveTo = CastRayAndGetPosition(movePlane, rayToNewPos); } UpdatePositions(moveTo); // Handle vertex snapping ONLY AFTER the original transformations. #colreg(red*0.3); if (!BA.NumericSnap && BA.VertexSnapON_ThisFrame) { BA.LastVertexSnapTime = EditorApplication.timeSinceStartup + BlenderActions.VertexSnapTimeInterval; BA.AntiHang = 0; moveTo = Vector3.zero; //#colreg(green); bool returnOnly1stVertex = false; Utils.VertexSnappingResult targetResult = Utils.VertexSnappingResult.BothVectorsFound; // If we are in collider editing mode - don't search for the closestSelectedVertexWorldSpace amongst models in scene. if (BA.ColliderBeingEdited != null) { returnOnly1stVertex = true; targetResult = Utils.VertexSnappingResult.FirstVectorFound; } //#endcolreg Vector2 correctedMousePos = BA.CurrentEvent.mousePosition; correctedMousePos.y = sceneCam.pixelHeight - correctedMousePos.y; Vector3 closestVertexWorldSpace = Vector3.zero; Vector3 closestSelectedVertexWorldSpace = Vector3.zero; Vector3 closestVertexLocalSpace = Vector3.zero; Vector3 closestSelectedVertexLocalSpace = Vector3.zero; GameObject closestGO = null; if (Utils.Find2VerticesForVertexSnapping(sceneCam, correctedMousePos, out closestVertexWorldSpace, out closestSelectedVertexWorldSpace, out closestGO, returnOnly1stVertex) == targetResult) { if (BA.Position3DCursorToLastSnapPoint) //#color(orange*3); { BA.The3DCursorPos = closestVertexWorldSpace; //#color(orange*3); } // If we are in collider editing mode - find closestSelectedVertexWorldSpace amongst the collider vertices. #colreg(green); if (BA.ColliderBeingEdited != null) { if (BA.EditedBoxCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestBoxColliderVertex(BA.EditedBoxCollider, sceneCam, correctedMousePos); } else if (BA.EditedSphereCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestSphereColliderVertex(BA.EditedSphereCollider, closestVertexWorldSpace); } else if (BA.EditedCapsuleCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestCapsuleColliderVertex(BA.EditedCapsuleCollider, closestVertexWorldSpace); } // Move to local space as the collider offset is applied in local space. closestVertexLocalSpace = BA.ColliderBeingEdited.transform.InverseTransformPoint(closestVertexWorldSpace); closestSelectedVertexLocalSpace = BA.ColliderBeingEdited.transform.InverseTransformPoint(closestSelectedVertexWorldSpace); moveTo = closestVertexLocalSpace - closestSelectedVertexLocalSpace; } //#endcolreg else { moveTo = closestVertexWorldSpace - closestSelectedVertexWorldSpace; } if (BA.TransformLock != Lock.None) { if (BA.TransformLock == Lock.X_Axis) { moveTo.y = 0; moveTo.z = 0; } else if (BA.TransformLock == Lock.Y_Axis) { moveTo.x = 0; moveTo.z = 0; } else if (BA.TransformLock == Lock.Z_Axis) { moveTo.y = 0; moveTo.x = 0; } else { if (BA.TransformLock == Lock.YZ_Plane) { moveTo.x = 0; } else if (BA.TransformLock == Lock.XZ_Plane) { moveTo.y = 0; } else { moveTo.z = 0; } } } if (BA.ColliderBeingEdited != null) //#colreg(green); { Utils.MoveEditableColliderCenterLocalSpace(moveTo, BA); //#endcolreg } else { for (int k = 0; k < SelectedTransforms.Length; k++) { SelectedTransforms[k].position += moveTo; } LastFrameAvgPivot += moveTo; } } } // #endcolreg } else { for (int i = 0; i < SelectedTransforms.Length; i++) { if (BA.TransformLock == Lock.X_Axis || BA.TransformLock == Lock.Y_Axis || BA.TransformLock == Lock.Z_Axis) { Vector3 vec1 = Vector3.zero; Vector3 vec2 = Vector3.zero; if (BA.TransformLock == Lock.X_Axis) { vec1 = SelectedTransforms[i].right; vec2 = SelectedTransforms[i].forward; } else if (BA.TransformLock == Lock.Y_Axis) { vec1 = SelectedTransforms[i].up; vec2 = SelectedTransforms[i].forward; } else { vec1 = SelectedTransforms[i].right; vec2 = SelectedTransforms[i].forward; } movePlane = new Plane(Vector3.Cross(vec1, vec2), OrigAvgPivot); moveTo = CastRayAndGetPositionLocal(movePlane, rayToNewPos, i) + OrigObjectsOffsets[i]; moveTo = SelectedTransforms[i].InverseTransformVector(moveTo); Vector3 localPos = SelectedTransforms[i].InverseTransformVector(SelectedTransforms[i].position); Vector3 difference = moveTo - localPos; if (BA.TransformLock == Lock.X_Axis) { difference.y = 0; difference.z = 0; } else if (BA.TransformLock == Lock.Y_Axis) { difference.x = 0; difference.z = 0; } else { difference.y = 0; difference.x = 0; } moveTo = localPos + difference; moveTo = SelectedTransforms[i].TransformVector(moveTo); } else { Vector3 vec1 = Vector3.zero; Vector3 vec2 = Vector3.zero; if (BA.TransformLock == Lock.YZ_Plane) { vec1 = SelectedTransforms[i].up; vec2 = SelectedTransforms[i].forward; } else if (BA.TransformLock == Lock.XZ_Plane) { vec1 = SelectedTransforms[i].right; vec2 = SelectedTransforms[i].forward; } else { vec1 = SelectedTransforms[i].right; vec2 = SelectedTransforms[i].up; } movePlane = new Plane(Vector3.Cross(vec1, vec2), SelectedTransforms[i].position); moveTo = CastRayAndGetPositionLocal(movePlane, rayToNewPos, i) + OrigObjectsOffsets[i]; } UpdateSinglePosition(moveTo, i); } // Handle vertex snapping ONLY AFTER the original transformations. #colreg(red*0.3); if (!BA.NumericSnap && BA.VertexSnapON_ThisFrame) { BA.LastVertexSnapTime = EditorApplication.timeSinceStartup + BlenderActions.VertexSnapTimeInterval; BA.AntiHang = 0; moveTo = Vector3.zero; //#colreg(green); bool returnOnly1stVertex = false; Utils.VertexSnappingResult targetResult = Utils.VertexSnappingResult.BothVectorsFound; // If we are in collider editing mode - don't search for the closestSelectedVertexWorldSpace amongst models in scene. if (BA.ColliderBeingEdited != null) { returnOnly1stVertex = true; targetResult = Utils.VertexSnappingResult.FirstVectorFound; } //#endcolreg Vector2 correctedMousePos = BA.CurrentEvent.mousePosition; correctedMousePos.y = sceneCam.pixelHeight - correctedMousePos.y; Vector3 closestVertexWorldSpace = Vector3.zero; Vector3 closestSelectedVertexWorldSpace = Vector3.zero; Vector3 closestVertexLocalSpace = Vector3.zero; Vector3 closestSelectedVertexLocalSpace = Vector3.zero; GameObject closestGO = null; if (Utils.Find2VerticesForVertexSnapping(sceneCam, correctedMousePos, out closestVertexWorldSpace, out closestSelectedVertexWorldSpace, out closestGO, returnOnly1stVertex) == targetResult) { if (BA.Position3DCursorToLastSnapPoint) { BA.The3DCursorPos = closestVertexWorldSpace; } // If we are in collider editing mode - find closestSelectedVertexWorldSpace amongst the collider vertices. #colreg(green); if (BA.ColliderBeingEdited != null) { if (BA.EditedBoxCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestBoxColliderVertex(BA.EditedBoxCollider, sceneCam, correctedMousePos); } else if (BA.EditedSphereCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestSphereColliderVertex(BA.EditedSphereCollider, closestVertexWorldSpace); } else if (BA.EditedCapsuleCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestCapsuleColliderVertex(BA.EditedCapsuleCollider, closestVertexWorldSpace); } // Move to local space as the collider offset is applied in local space. closestVertexLocalSpace = BA.ColliderBeingEdited.transform.InverseTransformPoint(closestVertexWorldSpace); closestSelectedVertexLocalSpace = BA.ColliderBeingEdited.transform.InverseTransformPoint(closestSelectedVertexWorldSpace); moveTo = closestVertexLocalSpace - closestSelectedVertexLocalSpace; } //#endcolreg else { closestVertexLocalSpace = closestGO.transform.InverseTransformDirection(closestVertexWorldSpace); closestSelectedVertexLocalSpace = closestGO.transform.InverseTransformDirection(closestSelectedVertexWorldSpace); moveTo = closestVertexLocalSpace - closestSelectedVertexLocalSpace; } if (BA.TransformLock == Lock.X_Axis || BA.TransformLock == Lock.Y_Axis || BA.TransformLock == Lock.Z_Axis) { if (BA.TransformLock == Lock.X_Axis) { moveTo.y = 0; moveTo.z = 0; } else if (BA.TransformLock == Lock.Y_Axis) { moveTo.x = 0; moveTo.z = 0; } else { moveTo.y = 0; moveTo.x = 0; } } else { if (BA.TransformLock == Lock.YZ_Plane) { moveTo.x = 0; } else if (BA.TransformLock == Lock.XZ_Plane) { moveTo.y = 0; } else { moveTo.z = 0; } } if (BA.ColliderBeingEdited != null) //#colreg(green); { Utils.MoveEditableColliderCenterLocalSpace(moveTo, BA); //#endcolreg } else { moveTo = closestGO.transform.TransformDirection(moveTo); for (int i = 0; i < SelectedTransforms.Length; i++) { SelectedTransforms[i].position += moveTo; LastFrameLocalPos[i] += moveTo; } } } } // #endcolreg; } #endregion }
/// <summary>The actual logic of the rotation action.</summary> private void CalculateRotation(Vector2 originalMouse, Vector2 newMouse) { //#colreg(darkcyan); Camera sceneCam = SceneView.lastActiveSceneView.camera; // Prevent a glitch that inverts movement in some cases. Vector3 camViewPlaneNormal = sceneCam.transform.forward; Vector3 Z_Difference = sceneCam.transform.position - OrigAvgPivot; Debug.Log(Vector3.Dot(Z_Difference, camViewPlaneNormal).ToString("0.#####")); float dot = Vector3.Dot(Z_Difference, camViewPlaneNormal); float angle = 0; Vector3 axis = Vector3.zero; Vector3 pivot = OrigAvgPivot; if (BA.Use3DCursor) //#color(orange*3); { pivot = BA.The3DCursorPos; //#color(orange*3); } Vector2 inSP = sceneCam.WorldToScreenPoint(pivot); Vector2 toNewPos = newMouse - originalMouse; // Implementing numeric input for rotations. if (NumericInput.EnteredNumber != 0) // #Color(lime*3); { angle = NumericInput.EnteredNumber; // #Color(lime*3); } else { inSP.y = sceneCam.pixelHeight - inSP.y; angle = Vector2.Angle(originalMouse - inSP, newMouse - inSP); if (dot > 0) { angle = 360 - angle; } if (Vector3.Cross(originalMouse - inSP, newMouse - inSP).z < 0) { angle = 360 - angle; } #region Shift slowdown float clearSign = Mathf.Sign(angle - OldAngle); float clearDelta = Mathf.Abs(angle - OldAngle) - 360; if (BA.SlowDownTransformsThisFrame) { float delta = (angle - OldAngleWithOffset - AngleOffset) * 0.9f; if (Mathf.Abs(delta) > 300) { float sign = Mathf.Sign(AngleOffset); AngleOffset = -1 * sign * (360 - Mathf.Abs(AngleOffset)) + clearDelta * clearSign; } else { AngleOffset += delta; } } OldAngle = angle; angle -= AngleOffset; if (angle > 360) { angle -= 360; } else if (angle < -360) { angle += 360; } OldAngleWithOffset = angle; #endregion } if (toNewPos.sqrMagnitude != 0 || NumericInput.EnteredNumber != 0) // #Color(lime*3); { if (BA.TransformSpace == Space.World) { if (BA.TransformLock == Lock.None) { axis = -sceneCam.ScreenPointToRay(inSP).direction; } else { Vector3 toCam = sceneCam.transform.position - pivot; if (BA.TransformLock == Lock.X_Axis || BA.TransformLock == Lock.YZ_Plane) { if (toCam.x >= 0) { axis = Vector3.right; } else { axis = Vector3.left; } } else if (BA.TransformLock == Lock.Y_Axis || BA.TransformLock == Lock.XZ_Plane) { if (toCam.y >= 0) { axis = Vector3.up; } else { axis = Vector3.down; } } else { if (toCam.z >= 0) { axis = Vector3.forward; } else { axis = Vector3.back; } } } UpdateRotations(axis, angle); } else { foreach (Transform t in SelectedTransforms) { Vector3 caminObjSP = t.transform.InverseTransformPoint(sceneCam.transform.position); if (BA.TransformLock == Lock.X_Axis || BA.TransformLock == Lock.YZ_Plane) { if (caminObjSP.x >= 0) { axis = t.transform.TransformDirection(Vector3.right); } else { axis = t.transform.TransformDirection(Vector3.left); } } else if (BA.TransformLock == Lock.Y_Axis || BA.TransformLock == Lock.XZ_Plane) { if (caminObjSP.y >= 0) { axis = t.transform.TransformDirection(Vector3.up); } else { axis = t.transform.TransformDirection(Vector3.down); } } else { if (caminObjSP.z >= 0) { axis = t.transform.TransformDirection(Vector3.forward); } else { axis = t.transform.TransformDirection(Vector3.back); } } Vector3 pointToRotateAround = t.position; if (BA.Use3DCursor) //#color(orange*3); { pointToRotateAround = BA.The3DCursorPos; //#color(orange*3); } t.RotateAround(pointToRotateAround, axis, angle); } } PerformNumericSnap(); // Handle vertex snapping ONLY AFTER the original transformations. #colreg(red*0.3); if (!BA.NumericSnap && BA.VertexSnapON_ThisFrame) { BA.LastVertexSnapTime = EditorApplication.timeSinceStartup + BlenderActions.VertexSnapTimeInterval; BA.AntiHang = 0; //#colreg(green); bool returnOnly1stVertex = false; Utils.VertexSnappingResult targetResult = Utils.VertexSnappingResult.BothVectorsFound; // If we are in collider editing mode - don't search for the closestSelectedVertexWorldSpace amongst models in scene. if (BA.ColliderBeingEdited != null) { returnOnly1stVertex = true; targetResult = Utils.VertexSnappingResult.FirstVectorFound; } //#endcolreg Vector2 correctedMousePos = BA.CurrentEvent.mousePosition; correctedMousePos.y = sceneCam.pixelHeight - correctedMousePos.y; Vector3 closestVertexWorldSpace = Vector3.zero; Vector3 closestSelectedVertexWorldSpace = Vector3.zero; GameObject closestGO = null; if (Utils.Find2VerticesForVertexSnapping(sceneCam, correctedMousePos, out closestVertexWorldSpace, out closestSelectedVertexWorldSpace, out closestGO, returnOnly1stVertex) == targetResult) { // If we are in collider editing mode - find closestSelectedVertexWorldSpace amongst the collider vertices. #colreg(green); if (BA.ColliderBeingEdited != null) { if (BA.EditedBoxCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestBoxColliderVertex(BA.EditedBoxCollider, sceneCam, correctedMousePos); } else if (BA.EditedSphereCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestSphereColliderVertex(BA.EditedSphereCollider, closestVertexWorldSpace); } else if (BA.EditedCapsuleCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestCapsuleColliderVertex(BA.EditedCapsuleCollider, closestVertexWorldSpace); } } //#endcolreg float vertexSnapFullAngle = 0; // Crazy math from here: // https://math.stackexchange.com/questions/2548811/find-an-angle-to-rotate-a-vector-around-a-ray-so-that-the-vector-gets-as-close-a/2549262#2549262 Vector3 deltaVertexWorldSpaceNormalized = (closestVertexWorldSpace - pivot).normalized; Vector3 deltaSelectedVertexWorldSpaceNormalized = (closestSelectedVertexWorldSpace - pivot).normalized; Vector3 axisNormalized = axis.normalized; Vector3 c = deltaSelectedVertexWorldSpaceNormalized - Vector3.Dot(deltaSelectedVertexWorldSpaceNormalized, axisNormalized) * axisNormalized; float temp = 1 / c.magnitude; if (!float.IsNaN(temp)) { Vector3 e = temp * c; Vector3 f = Vector3.Cross(axisNormalized, e); vertexSnapFullAngle = Mathf.Atan2(Vector3.Dot(deltaVertexWorldSpaceNormalized, f), Vector3.Dot(deltaVertexWorldSpaceNormalized, e)) * Mathf.Rad2Deg; if (!float.IsNaN(vertexSnapFullAngle)) { UpdateRotations(axis, vertexSnapFullAngle); } } } } //#endcolreg } } //#endcolreg
/// <summary>The actual logic of the scaling action.</summary> private void CalculateScale() { //#colreg(darkcyan); float scaleFactor = 1; Camera sceneCam = SceneView.lastActiveSceneView.camera; // Prevent a glitch that inverts movement in some cases. Vector3 camViewPlaneNormal = sceneCam.transform.forward; Vector3 Z_Difference = sceneCam.transform.position - OrigAvgPivot; float dot = Vector3.Dot(Z_Difference, camViewPlaneNormal); Vector2 upsideDownMousePos = BA.CurrentEvent.mousePosition; if (NumericInput.EnteredNumber != 0) // #Color(lime*3); { scaleFactor = NumericInput.EnteredNumber; // #Color(lime*3); } else { Vector3 pivot = OrigAvgPivot; if (BA.Use3DCursor) //#color(orange*3); { pivot = BA.The3DCursorPos; //#color(orange*3); } else if (BA.ColliderBeingEdited != null) //#colreg(green); { pivot = OriginalColliderCenterWorldSpace; //#endcolreg } Vector2 pivotPosScreenSpace = sceneCam.WorldToScreenPoint(pivot); pivotPosScreenSpace.y = sceneCam.pixelHeight - pivotPosScreenSpace.y; if (BA.SlowDownTransformsThisFrame) { MouseOffset += (upsideDownMousePos - LastMousePos) * 0.9f; } LastMousePos = upsideDownMousePos; upsideDownMousePos -= MouseOffset; if (dot > 0 && !sceneCam.orthographic) { upsideDownMousePos = OriginalMousePos * 2 - upsideDownMousePos; } float newDistance = Vector2.Distance(upsideDownMousePos, pivotPosScreenSpace); scaleFactor = newDistance / OriginalDistance; } Vector3 scaleBy = ApplyAxisLimtations(new Vector3(scaleFactor, scaleFactor, scaleFactor)); UpdateScale(scaleBy); PerformNumericSnap(); // Handle vertex snapping ONLY AFTER the original transformations. #colreg(red*0.3); if (!BA.NumericSnap && BA.VertexSnapON_ThisFrame) { BA.LastVertexSnapTime = EditorApplication.timeSinceStartup + BlenderActions.VertexSnapTimeInterval; BA.AntiHang = 0; //#colreg(green); bool returnOnly1stVertex = false; Utils.VertexSnappingResult targetResult = Utils.VertexSnappingResult.BothVectorsFound; // If we are in collider editing mode - don't search for the closestSelectedVertexWorldSpace amongst models in scene. if (BA.ColliderBeingEdited != null) { returnOnly1stVertex = true; targetResult = Utils.VertexSnappingResult.FirstVectorFound; } //#endcolreg Vector2 correctedMousePos = BA.CurrentEvent.mousePosition; correctedMousePos.y = sceneCam.pixelHeight - correctedMousePos.y; // If the user has set a transform lock, every time we evaluate a vertex // we would gauge whether it would produce zero in one of it's variables in // local space if the local space pivot point is subtracted from it. // If it does - we drop the vertex bool ignoreZeroesOnX = false; bool ignoreZeroesOnY = false; bool ignoreZeroesOnZ = false; if (BA.TransformLock == Lock.XY_Plane || BA.TransformLock == Lock.XZ_Plane || BA.TransformLock == Lock.X_Axis) { ignoreZeroesOnX = true; } if (BA.TransformLock == Lock.YZ_Plane || BA.TransformLock == Lock.XY_Plane || BA.TransformLock == Lock.Y_Axis) { ignoreZeroesOnY = true; } if (BA.TransformLock == Lock.YZ_Plane || BA.TransformLock == Lock.XZ_Plane || BA.TransformLock == Lock.Z_Axis) { ignoreZeroesOnZ = true; } Vector3 customPivotLocalSpace = OrigAvgPivot; if (BA.Use3DCursor) //#color(orange*3); { customPivotLocalSpace = BA.The3DCursorPos; //#color(orange*3); } else if (BA.ColliderBeingEdited != null) //#colreg(green); { customPivotLocalSpace = OriginalColliderCenterWorldSpace; //#endcolreg } if (BA.ColliderBeingEdited != null) //#colreg(green); { customPivotLocalSpace = BA.ColliderBeingEdited.transform.InverseTransformPoint(customPivotLocalSpace); //#endcolreg } else { customPivotLocalSpace = SelectedTransforms[0].transform.InverseTransformPoint(customPivotLocalSpace); } Vector3 closestVertexWorldSpace = Vector3.zero; Vector3 closestSelectedVertexWorldSpace = Vector3.zero; GameObject closestGO = null; if (Utils.Find2VerticesForVertexSnapping(sceneCam, correctedMousePos, out closestVertexWorldSpace, out closestSelectedVertexWorldSpace, out closestGO, returnOnly1stVertex, ignoreZeroesOnX, ignoreZeroesOnY, ignoreZeroesOnZ, customPivotLocalSpace) == targetResult) { Transform toLocalSpace = null; // we will use this to later move to the local space // If we are in collider editing mode - find closestSelectedVertexWorldSpace #colreg(green); // amongst the collider "vertices". if (BA.ColliderBeingEdited != null) { toLocalSpace = BA.ColliderBeingEdited.transform; if (BA.EditedBoxCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestBoxColliderVertex(BA.EditedBoxCollider, sceneCam, correctedMousePos); } else if (BA.EditedSphereCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestSphereColliderVertex(BA.EditedSphereCollider, closestVertexWorldSpace); } else if (BA.EditedCapsuleCollider != null) { closestSelectedVertexWorldSpace = Utils.FindClosestCapsuleColliderVertex(BA.EditedCapsuleCollider, closestVertexWorldSpace); } } //#endcolreg else if (SelectedTransforms.Length > 0 && SelectedTransforms[0] != null) { toLocalSpace = SelectedTransforms[0]; } // Move all the vertices into the local space because the scaling operation can only happen in local space. // The first model's space is used as the only space for all the rest of the models. if (toLocalSpace != null) { Vector3 closestVertexLocalSpace = toLocalSpace.transform.InverseTransformPoint(closestVertexWorldSpace); Vector3 closestSelectedVertexLocalSpace = toLocalSpace.transform.InverseTransformPoint(closestSelectedVertexWorldSpace); // Subtract the pivot from each of the vertices to find the relative difference vector closestVertexLocalSpace -= customPivotLocalSpace; closestSelectedVertexLocalSpace -= customPivotLocalSpace; Vector3 vertexSnapScale = Vector3.one; if (BA.TransformLock == Lock.None) { // If no axis lock - compute magnitudes of both vectors and find their ratio float ratio = closestVertexLocalSpace.magnitude / closestSelectedVertexLocalSpace.magnitude; vertexSnapScale = new Vector3(ratio, ratio, ratio); if (float.IsNaN(ratio)) { vertexSnapScale = Vector3.one; } } else { // If there is an axis lock, find the ratios in each of the three variables vertexSnapScale.x = closestVertexLocalSpace.x / closestSelectedVertexLocalSpace.x; if (float.IsNaN(vertexSnapScale.x) || float.IsInfinity(vertexSnapScale.x)) { vertexSnapScale.x = 1; } vertexSnapScale.y = closestVertexLocalSpace.y / closestSelectedVertexLocalSpace.y; if (float.IsNaN(vertexSnapScale.y) || float.IsInfinity(vertexSnapScale.y)) { vertexSnapScale.y = 1; } vertexSnapScale.z = closestVertexLocalSpace.z / closestSelectedVertexLocalSpace.z; if (float.IsNaN(vertexSnapScale.z) || float.IsInfinity(vertexSnapScale.z)) { vertexSnapScale.z = 1; } vertexSnapScale = ApplyAxisLimtations(vertexSnapScale); } UpdateScale(new Vector3(scaleBy.x * vertexSnapScale.x, scaleBy.y * vertexSnapScale.y, scaleBy.z * vertexSnapScale.z)); } } } //#endcolreg //#endcolreg }