Collisions editing progress

This commit is contained in:
dexy 2020-01-10 02:12:16 +11:00
parent 9ba701bd2d
commit e4cc7550eb
3 changed files with 148 additions and 35 deletions

View File

@ -2267,6 +2267,7 @@ namespace CodeWalker.GameFiles
public abstract Vector3 Position { get; set; }
public abstract Quaternion Orientation { get; set; }
public abstract BoundVertexRef NearestVertex(Vector3 p);
public abstract void GatherVertices(Dictionary<BoundVertex, int> verts);
public abstract void Read(byte[] bytes, int offset);
public abstract void Write(BinaryWriter bw);
public virtual string Title
@ -2405,6 +2406,15 @@ namespace CodeWalker.GameFiles
if (d2 <= d3) return new BoundVertexRef(vertIndex2, d2);
return new BoundVertexRef(vertIndex3, d3);
}
public override void GatherVertices(Dictionary<BoundVertex, int> verts)
{
if (Owner != null)
{
verts[Owner.GetVertexObject(vertIndex1)] = vertIndex1;
verts[Owner.GetVertexObject(vertIndex2)] = vertIndex2;
verts[Owner.GetVertexObject(vertIndex3)] = vertIndex3;
}
}
public BoundPolygonTriangle()
{
@ -2488,6 +2498,13 @@ namespace CodeWalker.GameFiles
{
return new BoundVertexRef(sphereIndex, sphereRadius);
}
public override void GatherVertices(Dictionary<BoundVertex, int> verts)
{
if (Owner != null)
{
verts[Owner.GetVertexObject(sphereIndex)] = sphereIndex;
}
}
public BoundPolygonSphere()
{
@ -2617,6 +2634,14 @@ namespace CodeWalker.GameFiles
if (d1 <= d2) return new BoundVertexRef(capsuleIndex1, d1);
return new BoundVertexRef(capsuleIndex2, d2);
}
public override void GatherVertices(Dictionary<BoundVertex, int> verts)
{
if (Owner != null)
{
verts[Owner.GetVertexObject(capsuleIndex1)] = capsuleIndex1;
verts[Owner.GetVertexObject(capsuleIndex2)] = capsuleIndex2;
}
}
public BoundPolygonCapsule()
{
@ -2773,6 +2798,16 @@ namespace CodeWalker.GameFiles
if (d3 <= d4) return new BoundVertexRef(boxIndex3, d3);
return new BoundVertexRef(boxIndex4, d4);
}
public override void GatherVertices(Dictionary<BoundVertex, int> verts)
{
if (Owner != null)
{
verts[Owner.GetVertexObject(boxIndex1)] = boxIndex1;
verts[Owner.GetVertexObject(boxIndex2)] = boxIndex2;
verts[Owner.GetVertexObject(boxIndex3)] = boxIndex3;
verts[Owner.GetVertexObject(boxIndex4)] = boxIndex4;
}
}
public BoundPolygonBox()
{
@ -2904,6 +2939,14 @@ namespace CodeWalker.GameFiles
if (d1 <= d2) return new BoundVertexRef(cylinderIndex1, d1);
return new BoundVertexRef(cylinderIndex2, d2);
}
public override void GatherVertices(Dictionary<BoundVertex, int> verts)
{
if (Owner != null)
{
verts[Owner.GetVertexObject(cylinderIndex1)] = cylinderIndex1;
verts[Owner.GetVertexObject(cylinderIndex2)] = cylinderIndex2;
}
}
public BoundPolygonCylinder()
{

View File

@ -69,10 +69,11 @@ namespace CodeWalker
public MCScenarioChainingEdge ScenarioEdge { get; set; }
public AudioPlacement Audio { get; set; }
public MapSelection[] MultipleSelectionItems { get; set; }
public MapSelection[] MultipleSelectionItems { get; private set; }
public Vector3 MultipleSelectionCenter { get; set; }
public Quaternion MultipleSelectionRotation { get; set; }
public Vector3 MultipleSelectionScale { get; set; }
public BoundVertex[] GatheredCollisionVerts { get; private set; } //for collision polys, need to move all the individual vertices instead
public Vector3 BBOffset { get; set; }
public Quaternion BBOrientation { get; set; }
@ -210,6 +211,7 @@ namespace CodeWalker
MultipleSelectionCenter = Vector3.Zero;
MultipleSelectionRotation = Quaternion.Identity;
MultipleSelectionScale = Vector3.One;
GatheredCollisionVerts = null;
AABB = new BoundingBox();
GeometryIndex = 0;
CamRel = Vector3.Zero;
@ -760,6 +762,14 @@ namespace CodeWalker
{
get
{
if (MultipleSelectionItems != null)
{
for (int i = 0; i < MultipleSelectionItems.Length; i++)
{
if (MultipleSelectionItems[i].EntityDef != null) return true;
}
return false;
}
if (CollisionBounds != null)
{
return false;
@ -774,6 +784,39 @@ namespace CodeWalker
public void SetMultipleSelectionItems(MapSelection[] items)
{
if ((items != null) && (items.Length == 0)) items = null;
MultipleSelectionItems = items;
GatheredCollisionVerts = null;
var center = Vector3.Zero;
if (items != null)
{
Dictionary<BoundVertex, int> collVerts = null;
for (int i = 0; i < items.Length; i++)
{
center += items[i].WidgetPosition;
var collPoly = items[i].CollisionPoly;
if (collPoly != null)
{
if (collVerts == null) collVerts = new Dictionary<BoundVertex, int>();
collPoly.GatherVertices(collVerts);
}
}
if (collVerts != null)
{
GatheredCollisionVerts = collVerts.Keys.ToArray();
}
if (items.Length > 0)
{
center *= (1.0f / items.Length);
}
}
MultipleSelectionCenter = center;
}
public void SetPosition(Vector3 newpos, bool editPivot)
{
if (MultipleSelectionItems != null)
@ -787,8 +830,19 @@ namespace CodeWalker
if (dpos == Vector3.Zero) return; //nothing moved.. (probably due to snap)
for (int i = 0; i < MultipleSelectionItems.Length; i++)
{
var refpos = MultipleSelectionItems[i].WidgetPosition;
MultipleSelectionItems[i].SetPosition(refpos + dpos, false);
if (MultipleSelectionItems[i].CollisionPoly == null)//skip polys, they use gathered verts
{
var refpos = MultipleSelectionItems[i].WidgetPosition;
MultipleSelectionItems[i].SetPosition(refpos + dpos, false);
}
}
if (GatheredCollisionVerts != null)
{
for (int i = 0; i < GatheredCollisionVerts.Length; i++)
{
var refpos = GatheredCollisionVerts[i].Position;
GatheredCollisionVerts[i].Position = refpos + dpos;
}
}
MultipleSelectionCenter = newpos;
}
@ -864,13 +918,26 @@ namespace CodeWalker
var trans = newrot * orinv;
for (int i = 0; i < MultipleSelectionItems.Length; i++)
{
var refpos = MultipleSelectionItems[i].WidgetPosition;
var relpos = refpos - cen;
var newpos = trans.Multiply(relpos) + cen;
var refori = MultipleSelectionItems[i].WidgetRotation;
var newori = trans * refori;
MultipleSelectionItems[i].SetPosition(newpos, false);
MultipleSelectionItems[i].SetRotation(newori, false);
if (MultipleSelectionItems[i].CollisionPoly == null)//skip polys, they use gathered verts
{
var refpos = MultipleSelectionItems[i].WidgetPosition;
var relpos = refpos - cen;
var newpos = trans.Multiply(relpos) + cen;
var refori = MultipleSelectionItems[i].WidgetRotation;
var newori = trans * refori;
MultipleSelectionItems[i].SetPosition(newpos, false);
MultipleSelectionItems[i].SetRotation(newori, false);
}
}
if (GatheredCollisionVerts != null)
{
for (int i = 0; i < GatheredCollisionVerts.Length; i++)
{
var refpos = GatheredCollisionVerts[i].Position;
var relpos = refpos - cen;
var newpos = trans.Multiply(relpos) + cen;
GatheredCollisionVerts[i].Position = newpos;
}
}
MultipleSelectionRotation = newrot;
}
@ -934,11 +1001,24 @@ namespace CodeWalker
var rsca = newscale / MultipleSelectionScale;
for (int i = 0; i < MultipleSelectionItems.Length; i++)
{
var refpos = MultipleSelectionItems[i].WidgetPosition;
var relpos = refpos - cen;
var newpos = ori.Multiply(orinv.Multiply(relpos) * rsca) + cen;
MultipleSelectionItems[i].SetPosition(newpos, false);
MultipleSelectionItems[i].SetScale(newscale, false);
if (MultipleSelectionItems[i].CollisionPoly == null)//skip polys, they use gathered verts
{
var refpos = MultipleSelectionItems[i].WidgetPosition;
var relpos = refpos - cen;
var newpos = ori.Multiply(orinv.Multiply(relpos) * rsca) + cen;
MultipleSelectionItems[i].SetPosition(newpos, false);
MultipleSelectionItems[i].SetScale(newscale, false);
}
}
if (GatheredCollisionVerts != null)
{
for (int i = 0; i < GatheredCollisionVerts.Length; i++)
{
var refpos = GatheredCollisionVerts[i].Position;
var relpos = refpos - cen;
var newpos = ori.Multiply(orinv.Multiply(relpos) * rsca) + cen;
GatheredCollisionVerts[i].Position = newpos;
}
}
MultipleSelectionScale = newscale;
}
@ -952,6 +1032,10 @@ namespace CodeWalker
CarGenerator.SetScale(newscale);
AABB = new BoundingBox(CarGenerator.BBMin, CarGenerator.BBMax);
}
else if (CollisionVertex != null)
{
//do nothing, but stop any poly from being scaled also
}
else if (CollisionPoly != null)
{
CollisionPoly.Scale = newscale;

View File

@ -3277,11 +3277,11 @@ namespace CodeWalker
mhitv.Clear();
items.Clear();//this shouldn't really happen..
}
mhitv.MultipleSelectionItems = items.ToArray();
mhitv.SetMultipleSelectionItems(items.ToArray());
}
else
{
mhitv.MultipleSelectionItems = null;
mhitv.SetMultipleSelectionItems(null);
items.Add(mhitv);
}
change = true;
@ -3299,11 +3299,11 @@ namespace CodeWalker
{
if (SelectedItem.HasValue) //add the existing item to the selection list, if it's not empty
{
mhitv.MultipleSelectionItems = null;
SelectedItem.MultipleSelectionItems = null;
mhitv.SetMultipleSelectionItems(null);
SelectedItem.SetMultipleSelectionItems(null);
items.Add(SelectedItem);
items.Add(mhitv);
SelectedItem.MultipleSelectionItems = items.ToArray();
SelectedItem.SetMultipleSelectionItems(items.ToArray());
}
}
else //empty incoming value... do nothing?
@ -3322,21 +3322,8 @@ namespace CodeWalker
if (items.Count > 1)
{
//iterate the selected items, and calculate the selection position
var center = Vector3.Zero;
foreach (var item in items)
{
center += item.WidgetPosition;
}
if (items.Count > 0)
{
center *= (1.0f / items.Count);
}
mhitv.Clear();
mhitv.MultipleSelectionItems = items.ToArray();
mhitv.MultipleSelectionCenter = center;
mhitv.MultipleSelectionRotation = Quaternion.Identity;
mhitv.MultipleSelectionScale = Vector3.One;
mhitv.SetMultipleSelectionItems(items.ToArray());
}
}
else
@ -3344,7 +3331,6 @@ namespace CodeWalker
if (SelectedItem.MultipleSelectionItems != null)
{
change = true;
SelectedItem.MultipleSelectionItems = null;
SelectedItem.Clear();
}
}