diff --git a/Assets/Scripts/tools/Extruder.cs b/Assets/Scripts/tools/Extruder.cs index 657baa1a..ee1dda31 100644 --- a/Assets/Scripts/tools/Extruder.cs +++ b/Assets/Scripts/tools/Extruder.cs @@ -19,9 +19,7 @@ using com.google.apps.peltzer.client.model.controller; using com.google.apps.peltzer.client.model.core; using com.google.apps.peltzer.client.model.main; -using com.google.apps.peltzer.client.model.util; using com.google.apps.peltzer.client.model.render; -using com.google.apps.peltzer.client.tools.utils; namespace com.google.apps.peltzer.client.tools { @@ -30,7 +28,7 @@ namespace com.google.apps.peltzer.client.tools /// Update() loop. /// An extrusion is composed of grabbing a face, (potentially) pulling out the face, and releasing. The face /// itself is moved, and new faces are created to link the moved face back to the mesh. - /// + /// /// public class Extruder : MonoBehaviour { @@ -72,7 +70,7 @@ public class Extruder : MonoBehaviour private WorldSpace worldSpace; - // Detection for trigger down & straight back up, vs trigger down and hold -- either of which + // Detection for trigger down & straight back up, vs trigger down and hold -- either of which // begins an extrusion. private bool triggerUpToRelease; private float triggerDownTime; @@ -108,7 +106,7 @@ public void Setup(Model model, ControllerMain controllerMain, PeltzerController controllerMain.ControllerActionHandler += ControllerEventHandler; } - private ExtrusionOperation.ExtrusionParams BuildExtrusionParams(bool flipped) + private ExtrusionOperation.ExtrusionParams BuildExtrusionParams(bool flipped, bool multi) { // Note: ExtrusionParams is a struct, so this is stack allocated and doesn't generate garbage. ExtrusionOperation.ExtrusionParams extrusionParams = new ExtrusionOperation.ExtrusionParams(); @@ -119,6 +117,7 @@ private ExtrusionOperation.ExtrusionParams BuildExtrusionParams(bool flipped) extrusionParams.rotationModel = peltzerController.LastRotationModel * Quaternion.Inverse(extrusionBeginOrientation); extrusionParams.flipped = flipped; + extrusionParams.multipleFaces = multi; return extrusionParams; } @@ -182,7 +181,7 @@ private void Update() var dragVector = peltzerController.LastPositionModel - extrusionBeginPosition; towards = Vector3.Dot(faceVector, dragVector) > 0; } - ExtrusionOperation.ExtrusionParams extrusionParams = BuildExtrusionParams(!towards); + ExtrusionOperation.ExtrusionParams extrusionParams = BuildExtrusionParams(!towards, extrusions.Count > 1); foreach (ExtrusionOperation operation in extrusions) { operation.UpdateExtrudeGuide(extrusionParams); @@ -415,7 +414,7 @@ private void ReleaseMesh() var dragVector = peltzerController.LastPositionModel - extrusionBeginPosition; towards = Vector3.Dot(faceVector, dragVector) > 0; } - ExtrusionOperation.ExtrusionParams extrusionParams = BuildExtrusionParams(!towards); + ExtrusionOperation.ExtrusionParams extrusionParams = BuildExtrusionParams(!towards, extrusions.Count > 1); foreach (ExtrusionOperation extrusion in extrusions) { @@ -464,7 +463,7 @@ private void ReleaseMesh() } } - // Expire the temporary held face commands, because the originally-held faces have now been removed + // Expire the temporary held face commands, because the originally-held faces have now been removed // following a successful extrusion. temporaryHeldFaceMaterialCommands.Clear(); model.ApplyCommand(new CompositeCommand(commands)); diff --git a/Assets/Scripts/tools/ExtrusionOperation.cs b/Assets/Scripts/tools/ExtrusionOperation.cs index 5c632a65..84adb1c0 100644 --- a/Assets/Scripts/tools/ExtrusionOperation.cs +++ b/Assets/Scripts/tools/ExtrusionOperation.cs @@ -50,6 +50,7 @@ public struct ExtrusionParams // This is in MODEL space. public Vector3 rotationPivotModel; public bool flipped; + public bool multipleFaces; } /// @@ -476,8 +477,22 @@ public static List BuildExtrusionSides( Vector3 projectedDelta; if (extrusionParams.lockToNormal) { - var extrudedPoint = GridUtils.SnapToGrid(extrusionParams.translationModel); - projectedDelta = mesh.rotation * face.normal * (extrudedPoint.magnitude * (extrusionParams.flipped ? -1 : 1)); + if (extrusionParams.multipleFaces) + { + var extrudedPoint = GridUtils.SnapToGrid(extrusionParams.translationModel); + projectedDelta = mesh.rotation * face.normal * (extrudedPoint.magnitude * (extrusionParams.flipped ? -1 : 1)); + } + else + { + List coplanar = new List { + mesh.VertexPositionInModelCoords(face.vertexIds[0]), + mesh.VertexPositionInModelCoords(face.vertexIds[1]), + mesh.VertexPositionInModelCoords(face.vertexIds[2]) + }; + Vector3 normal = MeshMath.CalculateNormal(coplanar); + projectedDelta = + Vector3.Project(GridUtils.SnapToGrid(extrusionParams.translationModel), normal); + } } else {