diff --git a/Source/BuilderModes/VisualModes/BaseVisualGeometrySector.cs b/Source/BuilderModes/VisualModes/BaseVisualGeometrySector.cs index 529ee9fc..7a7ec71b 100644 --- a/Source/BuilderModes/VisualModes/BaseVisualGeometrySector.cs +++ b/Source/BuilderModes/VisualModes/BaseVisualGeometrySector.cs @@ -75,6 +75,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public virtual void OnSelectBegin() { } public virtual void OnSelectEnd() { } public virtual void OnEditBegin() { } + public virtual void OnMouseMove(MouseEventArgs e) { } // Edit button released public virtual void OnEditEnd() diff --git a/Source/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs index bbaa101b..d6312ef2 100644 --- a/Source/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs +++ b/Source/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs @@ -39,7 +39,9 @@ namespace CodeImp.DoomBuilder.BuilderModes internal abstract class BaseVisualGeometrySidedef : VisualGeometry, IVisualEventReceiver { #region ================== Constants - + + private const float DRAG_ANGLE_TOLERANCE = 0.02f; + #endregion #region ================== Variables @@ -49,18 +51,32 @@ namespace CodeImp.DoomBuilder.BuilderModes protected float top; protected float bottom; + // UV dragging + private float dragstartanglexy; + private float dragstartanglez; + private Vector3D dragorigin; + private Vector3D deltaxy; + private Vector3D deltaz; + private int startoffsetx; + private int startoffsety; + protected bool uvdragging; + #endregion - + #region ================== Properties - + + public bool IsDraggingUV { get { return uvdragging; } } + #endregion - + #region ================== Constructor / Destructor // Constructor for sidedefs public BaseVisualGeometrySidedef(BaseVisualMode mode, VisualSector vs, Sidedef sd) : base(vs, sd) { this.mode = mode; + this.deltaz = new Vector3D(0.0f, 0.0f, 1.0f); + this.deltaxy = (sd.Line.End.Position - sd.Line.Start.Position) * sd.Line.LengthInv; } #endregion @@ -86,19 +102,86 @@ namespace CodeImp.DoomBuilder.BuilderModes #endregion #region ================== Events - + // Unused public virtual void OnSelectBegin() { } public virtual void OnSelectEnd() { } - public virtual void OnEditBegin() { } + + // Edit button pressed + public virtual void OnEditBegin() + { + dragstartanglexy = mode.CameraAngleXY; + dragstartanglez = mode.CameraAngleZ; + dragorigin = pickintersect; + startoffsetx = Sidedef.OffsetX; + startoffsety = Sidedef.OffsetY; + } // Edit button released public virtual void OnEditEnd() { - List lines = new List(); - lines.Add(this.Sidedef.Line); - DialogResult result = General.Interface.ShowEditLinedefs(lines); - if(result == DialogResult.OK) (this.Sector as BaseVisualSector).Rebuild(); + // Was dragging? + if(uvdragging) + { + // Dragging stops now + mode.UnlockTarget(); + uvdragging = false; + } + else + { + List lines = new List(); + lines.Add(this.Sidedef.Line); + DialogResult result = General.Interface.ShowEditLinedefs(lines); + if(result == DialogResult.OK) (this.Sector as BaseVisualSector).Rebuild(); + } + } + + // Mouse moves + public virtual void OnMouseMove(MouseEventArgs e) + { + // Dragging UV? + if(uvdragging) + { + UpdateDragUV(); + } + else + { + // Check if tolerance is exceeded to start UV dragging + float deltaxy = mode.CameraAngleXY - dragstartanglexy; + float deltaz = mode.CameraAngleZ - dragstartanglez; + if((Math.Abs(deltaxy) + Math.Abs(deltaz)) > DRAG_ANGLE_TOLERANCE) + { + // Start drag now + uvdragging = true; + mode.LockTarget(); + UpdateDragUV(); + } + } + } + + // This is called to update UV dragging + protected virtual void UpdateDragUV() + { + float u_ray; + + // Calculate intersection position + Line2D ray = new Line2D(mode.CameraPosition, mode.CameraTarget); + Sidedef.Line.Line.GetIntersection(ray, out u_ray); + Vector3D intersect = mode.CameraPosition + (mode.CameraTarget - mode.CameraPosition) * u_ray; + + // Calculate offsets + Vector3D dragdelta = intersect - dragorigin; + Vector3D dragdeltaxy = dragdelta * deltaxy; + Vector3D dragdeltaz = dragdelta * deltaz; + float offsetx = dragdeltaxy.GetLength(); + float offsety = dragdeltaz.GetLength(); + + // Apply offsets + Sidedef.OffsetX = startoffsetx + (int)Math.Round(offsetx); + Sidedef.OffsetY = startoffsety + (int)Math.Round(offsety); + + // TODO: Update sidedef geometry + } #endregion diff --git a/Source/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/BuilderModes/VisualModes/BaseVisualMode.cs index 414a5ec6..083c86e0 100644 --- a/Source/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/BuilderModes/VisualModes/BaseVisualMode.cs @@ -120,6 +120,12 @@ namespace CodeImp.DoomBuilder.BuilderModes locktarget = false; } + // This picks a new target, if not locked + private void PickTargetUnlocked() + { + if(!locktarget) PickTarget(); + } + // This picks a new target private void PickTarget() { @@ -220,7 +226,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Time to pick a new target? if(General.Clock.CurrentTime > (lastpicktime + PICK_INTERVAL)) { - if(!locktarget) PickTarget(); + PickTargetUnlocked(); lastpicktime = General.Clock.CurrentTime; } } @@ -269,13 +275,20 @@ namespace CodeImp.DoomBuilder.BuilderModes PickTarget(); } + // Mouse moves + public override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + } + #endregion #region ================== Actions - + [BeginAction("visualselect", BaseAction = true)] public void BeginSelect() { + PickTargetUnlocked(); if(target.picked != null) (target.picked as IVisualEventReceiver).OnSelectBegin(); } @@ -288,6 +301,7 @@ namespace CodeImp.DoomBuilder.BuilderModes [BeginAction("visualedit", BaseAction = true)] public void BeginEdit() { + PickTargetUnlocked(); if(target.picked != null) (target.picked as IVisualEventReceiver).OnEditBegin(); } @@ -300,24 +314,28 @@ namespace CodeImp.DoomBuilder.BuilderModes [BeginAction("raisesector8")] public void RaiseSector8() { + PickTargetUnlocked(); ChangeTargetHeight(8); } [BeginAction("lowersector8")] public void LowerSector8() { + PickTargetUnlocked(); ChangeTargetHeight(-8); } [BeginAction("raisesector1")] public void RaiseSector1() { + PickTargetUnlocked(); ChangeTargetHeight(1); } - + [BeginAction("lowersector1")] public void LowerSector1() { + PickTargetUnlocked(); ChangeTargetHeight(-1); } diff --git a/Source/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/BuilderModes/VisualModes/BaseVisualThing.cs index b06d7a1e..a9d78e6e 100644 --- a/Source/BuilderModes/VisualModes/BaseVisualThing.cs +++ b/Source/BuilderModes/VisualModes/BaseVisualThing.cs @@ -331,6 +331,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public virtual void OnSelectBegin() { } public virtual void OnSelectEnd() { } public virtual void OnEditBegin() { } + public virtual void OnMouseMove(MouseEventArgs e) { } // Edit button released public virtual void OnEditEnd() diff --git a/Source/BuilderModes/VisualModes/IVisualEventReceiver.cs b/Source/BuilderModes/VisualModes/IVisualEventReceiver.cs index e2d806fe..179198ac 100644 --- a/Source/BuilderModes/VisualModes/IVisualEventReceiver.cs +++ b/Source/BuilderModes/VisualModes/IVisualEventReceiver.cs @@ -43,5 +43,6 @@ namespace CodeImp.DoomBuilder.BuilderModes void OnSelectEnd(); void OnEditBegin(); void OnEditEnd(); + void OnMouseMove(MouseEventArgs e); } } diff --git a/Source/VisualModes/VisualMode.cs b/Source/VisualModes/VisualMode.cs index 8df97da6..81edb6b6 100644 --- a/Source/VisualModes/VisualMode.cs +++ b/Source/VisualModes/VisualMode.cs @@ -93,6 +93,8 @@ namespace CodeImp.DoomBuilder.VisualModes public Vector3D CameraPosition { get { return campos; } set { campos = value; } } public Vector3D CameraTarget { get { return camtarget; } } + public float CameraAngleXY { get { return camanglexy; } } + public float CameraAngleZ { get { return camanglez; } } public Sector CameraSector { get { return camsector; } } public bool ProcessGeometry { get { return processgeometry; } set { processgeometry = value; } } public bool ProcessThings { get { return processthings; } set { processthings = value; } }