void SetupInputPlane(Vector2 mousePosition) { plane = EditorHandleUtility.FindBestPlane(mousePosition); var planeNormal = plane.normal; var planeCenter = plane.normal * -plane.distance; // if hit point on plane is cardinal axis and on grid, snap to grid. if (Math.IsCardinalAxis(planeNormal)) { const float epsilon = .00001f; bool offGrid = false; Vector3 snapVal = EditorSnapping.activeMoveSnapValue; Vector3 center = Vector3.Scale(ProBuilderSnapping.GetSnappingMaskBasedOnNormalVector(planeNormal), planeCenter); for (int i = 0; i < 3; i++) { offGrid |= Mathf.Abs(snapVal[i] % center[i]) > epsilon; } polygon.isOnGrid = !offGrid; } else { polygon.isOnGrid = false; } }
/// <summary> /// Called from ProGrids. /// </summary> /// <param name="snapVal"></param> void PushToGrid(float snapVal) { UndoUtility.RecordSelection(selection.ToArray(), "Push elements to Grid"); if (selectMode == SelectMode.Object || selectMode == SelectMode.None) { return; } for (int i = 0, c = MeshSelection.selectedObjectCount; i < c; i++) { ProBuilderMesh mesh = selection[i]; if (mesh.selectedVertexCount < 1) { continue; } var indexes = mesh.GetCoincidentVertices(mesh.selectedIndexesInternal); ProBuilderSnapping.SnapVertices(mesh, indexes, Vector3.one * snapVal); mesh.ToMesh(); mesh.Refresh(); mesh.Optimize(); } UpdateSelection(); }
// If s_SnapNewShapesToGrid is enabled, always snap to the grid size. If it is not, use the active snap settings internal static void SnapInstantiatedObject(ProBuilderMesh mesh) { mesh.transform.position = ProBuilderSnapping.Snap( mesh.transform.position, s_SnapNewShapesToGrid ? EditorSnapping.worldSnapMoveValue : EditorSnapping.activeMoveSnapValue); }
// Returns a local space point, Vector3 GetPointInLocalSpace(Vector3 point) { var trs = polygon.transform; if (polygon.isOnGrid) { Vector3 snapMask = ProBuilderSnapping.GetSnappingMaskBasedOnNormalVector(m_Plane.normal); return(trs.InverseTransformPoint(ProGridsInterface.ProGridsSnap(point, snapMask))); } return(trs.InverseTransformPoint(point)); }
// Returns a local space point, Vector3 GetPointInLocalSpace(Vector3 point) { var trs = polygon.transform; if (polygon.isOnGrid) { Vector3 snapMask = ProBuilderSnapping.GetSnappingMaskBasedOnNormalVector(plane.normal); return(trs.InverseTransformPoint(ProBuilderSnapping.Snap(point, Vector3.Scale(EditorSnapping.activeMoveSnapValue, snapMask)))); } return(trs.InverseTransformPoint(point)); }
// Transform the point according to the snapping settings public Vector3 GetPoint(Vector3 point, bool useIncrementSnap = false) { if (useIncrementSnap) { return(ProBuilderSnapping.Snap(point, EditorSnapping.incrementalSnapMoveValue)); } if (m_IsOnGrid) { return(ProBuilderSnapping.Snap(point, EditorSnapping.activeMoveSnapValue)); } return(point); }
public static float ProGridsSnap(float point) { if (GetProGridsType() == null) { return(point); } if (SnapEnabled()) { return(ProBuilderSnapping.Snap(point, SnapValue())); } return(point); }
public static Vector3 ProGridsSnap(Vector3 point, Vector3 mask) { if (GetProGridsType() == null) { return(point); } if (ProGridsInterface.SnapEnabled()) { float snap = ProGridsInterface.SnapValue(); return(ProBuilderSnapping.Snap(point, mask * snap)); } return(point); }
internal static void SetPivotLocationAndSnap(ProBuilderMesh mesh) { if (ProGridsInterface.SnapEnabled()) { mesh.transform.position = ProBuilderSnapping.SnapValue(mesh.transform.position, ProGridsInterface.SnapValue()); } else if (s_SnapNewShapesToGrid) { mesh.transform.position = ProBuilderSnapping.SnapValue(mesh.transform.position, new Vector3( EditorPrefs.GetFloat("MoveSnapX"), EditorPrefs.GetFloat("MoveSnapY"), EditorPrefs.GetFloat("MoveSnapZ"))); } mesh.Optimize(); }
/// <summary> /// Return the last known grid pivot point. /// </summary> /// <param name="pivot"></param> /// <returns></returns> public static bool GetPivot(out Vector3 pivot) { pivot = Vector3.zero; if (s_GetPivotDelegate == null) { s_GetPivotDelegate = (Func <Vector3>)ReflectionUtility.GetOpenDelegate <Func <Vector3> >(GetProGridsType(), "GetPivot"); } if (s_GetPivotDelegate != null) { pivot = s_GetPivotDelegate(); // earlier version of progrids return a non-snapped pivot point pivot = ProBuilderSnapping.Snap(pivot, Vector3.one * SnapValue()); return(true); } return(false); }
void DoExistingPointsGUI() { Transform trs = polygon.transform; int len = polygon.m_Points.Count; Vector3 up = polygon.transform.up; Vector3 right = polygon.transform.right; Vector3 forward = polygon.transform.forward; Vector3 center = Vector3.zero; Event evt = Event.current; bool used = evt.type == EventType.Used; if (!used && (evt.type == EventType.MouseDown && evt.button == 0 && !EditorHandleUtility.IsAppendModifier(evt.modifiers))) { m_SelectedIndex = -1; Repaint(); } if (polygon.polyEditMode == PolyShape.PolyEditMode.Height) { if (!used && evt.type == EventType.MouseUp && evt.button == 0 && !EditorHandleUtility.IsAppendModifier(evt.modifiers)) { evt.Use(); SetPolyEditMode(PolyShape.PolyEditMode.Edit); } bool sceneInUse = EditorHandleUtility.SceneViewInUse(evt); Ray r = HandleUtility.GUIPointToWorldRay(evt.mousePosition); Vector3 origin = polygon.transform.TransformPoint(Math.Average(polygon.m_Points)); float extrude = polygon.extrude; if (evt.type == EventType.MouseMove && !sceneInUse) { Vector3 p = Math.GetNearestPointRayRay(origin, up, r.origin, r.direction); extrude = ProGridsInterface.ProGridsSnap(s_HeightMouseOffset + Vector3.Distance(origin, p) * Mathf.Sign(Vector3.Dot(p - origin, up))); } Vector3 extrudePoint = origin + (extrude * up); if (m_DrawHeightHandles) { Handles.color = k_HandleColor; Handles.DotHandleCap(-1, origin, Quaternion.identity, HandleUtility.GetHandleSize(origin) * k_HandleSize, evt.type); Handles.color = k_HandleColorGreen; Handles.DrawLine(origin, extrudePoint); Handles.DotHandleCap(-1, extrudePoint, Quaternion.identity, HandleUtility.GetHandleSize(extrudePoint) * k_HandleSize, evt.type); Handles.color = Color.white; } if (!sceneInUse && polygon.extrude != extrude) { OnBeginVertexMovement(); polygon.extrude = extrude; RebuildPolyShapeMesh(false); } } else { // vertex dots for (int ii = 0; ii < len; ii++) { Vector3 point = trs.TransformPoint(polygon.m_Points[ii]); center.x += point.x; center.y += point.y; center.z += point.z; float size = HandleUtility.GetHandleSize(point) * k_HandleSize; Handles.color = ii == m_SelectedIndex ? k_HandleSelectedColor : k_HandleColor; EditorGUI.BeginChangeCheck(); point = Handles.Slider2D(point, up, right, forward, size, Handles.DotHandleCap, Vector2.zero, true); if (EditorGUI.EndChangeCheck()) { UndoUtility.RecordObject(polygon, "Move Polygon Shape Point"); Vector3 snapMask = ProBuilderSnapping.GetSnappingMaskBasedOnNormalVector(m_Plane.normal); polygon.m_Points[ii] = ProGridsInterface.ProGridsSnap(trs.InverseTransformPoint(point), snapMask); OnBeginVertexMovement(); RebuildPolyShapeMesh(false); } // "clicked" a button if (!used && evt.type == EventType.Used) { if (ii == 0 && polygon.m_Points.Count > 2 && polygon.polyEditMode == PolyShape.PolyEditMode.Path) { m_NextMouseUpAdvancesMode = true; return; } else { used = true; m_SelectedIndex = ii; } } } Handles.color = Color.white; // height setting if (polygon.polyEditMode != PolyShape.PolyEditMode.Path && polygon.m_Points.Count > 2) { center.x /= (float)len; center.y /= (float)len; center.z /= (float)len; Vector3 extrude = center + (up * polygon.extrude); m_DistanceFromHeightHandle = Vector2.Distance(HandleUtility.WorldToGUIPoint(extrude), evt.mousePosition); EditorGUI.BeginChangeCheck(); if (m_DrawHeightHandles) { Handles.color = k_HandleColor; Handles.DotHandleCap(-1, center, Quaternion.identity, HandleUtility.GetHandleSize(center) * k_HandleSize, evt.type); Handles.DrawLine(center, extrude); Handles.color = k_HandleColorGreen; extrude = Handles.Slider(extrude, up, HandleUtility.GetHandleSize(extrude) * k_HandleSize, Handles.DotHandleCap, 0f); Handles.color = Color.white; } if (EditorGUI.EndChangeCheck()) { UndoUtility.RecordObject(polygon, "Set Polygon Shape Height"); polygon.extrude = ProGridsInterface.ProGridsSnap(Vector3.Distance(extrude, center) * Mathf.Sign(Vector3.Dot(up, extrude - center))); OnBeginVertexMovement(); RebuildPolyShapeMesh(false); } } } }
public override ShapeState DoState(Event evt) { if (evt.type == EventType.KeyDown) { switch (evt.keyCode) { case KeyCode.Escape: ToolManager.RestorePreviousTool(); break; } } if (tool.m_LastShapeCreated != null) { EditShapeTool.DoEditingHandles(tool.m_LastShapeCreated, true); } if (evt.isMouse && HandleUtility.nearestControl == tool.controlID) { var res = EditorHandleUtility.FindBestPlaneAndBitangent(evt.mousePosition); Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); float hit; if (res.item1.Raycast(ray, out hit)) { //Plane init tool.m_Plane = res.item1; tool.m_PlaneForward = res.item2; tool.m_PlaneRight = Vector3.Cross(tool.m_Plane.normal, tool.m_PlaneForward); var planeNormal = tool.m_Plane.normal; var planeCenter = tool.m_Plane.normal * -tool.m_Plane.distance; // if hit point on plane is cardinal axis and on grid, snap to grid. if (Math.IsCardinalAxis(planeNormal)) { const float epsilon = .00001f; bool offGrid = false; Vector3 snapVal = EditorSnapping.activeMoveSnapValue; Vector3 center = Vector3.Scale(ProBuilderSnapping.GetSnappingMaskBasedOnNormalVector(planeNormal), planeCenter); for (int i = 0; i < 3; i++) { offGrid |= Mathf.Abs(snapVal[i] % center[i]) > epsilon; } tool.m_IsOnGrid = !offGrid; } else { tool.m_IsOnGrid = false; } m_HitPosition = tool.GetPoint(ray.GetPoint(hit)); //Click has been done => Define a plane for the tool if (evt.type == EventType.MouseDown) { //BB init tool.m_BB_Origin = m_HitPosition; tool.m_BB_HeightCorner = tool.m_BB_Origin; tool.m_BB_OppositeCorner = tool.m_BB_Origin; return(NextState()); } } else { m_HitPosition = Vector3.negativeInfinity; } } if (GUIUtility.hotControl == 0 && evt.shift && !(evt.control || evt.command)) { tool.DuplicatePreview(m_HitPosition); } else if (tool.m_DuplicateGO != null) { Object.DestroyImmediate(tool.m_DuplicateGO); } // Repaint to visualize the placement preview dot if (evt.type == EventType.MouseMove && HandleUtility.nearestControl == tool.controlID) { HandleUtility.Repaint(); } if (evt.type == EventType.Repaint) { if (GUIUtility.hotControl == 0 && HandleUtility.nearestControl == tool.controlID) { using (new Handles.DrawingScope(EditorHandleDrawing.vertexSelectedColor)) { Handles.DotHandleCap(-1, m_HitPosition, Quaternion.identity, HandleUtility.GetHandleSize(m_HitPosition) * 0.05f, EventType.Repaint); } } if (GUIUtility.hotControl == 0 && evt.shift && !(evt.control || evt.command)) { tool.DrawBoundingBox(false); } } return(this); }
public static Vector3 MoveSnap(Vector3 value) { return(ProBuilderSnapping.Snap(value, activeMoveSnapValue)); }
public static float RotateSnap(float value) { return(ProBuilderSnapping.Snap(value, activeRotateSnapValue)); }
void ApplyTranslation(Vector3 translation) { var translationMagnitude = translation.magnitude; foreach (var key in elementSelection) { if (!(key is MeshAndPositions)) { continue; } var kvp = (MeshAndPositions)key; var mesh = kvp.mesh; var worldToLocal = mesh.transform.worldToLocalMatrix; var origins = kvp.positions; var positions = mesh.positionsInternal; foreach (var group in kvp.elementGroups) { var postApplyMatrix = GetPostApplyMatrix(group); var preApplyMatrix = postApplyMatrix.inverse; foreach (var index in group.indices) { // res = Group pre-apply matrix * world vertex position // res += translation // res = Group post-apply matrix * res // positions[i] = mesh.worldToLocal * res if (EditorSnapping.snapMode == SnapMode.World && !m_SnapAsGroup) { if (snapAxisConstraint && m_ActiveAxesWorld.active == 1) { var wp = postApplyMatrix.MultiplyPoint3x4(preApplyMatrix.MultiplyPoint3x4(origins[index])); var snap = ProBuilderSnapping.SnapValueOnRay( new Ray(wp, m_RawHandleDelta), translationMagnitude, GetSnapValueForAxis(m_ActiveAxesWorld), m_ActiveAxesWorld); positions[index] = worldToLocal.MultiplyPoint3x4(snap); } else { var wp = postApplyMatrix.MultiplyPoint3x4(translation + preApplyMatrix.MultiplyPoint3x4(origins[index])); var snap = ProBuilderSnapping.Snap(wp, snapValue); positions[index] = worldToLocal.MultiplyPoint3x4(snap); } } else { positions[index] = worldToLocal.MultiplyPoint3x4( postApplyMatrix.MultiplyPoint3x4( translation + preApplyMatrix.MultiplyPoint3x4(origins[index]))); } } } mesh.mesh.vertices = positions; mesh.RefreshUV(MeshSelection.selectedFacesInEditZone[mesh]); mesh.Refresh(RefreshMask.Normals); } ProBuilderEditor.Refresh(false); }
protected override void DoTool(Vector3 handlePosition, Quaternion handleRotation) { if (!isEditing) { m_Rotation = 0f; } EditorGUI.BeginChangeCheck(); var size = HandleUtility.GetHandleSize(handlePosition); EditorHandleUtility.PushMatrix(); Handles.matrix = Matrix4x4.TRS(handlePosition, handleRotation, Vector3.one); Handles.color = Color.blue; m_Euler.z = m_Rotation; m_Quaternion = Quaternion.Euler(m_Euler); m_Quaternion = Handles.Disc(m_Quaternion, Vector3.zero, Vector3.forward, size, relativeSnapEnabled, ProBuilderSnapSettings.incrementalSnapRotateValue); m_Euler = m_Quaternion.eulerAngles; m_Rotation = m_Euler.z; EditorHandleUtility.PopMatrix(); if (EditorGUI.EndChangeCheck()) { if (!isEditing) { BeginEdit("Rotate Textures"); } if (relativeSnapEnabled) { m_Rotation = ProBuilderSnapping.SnapValue(m_Rotation, ProBuilderSnapSettings.incrementalSnapRotateValue); } foreach (var mesh in elementSelection) { if (!(mesh is MeshAndTextures)) { continue; } var mat = (MeshAndTextures)mesh; var origins = mat.origins; var positions = mat.textures; foreach (var group in mat.elementGroups) { foreach (var index in group.indices) { positions[index] = mat.postApplyMatrix.MultiplyPoint( Math.RotateAroundPoint( mat.preApplyMatrix.MultiplyPoint3x4(origins[index]), Vector2.zero, -m_Rotation)); } } mesh.mesh.mesh.SetUVs(k_TextureChannel, positions); } } }
public static Vector3 ScaleSnap(Vector3 value) { return(ProBuilderSnapping.Snap(value, Vector3.one * activeRotateSnapValue)); }
protected override void DoToolGUI() { if (!isEditing) { m_Position = m_HandlePosition; } #if PROBUILDER_ENABLE_TRANSFORM_ORIGIN_GIZMO if (isEditing) { DrawSelectionOriginGizmos(); } #endif EditorGUI.BeginChangeCheck(); m_Position = Handles.PositionHandle(m_Position, m_HandleRotation); m_RawHandleDelta = m_Position - handlePositionOrigin; var delta = m_RawHandleDelta; if (EditorGUI.EndChangeCheck() && delta.sqrMagnitude > k_MinTranslateDeltaSqrMagnitude) { if (!isEditing) { BeginEdit("Translate Selection"); } if (Tools.vertexDragging) { Vector3 nearest; if (FindNearestVertex(currentEvent.mousePosition, out nearest)) { var unrotated = handleRotationOriginInverse * delta; var dir = new Vector3Mask(unrotated, k_CardinalAxisError); if (dir.active == 1) { var rotationDirection = handleRotationOrigin * dir * 10000f; m_Position = HandleUtility.ProjectPointLine(nearest, handlePositionOrigin + rotationDirection, handlePositionOrigin - rotationDirection); delta = m_Position - handlePositionOrigin; } } } else if (EditorSnapping.snapMode == SnapMode.World) { if (snapAxisConstraint) { m_ActiveAxesModel |= new Vector3Mask(handleRotationOriginInverse * delta, k_CardinalAxisError); m_ActiveAxesWorld = new Vector3Mask(m_HandleRotation * m_ActiveAxesModel); if (m_ActiveAxesWorld.active == 1) { m_Position = ProBuilderSnapping.SnapValueOnRay( new Ray(handlePositionOrigin, delta), delta.magnitude, GetSnapValueForAxis(m_ActiveAxesModel), m_ActiveAxesWorld); } else { m_Position = ProBuilderSnapping.Snap(m_Position, snapValue); } } else { m_Position = ProBuilderSnapping.Snap(m_Position, snapValue); } delta = m_Position - handlePositionOrigin; } #if PROBUILDER_ENABLE_TRANSFORM_ORIGIN_GIZMO if (pivotPoint == PivotPoint.IndividualOrigins && !m_DirectionOriginInitialized) { var mask = new Vector3Mask(handleRotationOriginInverse * delta, k_CardinalAxisError); if (mask.active > 0) { m_IndividualOriginDirection = mask; m_DirectionOriginInitialized = true; } } #endif ApplyTranslation(handleRotationOriginInverse * delta); } // Draw at the end so we get the snapped value if (showHandleInfo && isEditing) { DrawDeltaInfo(string.Format("Translate: <b>{0:F2}</b> {1}", delta.magnitude, (handleRotationOriginInverse * delta).ToString("0.00"))); } }
protected override void DoTool(Vector3 handlePosition, Quaternion handleRotation) { if (!isEditing) { m_Position = Vector3.zero; } EditorHandleUtility.PushMatrix(); Handles.matrix = Matrix4x4.TRS(handlePosition, handleRotation, Vector3.one); EditorGUI.BeginChangeCheck(); Handles.color = Color.blue; m_Position = Handles.Slider2D(m_Position, Vector3.forward, Vector3.right, Vector3.up, HandleUtility.GetHandleSize(m_Position) * .2f, Handles.RectangleHandleCap, 0f, false); Handles.color = Color.green; m_Position = Handles.Slider(m_Position, Vector3.up); Handles.color = Color.red; m_Position = Handles.Slider(m_Position, Vector3.right); Handles.color = Color.white; if (EditorGUI.EndChangeCheck()) { if (!isEditing) { BeginEdit("Translate Textures"); } if (relativeSnapEnabled) { m_Position.x = ProBuilderSnapping.SnapValue(m_Position.x, ProBuilderSnapSettings.incrementalSnapMoveValue.x); m_Position.y = ProBuilderSnapping.SnapValue(m_Position.y, ProBuilderSnapSettings.incrementalSnapMoveValue.y); } else if (worldSnapEnabled) { m_Position.x = ProBuilderSnapping.SnapValue(m_Position.x, snapValue.x); m_Position.y = ProBuilderSnapping.SnapValue(m_Position.y, snapValue.y); } // invert `y` because to users it's confusing that "up" in UV space visually moves the texture down var delta = new Vector4(m_Position.x, -m_Position.y, 0f, 0f); foreach (var value in elementSelection) { var selection = value as TranslateTextureSelection; if (selection == null) { continue; } // Account for object scale delta *= k_Vector3Magnitude / selection.mesh.transform.lossyScale.magnitude; var origins = selection.origins; var positions = selection.textures; // Translating faces is treated as a special case because we want the textures in scene to visually // match the movement of the translation handle. When UVs are scaled, they have the appearance of // moving faster or slower (even though they are translating the correct distances). To avoid this, // we cache the UV scale of each face and modify the translation delta accordingly. This isn't perfect, // as it will not be able to find the scale for sheared or otherwise distorted face UVs. However, for // most cases it maps quite well. if (ProBuilderEditor.selectMode == SelectMode.TextureFace) { foreach (var face in selection.faceAndScale) { var faceDelta = new Vector4(delta.x / face.item2.x, delta.y / face.item2.y, 0f, 0f); foreach (var index in face.item1.distinctIndexes) { positions[index] = origins[index] + faceDelta; } } } else { foreach (var group in value.elementGroups) { foreach (var index in group.indices) { positions[index] = origins[index] + delta; } } } selection.mesh.mesh.SetUVs(k_TextureChannel, positions); } } EditorHandleUtility.PopMatrix(); }
void DoPointPlacement() { Event evt = Event.current; EventType eventType = evt.type; if (m_PlacingPoint) { Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (eventType == EventType.MouseDrag) { float hitDistance = Mathf.Infinity; if (plane.Raycast(ray, out hitDistance)) { evt.Use(); polygon.m_Points[m_SelectedIndex] = GetPointInLocalSpace(ray.GetPoint(hitDistance)); RebuildPolyShapeMesh(false); SceneView.RepaintAll(); } } if (eventType == EventType.MouseUp || eventType == EventType.Ignore || eventType == EventType.KeyDown || eventType == EventType.KeyUp) { evt.Use(); m_PlacingPoint = false; m_SelectedIndex = -1; SceneView.RepaintAll(); } } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Path) { if (eventType == EventType.MouseDown && HandleUtility.nearestControl == m_ControlId) { if (polygon.m_Points.Count < 1) { SetupInputPlane(evt.mousePosition); } float hitDistance = Mathf.Infinity; Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (plane.Raycast(ray, out hitDistance)) { UndoUtility.RecordObject(polygon, "Add Polygon Shape Point"); Vector3 hit = ray.GetPoint(hitDistance); if (polygon.m_Points.Count < 1) { // this monstrosity exists so that grid and incremental snap work when possible, and // incremental is enabled when grid is not available. polygon.transform.position = m_Polygon.isOnGrid ? EditorSnapping.MoveSnap(hit) : EditorSnapping.snapMode == SnapMode.Relative ? ProBuilderSnapping.Snap(hit, EditorSnapping.incrementalSnapMoveValue) : hit; Vector3 cameraFacingPlaneNormal = plane.normal; if (Vector3.Dot(cameraFacingPlaneNormal, SceneView.lastActiveSceneView.camera.transform.forward) > 0f) { cameraFacingPlaneNormal *= -1; } polygon.transform.rotation = Quaternion.LookRotation(cameraFacingPlaneNormal) * Quaternion.Euler(new Vector3(90f, 0f, 0f)); } Vector3 point = GetPointInLocalSpace(hit); if (polygon.m_Points.Count > 2 && Math.Approx3(polygon.m_Points[0], point)) { m_NextMouseUpAdvancesMode = true; return; } polygon.m_Points.Add(point); m_PlacingPoint = true; m_SelectedIndex = polygon.m_Points.Count - 1; RebuildPolyShapeMesh(polygon); evt.Use(); } } else { float hitDistance = Mathf.Infinity; Ray ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition); if (plane.Raycast(ray, out hitDistance)) { Vector3 hit = ray.GetPoint(hitDistance); m_CurrentPosition = GetPointInLocalSpace(hit); } } } else if (polygon.polyEditMode == PolyShape.PolyEditMode.Edit) { if (polygon.m_Points.Count < 3) { SetPolyEditMode(PolyShape.PolyEditMode.Path); return; } if (m_DistanceFromHeightHandle > PreferenceKeys.k_MaxPointDistanceFromControl) { // point insertion Vector2 mouse = evt.mousePosition; Ray ray = HandleUtility.GUIPointToWorldRay(mouse); float hitDistance = Mathf.Infinity; if (plane.Raycast(ray, out hitDistance)) { Vector3 hit = ray.GetPoint(hitDistance); Vector3 point = GetPointInLocalSpace(hit); int polyCount = polygon.m_Points.Count; float distToLineInGUI; int index; Vector3 pInGUI = EditorHandleUtility.ClosestPointToPolyLine(polygon.m_Points, out index, out distToLineInGUI, true, polygon.transform); Vector3 aToPoint = point - polygon.m_Points[index - 1]; Vector3 aToB = polygon.m_Points[index % polyCount] - polygon.m_Points[index - 1]; float ratio = Vector3.Dot(aToPoint, aToB.normalized) / aToB.magnitude; Vector3 wp = Vector3.Lerp(polygon.m_Points[index - 1], polygon.m_Points[index % polyCount], ratio); wp = polygon.transform.TransformPoint(wp); Vector2 aInGUI = HandleUtility.WorldToGUIPoint(polygon.transform.TransformPoint(polygon.m_Points[index - 1])); Vector2 bInGUI = HandleUtility.WorldToGUIPoint(polygon.transform.TransformPoint(polygon.m_Points[index % polyCount])); float distanceToVertex = Mathf.Min(Vector2.Distance(mouse, aInGUI), Vector2.Distance(mouse, bInGUI)); if (distanceToVertex > PreferenceKeys.k_MaxPointDistanceFromControl && distToLineInGUI < PreferenceKeys.k_MaxPointDistanceFromControl) { m_MouseCursor = MouseCursor.ArrowPlus; if (evt.type == EventType.Repaint) { Handles.color = Color.green; Handles.DotHandleCap(-1, wp, Quaternion.identity, HandleUtility.GetHandleSize(wp) * k_HandleSize, evt.type); } if (evt.type == EventType.MouseDown && HandleUtility.nearestControl == m_ControlId) { evt.Use(); UndoUtility.RecordObject(polygon, "Insert Point"); polygon.m_Points.Insert(index, point); m_SelectedIndex = index; m_PlacingPoint = true; RebuildPolyShapeMesh(true); OnBeginVertexMovement(); } Handles.color = Color.white; } if (evt.type != EventType.Repaint) { SceneView.RepaintAll(); } } } } }
static void DoSizeHandles(ProBuilderShape proBuilderShape, bool updatePrefs) { int faceCount = s_Faces.Length; var evt = Event.current; var is2D = proBuilderShape.shape is Plane || proBuilderShape.shape is Sprite; for (int i = 0; i < faceCount; i++) { var face = faces[i]; if (is2D && !face.IsValid) { continue; } if (Event.current.type == EventType.Repaint) { Color color = k_BoundsHandleColor; color.a *= face.IsVisible ? 1f : 0.5f; using (new Handles.DrawingScope(color)) { int pointsCount = face.Points.Length; for (int k = 0; k < pointsCount; k++) { Handles.DrawLine(face.Points[k], face.Points[(k + 1) % pointsCount]); } } } if (DoFaceSizeHandle(face)) { float modifier = 1f; if (evt.alt) { modifier = 2f; } if (!s_SizeManipulationInit) { s_StartCenter = proBuilderShape.transform.position + proBuilderShape.transform.TransformVector(proBuilderShape.shapeBox.center); s_StartPosition = face.CenterPosition; s_StartSize = proBuilderShape.size; s_SizeManipulationInit = true; s_Scaling = Vector3.Scale(face.Normal, Math.Sign(s_StartSize)); } var targetDelta = modifier * (s_TargetSize - s_StartPosition); targetDelta.Scale(s_Scaling); var targetSize = s_StartSize + targetDelta; var snap = Math.IsCardinalAxis(proBuilderShape.transform.up) && EditorSnapSettings.gridSnapEnabled ? EditorSnapping.activeMoveSnapValue : Vector3.zero; targetSize = ProBuilderSnapping.Snap(targetSize, snap); var center = Vector3.zero; if (!evt.alt) { center = Vector3.Scale((targetSize - s_StartSize) / 2f, s_Scaling); center = Vector3.Scale(center, Math.Sign(proBuilderShape.transform.lossyScale)); center = proBuilderShape.transform.TransformVector(center); } ApplyProperties(proBuilderShape, s_StartCenter + center, targetSize); if (updatePrefs) { DrawShapeTool.SaveShapeParams(proBuilderShape); } } } }
static void DoSizeHandles(ProBuilderShape proBuilderShape, bool updatePrefs) { int faceCount = s_Faces.Length; var evt = Event.current; var is2D = proBuilderShape.shape is Plane || proBuilderShape.shape is Sprite; for (int i = 0; i < faceCount; i++) { var face = faces[i]; if (is2D && !face.IsValid) { continue; } if (Event.current.type == EventType.Repaint) { Color color = k_BoundsHandleColor; color.a *= face.IsVisible ? 1f : 0.5f; using (new Handles.DrawingScope(color)) { int pointsCount = face.Points.Length; for (int k = 0; k < pointsCount; k++) { Handles.DrawLine(face.Points[k], face.Points[(k + 1) % pointsCount]); } } } if (DoFaceSizeHandle(face, s_FaceControlIDs[i])) { if (!s_SizeManipulationInit) { s_StartCenter = proBuilderShape.transform.position + proBuilderShape.transform.TransformVector(proBuilderShape.shapeBox.center); s_StartScale = proBuilderShape.transform.lossyScale; s_StartScaleInverse = new Vector3(1f / Mathf.Abs(s_StartScale.x), 1f / Mathf.Abs(s_StartScale.y), 1f / Mathf.Abs(s_StartScale.z)); s_StartPositionLocal = face.CenterPosition; s_StartPositionGlobal = proBuilderShape.transform.TransformPoint(Vector3.Scale(face.CenterPosition, s_StartScale)); s_StartSize = proBuilderShape.size; s_SizeManipulationInit = true; s_Scaling = Vector3.Scale(face.Normal, Math.Sign(s_StartSize)); } var targetSize = s_StartSize; if (Math.IsCardinalAxis(proBuilderShape.transform.up) && EditorSnapSettings.gridSnapEnabled && !EditorSnapSettings.incrementalSnapActive && !evt.alt) { var faceDelta = (s_SizeDelta * s_Faces[i].Normal); var facePosition = s_StartPositionGlobal + faceDelta; facePosition = ProBuilderSnapping.Snap(facePosition, EditorSnapping.activeMoveSnapValue); targetSize += Vector3.Scale((facePosition - s_StartPositionGlobal), s_Scaling); } else { //Should we expand on the 2 sides? var modifier = evt.alt ? 2f : 1f; var delta = modifier * (s_SizeDelta * s_Faces[i].Normal); delta.Scale(s_Scaling); delta.Scale(s_StartScaleInverse); targetSize += delta; var snap = EditorSnapSettings.incrementalSnapActive ? Vector3.Scale(EditorSnapping.activeMoveSnapValue, Math.Abs(face.Normal)) : Vector3.zero; targetSize = ProBuilderSnapping.Snap(targetSize, snap); } var center = Vector3.zero; if (!evt.alt) { center = Vector3.Scale((targetSize - s_StartSize) / 2f, s_Scaling); center = Vector3.Scale(center, Math.Sign(s_StartScale)); center = proBuilderShape.transform.TransformVector(center); } ApplyProperties(proBuilderShape, s_StartCenter + center, targetSize); if (updatePrefs) { DrawShapeTool.SaveShapeParams(proBuilderShape); } } } }
public static float MoveSnap(float value) { return(ProBuilderSnapping.Snap(value, activeMoveSnapValue.x)); }