Collisions editing beginnings

This commit is contained in:
dexy 2020-01-02 00:16:49 +11:00
parent f51d5644fd
commit d85f5eddb2
7 changed files with 704 additions and 42 deletions

View File

@ -130,7 +130,7 @@ namespace CodeWalker.GameFiles
public float BoundingBoxVolume { get; set; }
public Bounds Parent { get; set; }
public BoundComposite Parent { get; set; }
public string OwnerName { get; set; }
public string GetName()
{
@ -147,6 +147,49 @@ namespace CodeWalker.GameFiles
public Matrix Transform { get; set; } = Matrix.Identity; //when it's the child of a bound composite
public Matrix TransformInv { get; set; } = Matrix.Identity;
public virtual Vector3 Scale
{
get
{
return Transform.ScaleVector;
}
set
{
var m = Transform;
m.ScaleVector = value;
Transform = m;
TransformInv = Matrix.Invert(m);
}
}
public virtual Vector3 Position
{
get
{
return Transform.TranslationVector;
}
set
{
var m = Transform;
m.TranslationVector = value;
Transform = m;
TransformInv = Matrix.Invert(m);
}
}
public virtual Quaternion Orientation
{
get
{
return Transform.ToQuaternion();
}
set
{
var m = value.ToMatrix();
m.TranslationVector = Transform.TranslationVector;
m.ScaleVector = Transform.ScaleVector;
Transform = m;
TransformInv = Matrix.Invert(m);
}
}
/// <summary>
/// Reads the data-block from a stream.
@ -1365,6 +1408,9 @@ namespace CodeWalker.GameFiles
public BoundPolygonType Type { get; set; }
public BoundGeometry Owner { get; set; } //for browsing/editing convenience
public int Index { get; set; } //for editing convenience, not stored
public abstract Vector3 Scale { get; set; }
public abstract Vector3 Position { get; set; }
public abstract Quaternion Orientation { get; set; }
public abstract void Read(byte[] bytes, int offset);
public abstract void Write(BinaryWriter bw);
public override string ToString()
@ -1405,6 +1451,41 @@ namespace CodeWalker.GameFiles
set { if (Owner != null) Owner.SetVertexPos(vertIndex3, value); }
}
public override Vector3 Scale
{
get
{
return Vector3.One;
}
set
{
}
}
public override Vector3 Position
{
get
{
return (Vertex1 + Vertex2 + Vertex3) * (1.0f / 3.0f);
}
set
{
var offset = value - Position;
Vertex1 += offset;
Vertex2 += offset;
Vertex3 += offset;
}
}
public override Quaternion Orientation
{
get
{
return Quaternion.Identity;
}
set
{
}
}
public BoundPolygonTriangle()
{
Type = BoundPolygonType.Triangle;
@ -1442,11 +1523,31 @@ namespace CodeWalker.GameFiles
public uint unused0 { get; set; }
public uint unused1 { get; set; }
public Vector3 Position
public override Vector3 Scale
{
get
{
return Vector3.One;
}
set
{
}
}
public override Vector3 Position
{
get { return (Owner != null) ? Owner.GetVertexPos(sphereIndex) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(sphereIndex, value); }
}
public override Quaternion Orientation
{
get
{
return Quaternion.Identity;
}
set
{
}
}
public BoundPolygonSphere()
{
@ -1493,6 +1594,40 @@ namespace CodeWalker.GameFiles
set { if (Owner != null) Owner.SetVertexPos(capsuleIndex2, value); }
}
public override Vector3 Scale
{
get
{
return Vector3.One;
}
set
{
}
}
public override Vector3 Position
{
get
{
return (Vertex1 + Vertex2) * 0.5f;
}
set
{
var offset = value - Position;
Vertex1 += offset;
Vertex2 += offset;
}
}
public override Quaternion Orientation
{
get
{
return Quaternion.Identity;
}
set
{
}
}
public BoundPolygonCapsule()
{
Type = BoundPolygonType.Capsule;
@ -1550,6 +1685,42 @@ namespace CodeWalker.GameFiles
set { if (Owner != null) Owner.SetVertexPos(boxIndex4, value); }
}
public override Vector3 Scale
{
get
{
return Vector3.One;
}
set
{
}
}
public override Vector3 Position
{
get
{
return (Vertex1 + Vertex2 + Vertex3 + Vertex4) * 0.25f;
}
set
{
var offset = value - Position;
Vertex1 += offset;
Vertex2 += offset;
Vertex3 += offset;
Vertex4 += offset;
}
}
public override Quaternion Orientation
{
get
{
return Quaternion.Identity;
}
set
{
}
}
public BoundPolygonBox()
{
Type = BoundPolygonType.Box;
@ -1597,6 +1768,40 @@ namespace CodeWalker.GameFiles
set { if (Owner != null) Owner.SetVertexPos(cylinderIndex2, value); }
}
public override Vector3 Scale
{
get
{
return Vector3.One;
}
set
{
}
}
public override Vector3 Position
{
get
{
return (Vertex1 + Vertex2) * 0.5f;
}
set
{
var offset = value - Position;
Vertex1 += offset;
Vertex2 += offset;
}
}
public override Quaternion Orientation
{
get
{
return Quaternion.Identity;
}
set
{
}
}
public BoundPolygonCylinder()
{
Type = BoundPolygonType.Cylinder;
@ -1708,6 +1913,14 @@ namespace CodeWalker.GameFiles
public void BuildBVH()
{
}
public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph)
{
var res = new SpaceSphereIntersectResult();
@ -1742,11 +1955,11 @@ namespace CodeWalker.GameFiles
box.Maximum = new Vector3(node.MaxX, node.MaxY, node.MaxZ) * q + c;
bool nodehit = sph.Intersects(ref box);
bool nodeskip = !nodehit;
if (node.PolyCount <= 0) //intermediate node with child nodes
if (node.ItemCount <= 0) //intermediate node with child nodes
{
if (nodeskip)
{
nodeind += node.PolyId; //(child node count)
nodeind += node.ItemId; //(child node count)
}
else
{
@ -1757,9 +1970,9 @@ namespace CodeWalker.GameFiles
{
if (!nodeskip)
{
var lastp = Math.Min(node.PolyId + node.PolyCount, (int)PolygonsCount);
var lastp = Math.Min(node.ItemId + node.ItemCount, (int)PolygonsCount);
SphereIntersectPolygons(ref sph, ref res, node.PolyId, lastp);
SphereIntersectPolygons(ref sph, ref res, node.ItemId, lastp);
}
nodeind++;
@ -1812,11 +2025,11 @@ namespace CodeWalker.GameFiles
box.Maximum = new Vector3(node.MaxX, node.MaxY, node.MaxZ) * q + c;
bool nodehit = ray.Intersects(ref box, out bvhboxhittest);
bool nodeskip = !nodehit || (bvhboxhittest > res.HitDist);
if (node.PolyCount <= 0) //intermediate node with child nodes
if (node.ItemCount <= 0) //intermediate node with child nodes
{
if (nodeskip)
{
nodeind += node.PolyId; //(child node count)
nodeind += node.ItemId; //(child node count)
}
else
{
@ -1827,9 +2040,9 @@ namespace CodeWalker.GameFiles
{
if (!nodeskip)
{
var lastp = Math.Min(node.PolyId + node.PolyCount, (int)PolygonsCount);
var lastp = Math.Min(node.ItemId + node.ItemCount, (int)PolygonsCount);
RayIntersectPolygons(ref ray, ref res, node.PolyId, lastp);
RayIntersectPolygons(ref ray, ref res, node.ItemId, lastp);
}
nodeind++;
@ -2008,6 +2221,15 @@ namespace CodeWalker.GameFiles
public void BuildBVH()
{
}
public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph)
{
var res = new SpaceSphereIntersectResult();
@ -2218,12 +2440,12 @@ namespace CodeWalker.GameFiles
public short MaxX { get; set; }
public short MaxY { get; set; }
public short MaxZ { get; set; }
public short PolyId { get; set; }
public short PolyCount { get; set; }
public short ItemId { get; set; }
public short ItemCount { get; set; }
public override string ToString()
{
return PolyId.ToString() + ": " + PolyCount.ToString();
return ItemId.ToString() + ": " + ItemCount.ToString();
}
}

View File

@ -45,6 +45,12 @@ namespace CodeWalker
return new Vector4(x, y, z, w);
}
public static Quaternion ToQuaternion(this Matrix m)
{
var rmat = m;
rmat.TranslationVector = Vector3.Zero;
return Quaternion.RotationMatrix(rmat);
}
}
}

View File

@ -65,6 +65,7 @@ namespace CodeWalker.Project
Dictionary<YnvFile, int> navYnvs = new Dictionary<YnvFile, int>();
Dictionary<TrainTrack, int> trainTracks = new Dictionary<TrainTrack, int>();
Dictionary<YmtFile, int> scenarioYmts = new Dictionary<YmtFile, int>();
Dictionary<Bounds, int> bounds = new Dictionary<Bounds, int>();
if (Items != null)
{
@ -94,9 +95,21 @@ namespace CodeWalker.Project
{
scenarioYmts[item.ScenarioNode.Ymt] = 1;
}
if (item.CollisionBounds != null)
{
bounds[item.CollisionBounds] = 1;
}
if (item.CollisionPoly?.Owner != null)
{
bounds[item.CollisionPoly.Owner] = 1;
}
}
}
foreach (var kvp in bounds)
{
wf.UpdateCollisionBoundsGraphics(kvp.Key);
}
foreach (var kvp in pathYnds)
{
wf.UpdatePathYndGraphics(kvp.Key, true);
@ -172,7 +185,6 @@ namespace CodeWalker.Project
return (Entity?._CEntityDef.archetypeName.ToString() ?? "") + ": Position";
}
}
public class EntityRotationUndoStep : UndoStep
{
public YmapEntityDef Entity { get; set; }
@ -211,7 +223,6 @@ namespace CodeWalker.Project
return (Entity?._CEntityDef.archetypeName.ToString() ?? "") + ": Rotation";
}
}
public class EntityScaleUndoStep : UndoStep
{
public YmapEntityDef Entity { get; set; }
@ -252,6 +263,7 @@ namespace CodeWalker.Project
}
public class EntityPivotPositionUndoStep : UndoStep
{
public YmapEntityDef Entity { get; set; }
@ -288,7 +300,6 @@ namespace CodeWalker.Project
return (Entity?._CEntityDef.archetypeName.ToString() ?? "") + ": Pivot Position";
}
}
public class EntityPivotRotationUndoStep : UndoStep
{
public YmapEntityDef Entity { get; set; }
@ -366,7 +377,6 @@ namespace CodeWalker.Project
return "CarGen " + (CarGen?._CCarGen.carModel.ToString() ?? "") + ": Position";
}
}
public class CarGenRotationUndoStep : UndoStep
{
public YmapCarGen CarGen { get; set; }
@ -404,7 +414,6 @@ namespace CodeWalker.Project
return "CarGen " + (CarGen?._CCarGen.carModel.ToString() ?? "") + ": Rotation";
}
}
public class CarGenScaleUndoStep : UndoStep
{
public YmapCarGen CarGen { get; set; }
@ -445,6 +454,317 @@ namespace CodeWalker.Project
public class CollisionPositionUndoStep : UndoStep
{
public Bounds Bounds { get; set; }
public Vector3 StartPosition { get; set; }
public Vector3 EndPosition { get; set; }
public CollisionPositionUndoStep(Bounds bounds, Vector3 startpos, WorldForm wf)
{
Bounds = bounds;
StartPosition = startpos;
EndPosition = bounds?.Position ?? Vector3.Zero;
UpdateGraphics(wf);
}
private void Update(WorldForm wf, ref MapSelection sel, Vector3 p)
{
if (Bounds != null)
{
Bounds.Position = p;
}
if (Bounds != sel.CollisionBounds) wf.SelectCollisionBounds(Bounds);
wf.SetWidgetPosition(p);
UpdateGraphics(wf);
}
private void UpdateGraphics(WorldForm wf)
{
if (Bounds != null)
{
wf.UpdateCollisionBoundsGraphics(Bounds);
}
}
public override void Undo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, StartPosition);
}
public override void Redo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, EndPosition);
}
public override string ToString()
{
return "Collision " + (Bounds?.GetName() ?? "") + ": Position";
}
}
public class CollisionRotationUndoStep : UndoStep
{
public Bounds Bounds { get; set; }
public Quaternion StartRotation { get; set; }
public Quaternion EndRotation { get; set; }
public CollisionRotationUndoStep(Bounds bounds, Quaternion startrot, WorldForm wf)
{
Bounds = bounds;
StartRotation = startrot;
EndRotation = bounds?.Orientation ?? Quaternion.Identity;
UpdateGraphics(wf);
}
private void Update(WorldForm wf, ref MapSelection sel, Quaternion q)
{
if (Bounds != null)
{
Bounds.Orientation = q;
}
if (Bounds != sel.CollisionBounds) wf.SelectCollisionBounds(Bounds);
wf.SetWidgetRotation(q);
UpdateGraphics(wf);
}
private void UpdateGraphics(WorldForm wf)
{
if (Bounds != null)
{
wf.UpdateCollisionBoundsGraphics(Bounds);
}
}
public override void Undo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, StartRotation);
}
public override void Redo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, EndRotation);
}
public override string ToString()
{
return "Collision " + (Bounds?.GetName() ?? "") + ": Rotation";
}
}
public class CollisionScaleUndoStep : UndoStep
{
public Bounds Bounds { get; set; }
public Vector3 StartScale { get; set; }
public Vector3 EndScale { get; set; }
public CollisionScaleUndoStep(Bounds bounds, Vector3 startsca, WorldForm wf)
{
Bounds = bounds;
StartScale = startsca;
EndScale = bounds?.Scale ?? Vector3.One;
UpdateGraphics(wf);
}
private void Update(WorldForm wf, ref MapSelection sel, Vector3 s)
{
if (Bounds != null)
{
Bounds.Scale = s;
}
if (Bounds != sel.CollisionBounds) wf.SelectCollisionBounds(Bounds);
wf.SetWidgetScale(s);
UpdateGraphics(wf);
}
private void UpdateGraphics(WorldForm wf)
{
if (Bounds != null)
{
wf.UpdateCollisionBoundsGraphics(Bounds);
}
}
public override void Undo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, StartScale);
}
public override void Redo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, EndScale);
}
public override string ToString()
{
return "Collision " + (Bounds?.GetName() ?? "") + ": Scale";
}
}
public class CollisionPolyPositionUndoStep : UndoStep
{
public BoundPolygon Polygon { get; set; }
public Vector3 StartPosition { get; set; }
public Vector3 EndPosition { get; set; }
public CollisionPolyPositionUndoStep(BoundPolygon poly, Vector3 startpos, WorldForm wf)
{
Polygon = poly;
StartPosition = startpos;
EndPosition = poly?.Position ?? Vector3.Zero;
UpdateGraphics(wf);
}
private void Update(WorldForm wf, ref MapSelection sel, Vector3 p)
{
if (Polygon != null)
{
Polygon.Position = p;
}
if (Polygon != sel.CollisionPoly) wf.SelectCollisionPoly(Polygon);
wf.SetWidgetPosition(p);
UpdateGraphics(wf);
}
private void UpdateGraphics(WorldForm wf)
{
if (Polygon?.Owner != null)
{
wf.UpdateCollisionBoundsGraphics(Polygon.Owner);
}
}
public override void Undo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, StartPosition);
}
public override void Redo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, EndPosition);
}
public override string ToString()
{
return "Collision Poly " + (Polygon?.Index.ToString() ?? "") + ": Position";
}
}
public class CollisionPolyRotationUndoStep : UndoStep
{
public BoundPolygon Polygon { get; set; }
public Quaternion StartRotation { get; set; }
public Quaternion EndRotation { get; set; }
public CollisionPolyRotationUndoStep(BoundPolygon poly, Quaternion startrot, WorldForm wf)
{
Polygon = poly;
StartRotation = startrot;
EndRotation = poly?.Orientation ?? Quaternion.Identity;
UpdateGraphics(wf);
}
private void Update(WorldForm wf, ref MapSelection sel, Quaternion q)
{
if (Polygon != null)
{
Polygon.Orientation = q;
}
if (Polygon != sel.CollisionPoly) wf.SelectCollisionPoly(Polygon);
wf.SetWidgetRotation(q);
UpdateGraphics(wf);
}
private void UpdateGraphics(WorldForm wf)
{
if (Polygon?.Owner != null)
{
wf.UpdateCollisionBoundsGraphics(Polygon.Owner);
}
}
public override void Undo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, StartRotation);
}
public override void Redo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, EndRotation);
}
public override string ToString()
{
return "Collision Poly " + (Polygon?.Index.ToString() ?? "") + ": Rotation";
}
}
public class CollisionPolyScaleUndoStep : UndoStep
{
public BoundPolygon Polygon { get; set; }
public Vector3 StartScale { get; set; }
public Vector3 EndScale { get; set; }
public CollisionPolyScaleUndoStep(BoundPolygon poly, Vector3 startsca, WorldForm wf)
{
Polygon = poly;
StartScale = startsca;
EndScale = poly?.Scale ?? Vector3.One;
UpdateGraphics(wf);
}
private void Update(WorldForm wf, ref MapSelection sel, Vector3 s)
{
if (Polygon != null)
{
Polygon.Scale = s;
}
if (Polygon != sel.CollisionPoly) wf.SelectCollisionPoly(Polygon);
wf.SetWidgetScale(s);
UpdateGraphics(wf);
}
private void UpdateGraphics(WorldForm wf)
{
if (Polygon?.Owner != null)
{
wf.UpdateCollisionBoundsGraphics(Polygon.Owner);
}
}
public override void Undo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, StartScale);
}
public override void Redo(WorldForm wf, ref MapSelection sel)
{
Update(wf, ref sel, EndScale);
}
public override string ToString()
{
return "Collision Poly " + (Polygon?.Index.ToString() ?? "") + ": Scale";
}
}
public class PathNodePositionUndoStep : UndoStep
{
public YndNode PathNode { get; set; }
@ -563,7 +883,6 @@ namespace CodeWalker.Project
return "NavPoint " + (Point?.ToString() ?? "") + ": Position";
}
}
public class NavPointRotationUndoStep : UndoStep
{
public YnvPoint Point { get; set; }
@ -781,7 +1100,6 @@ namespace CodeWalker.Project
public class ScenarioNodePositionUndoStep : UndoStep
{
public ScenarioNode ScenarioNode { get; set; }
@ -831,7 +1149,6 @@ namespace CodeWalker.Project
return ScenarioNode.ToString() + ": Position";
}
}
public class ScenarioNodeRotationUndoStep : UndoStep
{
public ScenarioNode ScenarioNode { get; set; }
@ -886,7 +1203,6 @@ namespace CodeWalker.Project
public class AudioPositionUndoStep : UndoStep
{
public AudioPlacement Audio { get; set; }
@ -923,7 +1239,6 @@ namespace CodeWalker.Project
return "Audio " + (Audio?.GetNameString() ?? "") + ": Position";
}
}
public class AudioRotationUndoStep : UndoStep
{
public AudioPlacement Audio { get; set; }

View File

@ -231,20 +231,18 @@ namespace CodeWalker.Rendering
public void Invalidate(BasePathData path)
public void Invalidate(Bounds bounds)
{
//lock (updateSyncRoot)
boundcomps.Invalidate(bounds);
}
public void Invalidate(BasePathData path)
{
pathbatches.Invalidate(path);
}
}
public void Invalidate(YmapGrassInstanceBatch batch)
{
//lock (updateSyncRoot)
{
instbatches.Invalidate(batch);
}
}
}

