mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-23 04:12:12 +00:00
Things can now be moved, insterted and deleted in Visual modes.
"Place thing at cursor position" Action places Things much more precisely now.
This commit is contained in:
parent
24e1fcad6a
commit
fcd29375c8
9 changed files with 154 additions and 44 deletions
|
@ -26,9 +26,9 @@
|
|||
<li>Fog rendering (including colored fog in maps in UDMF format).</li>
|
||||
<li><a href="gz_gldefs.html">MD2 and MD3 models</a> rendering in 2D and 3D modes.</li>
|
||||
<li><a href="gz_mode_drawrect.html">Draw Rectangle</a>, <a href="gz_mode_drawellipse.html">Draw Ellipse</a> and <a href="gz_mode_drawbridge.html">Bridge</a> modes.</li>
|
||||
<li>Ability to <a href="gz_actions.html#movething">move</a>, insert and delete Things in Visual modes.</li>
|
||||
<li><a href="gz_actions.html#newtestmap">"Test Map from current position"</a> feature.</li>
|
||||
<li><a href="gz_settings.html">"Sync camera position between 2D and 3D modes"</a> feature.</li>
|
||||
<li><a href="gz_actions.html#movething">"Move Things horizontally in Visual Modes"</a> feature.</li>
|
||||
<li><a href="gz_actions.html#movethingtocursor">"Place Things at cursor position in Visual Modes"</a> feature.</li>
|
||||
<li>PNG image format support.</li>
|
||||
<li><a href="gz_plug_colorpicker.html">Color Picker plugin.</a></li>
|
||||
|
|
|
@ -1186,10 +1186,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
//mxd. gather models
|
||||
if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected) && t.Thing.IsModel) {
|
||||
ModeldefEntry mde = General.Map.Data.ModeldefEntries[t.Thing.Type];
|
||||
|
||||
//if (!isThingOnScreen(t.BoundingBox))
|
||||
//return;
|
||||
|
||||
if (!thingsWithModel.ContainsKey(mde))
|
||||
thingsWithModel.Add(mde, new List<VisualThing>());
|
||||
thingsWithModel[mde].Add(t);
|
||||
|
@ -1220,13 +1216,13 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
Vector3D thingNormal = D3DDevice.V3D(bbox[0]) - cameraposition; //bbox[0] is always thing center
|
||||
|
||||
if (Vector3D.DotProduct(camNormal, thingNormal) < 0) { //behind camera plane
|
||||
//GZBuilder.GZGeneral.TraceLine("Skipped geo. Vector3D.DotProduct(camNormal, thingNormal) < 0");
|
||||
//GZBuilder.GZGeneral.Trace("Skipped geo. Vector3D.DotProduct(camNormal, thingNormal) < 0");
|
||||
return false;
|
||||
}
|
||||
|
||||
int len = bbox.Length;
|
||||
Vector3 screenPos;
|
||||
int behingCount = 0;
|
||||
int behindCount = 0;
|
||||
int leftCount = 0;
|
||||
int rightCount = 0;
|
||||
int topCount = 0;
|
||||
|
@ -1240,7 +1236,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
return true;
|
||||
|
||||
if (screenPos.Z < 0)
|
||||
behingCount++;
|
||||
behindCount++;
|
||||
|
||||
if (screenPos.X < 0)
|
||||
leftCount++;
|
||||
|
@ -1252,8 +1248,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
bottomCount++;
|
||||
}
|
||||
|
||||
if (behingCount == len || leftCount == len || rightCount == len || topCount == len || bottomCount == len)
|
||||
if (behindCount == len || leftCount == len || rightCount == len || topCount == len || bottomCount == len) {
|
||||
//dbg
|
||||
//GZBuilder.GZGeneral.Trace("Skipped geo. Not on screen");
|
||||
return false; //Not on screen
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,14 +91,14 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
#region ================== Properties
|
||||
|
||||
// Internal properties
|
||||
internal WorldVertex[] Vertices { get { return vertices; } }
|
||||
public WorldVertex[] Vertices { get { return vertices; } } //mxd
|
||||
internal int VertexOffset { get { return vertexoffset; } set { vertexoffset = value; } }
|
||||
internal int Triangles { get { return triangles; } }
|
||||
internal int RenderPassInt { get { return renderpass; } }
|
||||
internal Color4 ModColor4 { get { return modcolor4; } }
|
||||
|
||||
//mxd
|
||||
internal Vector3[] BoundingBox { get { return boundingBox; } }
|
||||
public Vector3[] BoundingBox { get { return boundingBox; } }
|
||||
public VisualGeometryType GeometryType { get { return geoType; } }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -425,17 +425,43 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
[BeginAction("placethingatcursor", BaseAction = true)]
|
||||
protected void placeThingAtCursor() {
|
||||
Vector2D hitCoords = getHitPosition();
|
||||
if (!hitCoords.IsFinite()) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Cannot place Thing here");
|
||||
return;
|
||||
}
|
||||
|
||||
moveSelectedThings(new Vector2D((float)Math.Round(hitCoords.x), (float)Math.Round(hitCoords.y)), true);
|
||||
}
|
||||
|
||||
//mxd.
|
||||
protected Vector2D getHitPosition() {
|
||||
Vector3D start = General.Map.VisualCamera.Position;
|
||||
Vector3D delta = General.Map.VisualCamera.Target - General.Map.VisualCamera.Position;
|
||||
delta = delta.GetFixedLength(General.Settings.ViewDistance * 0.98f);
|
||||
VisualPickResult target = PickObject(start, start + delta);
|
||||
|
||||
if (target.picked == null) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Cannot place Thing here");
|
||||
return;
|
||||
if (target.picked == null) return new Vector2D(float.NaN, float.NaN);
|
||||
|
||||
//now find where exactly did we hit
|
||||
Vector2D hitCoords = new Vector2D();
|
||||
if (target.picked is VisualGeometry) {
|
||||
VisualGeometry vg = target.picked as VisualGeometry;
|
||||
hitCoords = getIntersection(start, start + delta, new Vector3D(vg.BoundingBox[0].X, vg.BoundingBox[0].Y, vg.BoundingBox[0].Z), new Vector3D(vg.Vertices[0].nx, vg.Vertices[0].ny, vg.Vertices[0].nz));
|
||||
} else if (target.picked is VisualThing) {
|
||||
VisualThing vt = target.picked as VisualThing;
|
||||
hitCoords = getIntersection(start, start + delta, new Vector3D(vt.BoundingBox[0].X, vt.BoundingBox[0].Y, vt.BoundingBox[0].Z), D3DDevice.V3D(vt.Center - vt.PositionV3));
|
||||
} else {
|
||||
return new Vector2D(float.NaN, float.NaN);
|
||||
}
|
||||
|
||||
moveSelectedThings(new Vector2D((float)Math.Round(target.hitpos.x), (float)Math.Round(target.hitpos.y)), true);
|
||||
return hitCoords;
|
||||
}
|
||||
|
||||
//mxd. this checks intersection between line and plane
|
||||
protected Vector2D getIntersection(Vector3D start, Vector3D end, Vector3D planeCenter, Vector3D planeNormal) {
|
||||
Vector3D delta = new Vector3D(planeCenter.x - start.x, planeCenter.y - start.y, planeCenter.z - start.z);
|
||||
return start + Vector3D.DotProduct(planeNormal, delta) / Vector3D.DotProduct(planeNormal, end - start) * (end - start);
|
||||
}
|
||||
|
||||
//should move selected things in specified direction
|
||||
|
|
|
@ -499,7 +499,14 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
//mxd. update bounding box
|
||||
public void UpdateBoundingBox() {
|
||||
updateBoundingBox(lightRadius, lightRadius * 2f);
|
||||
//updateBoundingBox(lightRadius, lightRadius * 2f);
|
||||
if (thing.IsModel) {
|
||||
updateBoundingBoxForModel();
|
||||
} else if (lightType != -1 && lightRadius > thing.Size) {
|
||||
updateBoundingBox(lightRadius, lightRadius * 2);
|
||||
} else {
|
||||
updateBoundingBox((int)thing.Size, thingHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBoundingBox(float width, float height) {
|
||||
|
|
|
@ -960,6 +960,40 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Copied from BuilderModes.ThingsMode
|
||||
// This creates a new thing
|
||||
private Thing InsertThing(Vector2D pos) {
|
||||
if (pos.x < General.Map.Config.LeftBoundary || pos.x > General.Map.Config.RightBoundary ||
|
||||
pos.y > General.Map.Config.TopBoundary || pos.y < General.Map.Config.BottomBoundary) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Failed to insert thing: outside of map boundaries.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create thing
|
||||
Thing t = General.Map.Map.CreateThing();
|
||||
if (t != null) {
|
||||
General.Settings.ApplyDefaultThingSettings(t);
|
||||
t.Move(pos);
|
||||
t.UpdateConfiguration();
|
||||
General.Map.IsChanged = true;
|
||||
|
||||
// Update things filter so that it includes this thing
|
||||
General.Map.ThingsFilter.Update();
|
||||
|
||||
// Snap to grid enabled?
|
||||
if (General.Interface.SnapToGrid) {
|
||||
// Snap to grid
|
||||
t.SnapToGrid();
|
||||
}
|
||||
else {
|
||||
// Snap to map format accuracy
|
||||
t.SnapToAccuracy();
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Actions
|
||||
|
@ -1309,21 +1343,59 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
PostAction();
|
||||
}
|
||||
|
||||
//mxd. now we can actually insert things in Visual modes
|
||||
[BeginAction("insertitem", BaseAction = true)]
|
||||
public void Insert()
|
||||
{
|
||||
PreAction(UndoGroup.None);
|
||||
List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, true);
|
||||
foreach(IVisualEventReceiver i in objs) i.OnInsert();
|
||||
public void Insert() {
|
||||
Vector2D hitpos = getHitPosition();
|
||||
|
||||
if (!hitpos.IsFinite()) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Cannot insert item here!");
|
||||
return;
|
||||
}
|
||||
|
||||
ClearSelection();
|
||||
PreActionNoChange();
|
||||
|
||||
General.Map.UndoRedo.CreateUndo("Insert thing");
|
||||
|
||||
Thing t = InsertThing(new Vector2D(hitpos.x, hitpos.y));
|
||||
|
||||
if (t == null) {
|
||||
General.Map.UndoRedo.WithdrawUndo();
|
||||
return;
|
||||
}
|
||||
|
||||
// Edit the thing?
|
||||
if (BuilderPlug.Me.EditNewThing)
|
||||
General.Interface.ShowEditThings(new List<Thing> { t });
|
||||
|
||||
//add thing to blockmap
|
||||
blockmap.AddThing(t);
|
||||
|
||||
General.Interface.DisplayStatus(StatusType.Action, "Inserted a new thing.");
|
||||
General.Map.IsChanged = true;
|
||||
General.Map.ThingsFilter.Update();
|
||||
PostAction();
|
||||
}
|
||||
|
||||
[BeginAction("deleteitem", BaseAction = true)]
|
||||
public void Delete()
|
||||
{
|
||||
PreAction(UndoGroup.None);
|
||||
List<IVisualEventReceiver> objs = GetSelectedObjects(true, true, true);
|
||||
foreach(IVisualEventReceiver i in objs) i.OnDelete();
|
||||
[BeginAction("deleteitem", BaseAction = true)] //mxd. now we can actually delete things in Visual modes
|
||||
public void Delete() {
|
||||
List<IVisualEventReceiver> objs = GetSelectedObjects(false, false, true);
|
||||
if (objs.Count == 0) return;
|
||||
|
||||
string rest = objs.Count + " thing" + (objs.Count > 1 ? "s." : ".");
|
||||
|
||||
//make undo
|
||||
General.Map.UndoRedo.CreateUndo("Delete " + rest);
|
||||
General.Interface.DisplayStatus(StatusType.Info, "Deleted " + rest);
|
||||
|
||||
PreActionNoChange();
|
||||
foreach (IVisualEventReceiver i in objs) i.OnDelete(); //are they deleted from BlockMap automatically?..
|
||||
|
||||
// Update cache values
|
||||
General.Map.IsChanged = true;
|
||||
General.Map.ThingsFilter.Update();
|
||||
|
||||
PostAction();
|
||||
}
|
||||
|
||||
|
|
|
@ -388,7 +388,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
public virtual void OnProcess(double deltatime) { }
|
||||
public virtual void OnTextureFloodfill() { }
|
||||
public virtual void OnInsert() { }
|
||||
public virtual void OnDelete() { }
|
||||
//public virtual void OnDelete() { }
|
||||
public virtual void ApplyTexture(string texture) { }
|
||||
public virtual void ApplyUpperUnpegged(bool set) { }
|
||||
public virtual void ApplyLowerUnpegged(bool set) { }
|
||||
|
@ -411,6 +411,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Delete thing
|
||||
public virtual void OnDelete() {
|
||||
this.Thing.Dispose();
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
// Copy properties
|
||||
public virtual void OnCopyProperties()
|
||||
{
|
||||
|
|
|
@ -1591,9 +1591,9 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
[BeginAction("insertitem", BaseAction = true)] //mxd. now we can actually insert things in Visual modes
|
||||
public void Insert()
|
||||
{
|
||||
PickTarget();
|
||||
Vector2D hitpos = getHitPosition();
|
||||
|
||||
if (target.picked == null) {
|
||||
if (!hitpos.IsFinite()) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Cannot insert item here!");
|
||||
return;
|
||||
}
|
||||
|
@ -1602,7 +1602,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
PreActionNoChange();
|
||||
|
||||
General.Map.UndoRedo.CreateUndo("Insert thing");
|
||||
Thing t = InsertThing(new Vector2D(target.hitpos.x, target.hitpos.y));
|
||||
|
||||
Thing t = InsertThing(new Vector2D(hitpos.x, hitpos.y));
|
||||
|
||||
if (t == null) {
|
||||
General.Map.UndoRedo.WithdrawUndo();
|
||||
|
|
|
@ -429,13 +429,6 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
public virtual void ApplyUpperUnpegged(bool set) { }
|
||||
public virtual void ApplyLowerUnpegged(bool set) { }
|
||||
|
||||
//mxd. Delete thing
|
||||
public virtual void OnDelete() {
|
||||
this.Thing.Dispose();
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
|
||||
// Return texture name
|
||||
public virtual string GetTextureName() { return ""; }
|
||||
|
||||
|
@ -454,6 +447,12 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Delete thing
|
||||
public virtual void OnDelete() {
|
||||
this.Thing.Dispose();
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
// Copy properties
|
||||
public virtual void OnCopyProperties()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue