diff --git a/Assets/Mogwai/Design/Icons/ic_modify_subdivide_plane.png b/Assets/Mogwai/Design/Icons/ic_modify_subdivide_plane.png new file mode 100644 index 00000000..111ab419 Binary files /dev/null and b/Assets/Mogwai/Design/Icons/ic_modify_subdivide_plane.png differ diff --git a/Assets/Mogwai/Design/Icons/ic_modify_subdivide_plane.png.meta b/Assets/Mogwai/Design/Icons/ic_modify_subdivide_plane.png.meta new file mode 100644 index 00000000..bce10335 --- /dev/null +++ b/Assets/Mogwai/Design/Icons/ic_modify_subdivide_plane.png.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: 65d6f3cd2f69efc4ba4dad3dc844733a +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 16 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 1 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/ControllerGeometryLeftRift.prefab b/Assets/Prefabs/ControllerGeometryLeftRift.prefab index e7c3f383..9cafa7fd 100644 --- a/Assets/Prefabs/ControllerGeometryLeftRift.prefab +++ b/Assets/Prefabs/ControllerGeometryLeftRift.prefab @@ -3696,7 +3696,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &4556842653616612 Transform: m_ObjectHideFlags: 0 @@ -3750,15 +3750,15 @@ SpriteRenderer: m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 - m_Sprite: {fileID: 0} + m_Sprite: {fileID: 21300000, guid: 65d6f3cd2f69efc4ba4dad3dc844733a, type: 3} m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 m_FlipY: 0 m_DrawMode: 0 - m_Size: {x: 1, y: 1} + m_Size: {x: 1.92, y: 1.92} m_AdaptiveModeThreshold: 0.5 m_SpriteTileMode: 0 - m_WasSpriteAssigned: 0 + m_WasSpriteAssigned: 1 m_MaskInteraction: 0 m_SpriteSortPoint: 0 --- !u!1 &1149554040781548 diff --git a/Assets/Prefabs/ControllerGeometryRightRift.prefab b/Assets/Prefabs/ControllerGeometryRightRift.prefab index 6b9c0e7c..e15aa59e 100644 --- a/Assets/Prefabs/ControllerGeometryRightRift.prefab +++ b/Assets/Prefabs/ControllerGeometryRightRift.prefab @@ -5117,7 +5117,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &4614152009913662 Transform: m_ObjectHideFlags: 0 @@ -5171,15 +5171,15 @@ SpriteRenderer: m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 - m_Sprite: {fileID: 0} + m_Sprite: {fileID: 21300000, guid: 65d6f3cd2f69efc4ba4dad3dc844733a, type: 3} m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 m_FlipY: 0 m_DrawMode: 0 - m_Size: {x: 1, y: 1} + m_Size: {x: 1.92, y: 1.92} m_AdaptiveModeThreshold: 0.5 m_SpriteTileMode: 0 - m_WasSpriteAssigned: 0 + m_WasSpriteAssigned: 1 m_MaskInteraction: 0 m_SpriteSortPoint: 0 --- !u!1 &1252400099692316 diff --git a/Assets/Scripts/model/controller/ChangeModeMenuItem.cs b/Assets/Scripts/model/controller/ChangeModeMenuItem.cs index 124bc51a..e2730eb5 100644 --- a/Assets/Scripts/model/controller/ChangeModeMenuItem.cs +++ b/Assets/Scripts/model/controller/ChangeModeMenuItem.cs @@ -191,6 +191,7 @@ private void ToolHeadAnimationEnd() case ControllerMode.reshape: case ControllerMode.subdivideFace: case ControllerMode.subdivideMesh: + case ControllerMode.subdividePlane: GetComponent().Activate(); break; case ControllerMode.move: diff --git a/Assets/Scripts/model/controller/ControllerMode.cs b/Assets/Scripts/model/controller/ControllerMode.cs index 3197db39..308995b9 100644 --- a/Assets/Scripts/model/controller/ControllerMode.cs +++ b/Assets/Scripts/model/controller/ControllerMode.cs @@ -73,5 +73,9 @@ public enum ControllerMode /// Mode for deleting edges. /// deletePart, + /// + /// Mode for plane subdivision. + /// + subdividePlane, } } diff --git a/Assets/Scripts/model/controller/PaletteController.cs b/Assets/Scripts/model/controller/PaletteController.cs index efdec4c3..14c24255 100644 --- a/Assets/Scripts/model/controller/PaletteController.cs +++ b/Assets/Scripts/model/controller/PaletteController.cs @@ -548,6 +548,7 @@ public GameObject GetToolheadForMode(ControllerMode mode) case ControllerMode.move: return grabToolhead; case ControllerMode.subdivideFace: + case ControllerMode.subdividePlane: case ControllerMode.reshape: case ControllerMode.extrude: return modifyToolhead; diff --git a/Assets/Scripts/model/controller/PeltzerController.cs b/Assets/Scripts/model/controller/PeltzerController.cs index ac2fe977..531ff401 100644 --- a/Assets/Scripts/model/controller/PeltzerController.cs +++ b/Assets/Scripts/model/controller/PeltzerController.cs @@ -407,6 +407,7 @@ public void CacheTooltips() tooltips.Add(ControllerMode.reshape, controllerGeometry.modifyTooltips); tooltips.Add(ControllerMode.subdivideMesh, controllerGeometry.modifyTooltips); tooltips.Add(ControllerMode.subdivideFace, controllerGeometry.modifyTooltips); + tooltips.Add(ControllerMode.subdividePlane, controllerGeometry.modifyTooltips); tooltips.Add(ControllerMode.paintFace, controllerGeometry.paintTooltips); tooltips.Add(ControllerMode.paintMesh, controllerGeometry.paintTooltips); tooltips.Add(ControllerMode.move, controllerGeometry.grabTooltips); @@ -741,7 +742,7 @@ private void HandleMenuItemPoint() return; } - // At this point, we know something on the menu has been hit, so we update variables accordingly and + // At this point, we know something on the menu has been hit, so we update variables accordingly and // hide the shapes menu. menuIsInDefaultState = false; isPointingAtMenu = true; @@ -1192,6 +1193,10 @@ private void ControllerEventHandler(object sender, ControllerEventArgs args) { ChangeMode(ControllerMode.subdivideFace); } + else if (location == TouchpadLocation.BOTTOM && mode != ControllerMode.subdividePlane) + { + ChangeMode(ControllerMode.subdividePlane); + } else if (location == TouchpadLocation.RIGHT && mode != ControllerMode.extrude) { ChangeMode(ControllerMode.extrude); @@ -1243,7 +1248,8 @@ private bool IsModifyMode(ControllerMode mode) return mode == ControllerMode.reshape || mode == ControllerMode.extrude || mode == ControllerMode.subdivideFace - || mode == ControllerMode.subdivideMesh; + || mode == ControllerMode.subdivideMesh + || mode == ControllerMode.subdividePlane; } private bool IsDeleteMode(ControllerMode mode) @@ -1335,6 +1341,7 @@ public void ChangeMode(ControllerMode newMode, GameObject toolHead = null) case ControllerMode.reshape: case ControllerMode.subdivideFace: case ControllerMode.subdivideMesh: + case ControllerMode.subdividePlane: attachedToolHead.GetComponent().Deactivate(); switch (newMode) { @@ -1343,6 +1350,7 @@ public void ChangeMode(ControllerMode newMode, GameObject toolHead = null) break; case ControllerMode.subdivideFace: case ControllerMode.subdivideMesh: + case ControllerMode.subdividePlane: PeltzerMain.Instance.GetSelector().UpdateInactive(Selector.EDGES_ONLY); break; default: @@ -1609,6 +1617,18 @@ public void ChangeTouchpadOverlay(TouchpadOverlay newOverlay) controllerGeometry.modifyOverlay.GetComponent().upIcon.color = halfWhite; // Extrude. controllerGeometry.modifyOverlay.GetComponent().rightIcon.color = halfWhite; + // Plane. + controllerGeometry.modifyOverlay.GetComponent().downIcon.color = halfWhite; + break; + case ControllerMode.subdividePlane: + // Subdivide. + controllerGeometry.modifyOverlay.GetComponent().leftIcon.color = halfWhite; + // Reshape. + controllerGeometry.modifyOverlay.GetComponent().upIcon.color = halfWhite; + // Extrude. + controllerGeometry.modifyOverlay.GetComponent().rightIcon.color = halfWhite; + // Plane. + controllerGeometry.modifyOverlay.GetComponent().downIcon.color = fullWhite; break; case ControllerMode.reshape: // Subdivide. @@ -1617,6 +1637,8 @@ public void ChangeTouchpadOverlay(TouchpadOverlay newOverlay) controllerGeometry.modifyOverlay.GetComponent().upIcon.color = fullWhite; // Extrude. controllerGeometry.modifyOverlay.GetComponent().rightIcon.color = halfWhite; + // Plane. + controllerGeometry.modifyOverlay.GetComponent().downIcon.color = halfWhite; break; case ControllerMode.extrude: // Subdivide. @@ -1625,6 +1647,8 @@ public void ChangeTouchpadOverlay(TouchpadOverlay newOverlay) controllerGeometry.modifyOverlay.GetComponent().upIcon.color = halfWhite; // Extrude. controllerGeometry.modifyOverlay.GetComponent().rightIcon.color = fullWhite; + // Plane. + controllerGeometry.modifyOverlay.GetComponent().downIcon.color = halfWhite; break; case ControllerMode.delete: controllerGeometry.deleteOverlay.GetComponent().leftIcon.gameObject @@ -1689,6 +1713,7 @@ public void ChangeTouchpadOverlay(TouchpadOverlay newOverlay) case ControllerMode.extrude: case ControllerMode.subdivideFace: case ControllerMode.subdivideMesh: + case ControllerMode.subdividePlane: currentOverlayGO = controllerGeometry.modifyOverlay; break; case ControllerMode.delete: @@ -1727,20 +1752,13 @@ public void ResetTouchpadOverlay() ChangeTouchpadOverlay(TouchpadOverlay.FREEFORM); break; case ControllerMode.reshape: - ChangeTouchpadOverlay(TouchpadOverlay.MODIFY); - break; case ControllerMode.extrude: - ChangeTouchpadOverlay(TouchpadOverlay.MODIFY); - break; case ControllerMode.subdivideFace: - ChangeTouchpadOverlay(TouchpadOverlay.MODIFY); - break; case ControllerMode.subdivideMesh: + case ControllerMode.subdividePlane: ChangeTouchpadOverlay(TouchpadOverlay.MODIFY); break; case ControllerMode.deletePart: - ChangeTouchpadOverlay(TouchpadOverlay.DELETE); - break; case ControllerMode.delete: ChangeTouchpadOverlay(TouchpadOverlay.DELETE); break; @@ -1748,8 +1766,6 @@ public void ResetTouchpadOverlay() ChangeTouchpadOverlay(TouchpadOverlay.MOVE); break; case ControllerMode.paintMesh: - ChangeTouchpadOverlay(TouchpadOverlay.PAINT); - break; case ControllerMode.paintFace: ChangeTouchpadOverlay(TouchpadOverlay.PAINT); break; @@ -1849,7 +1865,7 @@ public void ControllerHandednessChanged() /// /// Determines which tooltip and where to show it when called. These are the grip tooltips to /// advise a user how to move/zoom the world. - /// We only show these tooltips until the user has successfully moved or zoomed the world. + /// We only show these tooltips until the user has successfully moved or zoomed the world. /// We do not show these tooltips until at least one object is in the scene. /// We do not show these tooltips during tutorials. /// diff --git a/Assets/Scripts/model/main/Features.cs b/Assets/Scripts/model/main/Features.cs index 6614c0ef..aaf9088b 100644 --- a/Assets/Scripts/model/main/Features.cs +++ b/Assets/Scripts/model/main/Features.cs @@ -89,10 +89,6 @@ public class Features // Incompatible with planeSubdivideEnabled. public static bool loopSubdivideEnabled = false; - // If true, the subdivide tool will turn into the experimental plane subdivide form. - // Incompatible with loopSubdivideEnabled. - public static bool planeSubdivideEnabled = false; - // If true, allow noncoplanar faces to remain during mesh fixing. public static bool allowNoncoplanarFaces = false; diff --git a/Assets/Scripts/model/main/PeltzerMain.cs b/Assets/Scripts/model/main/PeltzerMain.cs index d2bda311..053f9828 100644 --- a/Assets/Scripts/model/main/PeltzerMain.cs +++ b/Assets/Scripts/model/main/PeltzerMain.cs @@ -1704,6 +1704,8 @@ public bool OperationInProgress() return reshaper.IsReshaping(); case ControllerMode.subdivideFace: return false; + case ControllerMode.subdividePlane: + return false; case ControllerMode.subtract: return volumeInserter.IsFilling(); } diff --git a/Assets/Scripts/tools/Subdivider.cs b/Assets/Scripts/tools/Subdivider.cs index 02290351..ceb08e3d 100644 --- a/Assets/Scripts/tools/Subdivider.cs +++ b/Assets/Scripts/tools/Subdivider.cs @@ -21,8 +21,6 @@ using com.google.apps.peltzer.client.model.main; using com.google.apps.peltzer.client.model.util; using com.google.apps.peltzer.client.tools.utils; -using com.google.apps.peltzer.client.model.render; -using System; namespace com.google.apps.peltzer.client.tools { @@ -158,7 +156,7 @@ private bool pressAndHoldEnabled GameObject guidanceMesh; /// - /// Keeps track of the faces that each edge in the mesh is connecting. This is needed to find + /// Keeps track of the faces that each edge in the mesh is connecting. This is needed to find /// the next face when performing loop subdivide operations. /// private Dictionary> edgeKeysToFaceIds = new Dictionary>(); @@ -211,47 +209,60 @@ void Update() PeltzerMain.Instance.highlightUtils.TurnOff(highlightToTurnOff.Value); } - if (!PeltzerController.AcquireIfNecessary(ref peltzerController) || peltzerController.mode != ControllerMode.subdivideFace) + bool anySubdivideMode = + peltzerController.mode == ControllerMode.subdivideFace || + peltzerController.mode == ControllerMode.subdividePlane; + if (anySubdivideMode && PeltzerController.AcquireIfNecessary(ref peltzerController)) { - return; - } + bool isNewMode = false; + if (pressAndHoldEnabled + && currentMode != Mode.PLANE_SUBDIVIDE + && isTriggerBeingHeld + && Time.time > triggerHoldStartTime + PRESS_AND_HOLD_DELAY) + { + currentMode = Mode.LOOP_SUBDIVIDE; + audioLibrary.PlayClip(audioLibrary.genericSelectSound); + peltzerController.TriggerHapticFeedback(); + isTriggerBeingHeld = false; + isNewMode = true; + } - bool isNewMode = false; - if (pressAndHoldEnabled - && isTriggerBeingHeld - && Time.time > triggerHoldStartTime + PRESS_AND_HOLD_DELAY) - { - currentMode = Mode.LOOP_SUBDIVIDE; - audioLibrary.PlayClip(audioLibrary.genericSelectSound); - peltzerController.TriggerHapticFeedback(); - isTriggerBeingHeld = false; - isNewMode = true; - } + // Update the position of the selector. + if (currentMode == Mode.PLANE_SUBDIVIDE) + { + selector.SelectMeshAtPosition(peltzerController.LastPositionModel, Selector.MESHES_ONLY); + } + else + { + selector.SelectAtPosition(peltzerController.LastPositionModel, Selector.FACES_ONLY); + } + selector.UpdateInactive(Selector.EDGES_ONLY); - // Update the position of the selector. - if (currentMode == Mode.PLANE_SUBDIVIDE) - { - selector.SelectMeshAtPosition(peltzerController.LastPositionModel, Selector.MESHES_ONLY); - } - else - { - selector.SelectAtPosition(peltzerController.LastPositionModel, Selector.FACES_ONLY); - } - selector.UpdateInactive(Selector.EDGES_ONLY); + // Clean up all temp edges. + foreach (EdgeTemporaryStyle.TemporaryEdge tempEdge in currentTemporaryEdges) + { + PeltzerMain.Instance.highlightUtils.TurnOff(tempEdge); + } + currentTemporaryEdges.Clear(); - // Clean up all temp edges. - foreach (EdgeTemporaryStyle.TemporaryEdge tempEdge in currentTemporaryEdges) - { - PeltzerMain.Instance.highlightUtils.TurnOff(tempEdge); + UpdateHighlights(isNewMode); } - currentTemporaryEdges.Clear(); - UpdateHighlights(isNewMode); } private void ControllerModeChangedHandler(ControllerMode oldMode, ControllerMode newMode) { - if (oldMode == ControllerMode.subdivideFace) + switch (newMode) + { + case ControllerMode.subdivideFace: + currentMode = Mode.SINGLE_FACE_SUBDIVIDE; + break; + case ControllerMode.subdividePlane: + currentMode = Mode.PLANE_SUBDIVIDE; + break; + } + if (oldMode == ControllerMode.subdivideFace || + oldMode == ControllerMode.subdividePlane) { ClearState(); UnsetAllHoverTooltips(); @@ -402,18 +413,35 @@ private void UpdateHighlightsForPlaneSubdivide() selectedMeshes.Add(model.GetMesh(hoverMeshId)); } - Vector3 planeNormal = (peltzerController.LastRotationModel * Vector3.up).normalized; - Vector3 planeOffset = peltzerController.LastPositionModel; + Vector3 planeNormal; + + if (isSnapping) + { + Vector3 forward = peltzerController.LastRotationModel * Vector3.up; - // TODO(bug): Use Graphics.DrawMesh instead. - Plane plane = new Plane(planeNormal, planeOffset); - if (guidanceMesh == null) + float dotX = Mathf.Abs(Vector3.Dot(forward, Vector3.right)); + float dotY = Mathf.Abs(Vector3.Dot(forward, Vector3.up)); + float dotZ = Mathf.Abs(Vector3.Dot(forward, Vector3.forward)); + + if (dotX > dotY && dotX > dotZ) + { + planeNormal = Vector3.right; // Closest to the X-axis + } + else if (dotY > dotX && dotY > dotZ) + { + planeNormal = Vector3.up; // Closest to the Y-axis + } + else + { + planeNormal = Vector3.forward; // Closest to the Z-axis + } + } + else { - guidanceMesh = CreatePlaneGuidanceMesh(); + planeNormal = (peltzerController.LastRotationModel * Vector3.up).normalized; } - guidanceMesh.transform.position = worldSpace.ModelToWorld(planeOffset); - guidanceMesh.transform.rotation = worldSpace.ModelOrientationToWorld(peltzerController.LastRotationModel); + Plane plane = new Plane(planeNormal, peltzerController.LastPositionModel); // Go through each face in each mesh and find intersection points with the plane. foreach (MMesh mesh in selectedMeshes) @@ -685,8 +713,8 @@ private void AdjustSubdivisionForEdgeCutPercentage(Subdivision subdivision, // The orientation of these points within an edge is not a concern here because // GetFaceVertexIndicesForEdge() will get us the indices as they appear in clockwise - // manner along the face. This means that the vertices indices will be flipped for - // a face in which they appear on the exitEdge, and the next subdivision on the + // manner along the face. This means that the vertices indices will be flipped for + // a face in which they appear on the exitEdge, and the next subdivision on the // chain, in which the same edge will be the origin edge instead. // Points on the origin edge. @@ -857,15 +885,6 @@ public void ClearState() Destroy(guidanceMesh); guidanceMesh = null; activeSubdivisions.Clear(); - - if (Features.planeSubdivideEnabled) - { - currentMode = Mode.PLANE_SUBDIVIDE; - } - else - { - currentMode = Mode.SINGLE_FACE_SUBDIVIDE; - } } private bool IsStartPressAndHoldEvent(ControllerEventArgs args) @@ -1246,7 +1265,8 @@ public static List MaybeInsertVert(Face face, int startId, int endId, int n /// private void ControllerEventHandler(object sender, ControllerEventArgs args) { - if (peltzerController.mode != ControllerMode.subdivideFace) + if (peltzerController.mode != ControllerMode.subdivideFace && + peltzerController.mode != ControllerMode.subdividePlane) return; if (IsStartPressAndHoldEvent(args))