View File

@ -395,12 +395,14 @@ namespace CodeWalker.Rendering
public void Invalidate(Bounds bounds)
{
renderableCache.Invalidate(bounds);
}
public void Invalidate(BasePathData path)
{
//used to update path graphics.
renderableCache.Invalidate(path);
}
public void Invalidate(YmapGrassInstanceBatch batch)
{
renderableCache.Invalidate(batch);

View File

@ -540,6 +540,14 @@ namespace CodeWalker
{
res = true;
}
else if (CollisionPoly != null)
{
res = true;
}
else if (CollisionBounds != null)
{
res = true;
}
else if (NavPoint != null)
{
res = true;
@ -583,6 +591,14 @@ namespace CodeWalker
{
return CarGenerator.Position;
}
else if (CollisionPoly != null)
{
return CollisionPoly.Position;
}
else if (CollisionBounds != null)
{
return CollisionBounds.Center;
}
else if (NavPoly != null)
{
return NavPoly.Position;
@ -630,6 +646,14 @@ namespace CodeWalker
{
return CarGenerator.Orientation;
}
else if (CollisionPoly != null)
{
return Quaternion.Identity;
}
else if (CollisionBounds != null)
{
return Quaternion.Identity;
}
else if (NavPoly != null)
{
return Quaternion.Identity;
@ -677,6 +701,14 @@ namespace CodeWalker
{
return WidgetAxis.Z;
}
else if (CollisionPoly != null)
{
return WidgetAxis.XYZ;
}
else if (CollisionBounds != null)
{
return WidgetAxis.XYZ;
}
else if (NavPoly != null)
{
return WidgetAxis.XYZ;
@ -724,6 +756,14 @@ namespace CodeWalker
{
return new Vector3(CarGenerator.CCarGen.perpendicularLength);
}
else if (CollisionPoly != null)
{
return Vector3.One;
}
else if (CollisionBounds != null)
{
return Vector3.One;
}
else if (NavPoly != null)
{
return Vector3.One;
@ -784,14 +824,17 @@ namespace CodeWalker
{
PathNode.SetPosition(newpos);
}
else if (CollisionPoly != null)
{
CollisionPoly.Position = newpos;
}
else if (CollisionBounds != null)
{
CollisionBounds.Center = newpos;
}
else if (NavPoly != null)
{
NavPoly.SetPosition(newpos);
//if (projectForm != null)
//{
// projectForm.OnWorldNavPolyModified(NavPoly);
//}
}
else if (NavPoint != null)
{

View File

@ -1821,6 +1821,29 @@ namespace CodeWalker
return space.NodeGrid.GetYndNode(areaid, nodeid);
}
public void UpdateCollisionBoundsGraphics(Bounds b)
{
if (b is BoundBVH bvh)
{
bvh.BuildBVH();
}
else if (b is BoundComposite bc)
{
bc.BuildBVH();
}
var ib = b;
while (ib.Parent != null)
{
ib = ib.Parent;
}
//lock (Renderer.RenderSyncRoot)
{
Renderer.Invalidate(ib);
}
}
public void UpdateNavYnvGraphics(YnvFile ynv, bool fullupdate)
{
ynv.UpdateAllNodePositions();
@ -2256,9 +2279,6 @@ namespace CodeWalker
if (MouseRayCollision.Hit)
{
Matrix rmat = MouseRayCollision.HitBounds?.Transform ?? Matrix.Identity;
rmat.TranslationVector = Vector3.Zero;
var position = MouseRayCollision.HitEntity?.Position ?? Vector3.Zero;
var orientation = MouseRayCollision.HitEntity?.Orientation ?? Quaternion.Identity;
var scale = MouseRayCollision.HitEntity?.Scale ?? Vector3.One;
@ -2272,7 +2292,7 @@ namespace CodeWalker
CurMouseHit.HitDist = MouseRayCollision.HitDist;
CurMouseHit.CamRel = camrel + orientation.Multiply(trans);
CurMouseHit.BBOffset = trans;
CurMouseHit.BBOrientation = Quaternion.RotationMatrix(rmat);
CurMouseHit.BBOrientation = MouseRayCollision.HitBounds?.Transform.ToQuaternion() ?? Quaternion.Identity;
CurMouseHit.AABB = new BoundingBox(MouseRayCollision.HitBounds?.BoundingBoxMin ?? Vector3.Zero, MouseRayCollision.HitBounds?.BoundingBoxMax ?? Vector3.Zero);
}
}
@ -3511,6 +3531,40 @@ namespace CodeWalker
SelectItem(ms);
}
}
public void SelectCollisionBounds(Bounds b)
{
if (b == null)
{
SelectItem(null);
}
else
{
MapSelection ms = new MapSelection();
ms.CollisionBounds = b;
ms.AABB = new BoundingBox(b.BoundingBoxMin, b.BoundingBoxMax);
SelectItem(ms);
}
}
public void SelectCollisionPoly(BoundPolygon p)
{
if (p == null)
{
SelectItem(null);
}
else
{
MapSelection ms = new MapSelection();
ms.CollisionPoly = p;
//ms.AABB = new BoundingBox(p.BoundingBoxMin, p.BoundingBoxMax);
SelectItem(ms);
}
}
public void SelectNavPoly(YnvPoly poly)
{
if (poly == null)
@ -4744,6 +4798,8 @@ namespace CodeWalker
if (SelectedItem.MultipleSelection) return true;
if (SelectedItem.EntityDef != null) return true;
if (SelectedItem.CarGenerator != null) return true;
if (SelectedItem.CollisionBounds != null) return true;
if (SelectedItem.CollisionPoly != null) return true;
if (SelectedItem.PathNode != null) return true;
//if (SelectedItem.NavPoly != null) return true;
if (SelectedItem.NavPoint != null) return true;
@ -4768,6 +4824,8 @@ namespace CodeWalker
if (!CanMarkUndo()) return;
var ent = SelectedItem.EntityDef;
var cargen = SelectedItem.CarGenerator;
var bounds = SelectedItem.CollisionBounds;
var boundpoly = SelectedItem.CollisionPoly;
var pathnode = SelectedItem.PathNode;
var navpoly = SelectedItem.NavPoly;
var navpoint = SelectedItem.NavPoint;
@ -4815,6 +4873,24 @@ namespace CodeWalker
case WidgetMode.Scale: s = new CarGenScaleUndoStep(cargen, UndoStartScale); break;
}
}
else if (boundpoly != null)
{
switch (tw.Mode)
{
case WidgetMode.Position: s = new CollisionPolyPositionUndoStep(boundpoly, UndoStartPosition, this); break;
case WidgetMode.Rotation: s = new CollisionPolyRotationUndoStep(boundpoly, UndoStartRotation, this); break;
case WidgetMode.Scale: s = new CollisionPolyScaleUndoStep(boundpoly, UndoStartScale, this); break;
}
}
else if (bounds != null)
{
switch (tw.Mode)
{
case WidgetMode.Position: s = new CollisionPositionUndoStep(bounds, UndoStartPosition, this); break;
case WidgetMode.Rotation: s = new CollisionRotationUndoStep(bounds, UndoStartRotation, this); break;
case WidgetMode.Scale: s = new CollisionScaleUndoStep(bounds, UndoStartScale, this); break;
}
}
else if (pathnode != null)
{
switch (tw.Mode)