Collisions selection improvements

This commit is contained in:
dexy 2020-01-01 00:00:04 +11:00
parent 786b9e5199
commit 26c3c5edec
5 changed files with 320 additions and 194 deletions

View File

@ -727,6 +727,8 @@ namespace CodeWalker.GameFiles
}
if (p != null)
{
p.Owner = this;
p.Index = i;
p.Read(polygonData, offset);
}
Polygons[i] = p;
@ -737,6 +739,19 @@ namespace CodeWalker.GameFiles
{
return ((index < 0) || (index >= Vertices.Length)) ? Vector3.Zero : Vertices[index];
}
public Vector3 GetVertexPos(int index)
{
var v = GetVertex(index) + CenterGeom;
return Vector3.Transform(v, Transform).XYZ();
}
public void SetVertexPos(int index, Vector3 v)
{
if ((index >= 0) && (index < Vertices.Length))
{
var t = Vector3.Transform(v, TransformInv).XYZ() - CenterGeom;
Vertices[index] = t;
}
}
/// <summary>
@ -934,7 +949,6 @@ namespace CodeWalker.GameFiles
var spht = new BoundingSphere();
var sp = sph.Center;
var sr = sph.Radius;
var cg = CenterGeom;
Vector3 p1, p2, p3, p4, a1, a2, a3;
Vector3 n1 = Vector3.Zero;
@ -946,15 +960,15 @@ namespace CodeWalker.GameFiles
{
case BoundPolygonType.Triangle:
var ptri = polygon as BoundPolygonTriangle;
p1 = GetVertex(ptri.vertIndex1) + cg;
p2 = GetVertex(ptri.vertIndex2) + cg;
p3 = GetVertex(ptri.vertIndex3) + cg;
p1 = GetVertexPos(ptri.vertIndex1);
p2 = GetVertexPos(ptri.vertIndex2);
p3 = GetVertexPos(ptri.vertIndex3);
polyhit = sph.Intersects(ref p1, ref p2, ref p3);
if (polyhit) n1 = Vector3.Normalize(Vector3.Cross(p2 - p1, p3 - p1));
break;
case BoundPolygonType.Sphere:
var psph = polygon as BoundPolygonSphere;
tsph.Center = GetVertex(psph.sphereIndex) + cg;
tsph.Center = GetVertexPos(psph.sphereIndex);
tsph.Radius = psph.sphereRadius;
polyhit = sph.Intersects(ref tsph);
if (polyhit) n1 = Vector3.Normalize(sph.Center - tsph.Center);
@ -962,17 +976,17 @@ namespace CodeWalker.GameFiles
case BoundPolygonType.Capsule:
var pcap = polygon as BoundPolygonCapsule;
var tcap = new BoundingCapsule();
tcap.PointA = GetVertex(pcap.capsuleIndex1) + cg;
tcap.PointB = GetVertex(pcap.capsuleIndex2) + cg;
tcap.PointA = GetVertexPos(pcap.capsuleIndex1);
tcap.PointB = GetVertexPos(pcap.capsuleIndex2);
tcap.Radius = pcap.capsuleRadius;
polyhit = sph.Intersects(ref tcap, out n1);
break;
case BoundPolygonType.Box:
var pbox = polygon as BoundPolygonBox;
p1 = GetVertex(pbox.boxIndex1);// + cg; //corner
p2 = GetVertex(pbox.boxIndex2);// + cg;
p3 = GetVertex(pbox.boxIndex3);// + cg;
p4 = GetVertex(pbox.boxIndex4);// + cg;
p1 = GetVertexPos(pbox.boxIndex1);//corner
p2 = GetVertexPos(pbox.boxIndex2);
p3 = GetVertexPos(pbox.boxIndex3);
p4 = GetVertexPos(pbox.boxIndex4);
a1 = ((p3 + p4) - (p1 + p2)) * 0.5f;
a2 = p3 - (p1 + a1);
a3 = p4 - (p1 + a1);
@ -983,7 +997,7 @@ namespace CodeWalker.GameFiles
if ((bs.X < bs.Y) && (bs.X < bs.Z)) m1 = Vector3.Cross(m2, m3);
else if (bs.Y < bs.Z) m2 = Vector3.Cross(m3, m1);
else m3 = Vector3.Cross(m1, m2);
Vector3 tp = sp - (p1 + cg);
Vector3 tp = sp - (p1);//+cg
spht.Center = new Vector3(Vector3.Dot(tp, m1), Vector3.Dot(tp, m2), Vector3.Dot(tp, m3));
spht.Radius = sph.Radius;
box.Minimum = Vector3.Zero;
@ -1009,14 +1023,14 @@ namespace CodeWalker.GameFiles
case BoundPolygonType.Cylinder:
var pcyl = polygon as BoundPolygonCylinder;
//var tcyl = new BoundingCylinder();
//tcyl.PointA = GetVertex(pcyl.cylinderIndex1) + cg;
//tcyl.PointB = GetVertex(pcyl.cylinderIndex2) + cg;
//tcyl.PointA = GetVertexPos(pcyl.cylinderIndex1);
//tcyl.PointB = GetVertexPos(pcyl.cylinderIndex2);
//tcyl.Radius = pcyl.cylinderRadius;
//////polyhit = ray.Intersects(ref tcyl, out polyhittestdist, out n1);
//////polyhit = sph.Intersects(ref tcyl, out polyhittestdist, out n1);
////////TODO
var ttcap = new BoundingCapsule();//just use the capsule intersection for now...
ttcap.PointA = GetVertex(pcyl.cylinderIndex1) + cg;
ttcap.PointB = GetVertex(pcyl.cylinderIndex2) + cg;
ttcap.PointA = GetVertexPos(pcyl.cylinderIndex1);
ttcap.PointB = GetVertexPos(pcyl.cylinderIndex2);
ttcap.Radius = pcyl.cylinderRadius;
polyhit = sph.Intersects(ref ttcap, out n1);
break;
@ -1041,7 +1055,6 @@ namespace CodeWalker.GameFiles
var rayt = new Ray();
var rp = ray.Position;
var rd = ray.Direction;
var cg = CenterGeom;
Vector3 p1, p2, p3, p4, a1, a2, a3;
Vector3 n1 = Vector3.Zero;
@ -1054,15 +1067,15 @@ namespace CodeWalker.GameFiles
{
case BoundPolygonType.Triangle:
var ptri = polygon as BoundPolygonTriangle;
p1 = GetVertex(ptri.vertIndex1) + cg;
p2 = GetVertex(ptri.vertIndex2) + cg;
p3 = GetVertex(ptri.vertIndex3) + cg;
p1 = GetVertexPos(ptri.vertIndex1);
p2 = GetVertexPos(ptri.vertIndex2);
p3 = GetVertexPos(ptri.vertIndex3);
polyhit = ray.Intersects(ref p1, ref p2, ref p3, out polyhittestdist);
if (polyhit) n1 = Vector3.Normalize(Vector3.Cross(p2 - p1, p3 - p1));
break;
case BoundPolygonType.Sphere:
var psph = polygon as BoundPolygonSphere;
tsph.Center = GetVertex(psph.sphereIndex) + cg;
tsph.Center = GetVertexPos(psph.sphereIndex);
tsph.Radius = psph.sphereRadius;
polyhit = ray.Intersects(ref tsph, out polyhittestdist);
if (polyhit) n1 = Vector3.Normalize((ray.Position + ray.Direction * polyhittestdist) - tsph.Center);
@ -1070,8 +1083,8 @@ namespace CodeWalker.GameFiles
case BoundPolygonType.Capsule:
var pcap = polygon as BoundPolygonCapsule;
var tcap = new BoundingCapsule();
tcap.PointA = GetVertex(pcap.capsuleIndex1) + cg;
tcap.PointB = GetVertex(pcap.capsuleIndex2) + cg;
tcap.PointA = GetVertexPos(pcap.capsuleIndex1);
tcap.PointB = GetVertexPos(pcap.capsuleIndex2);
tcap.Radius = pcap.capsuleRadius;
polyhit = ray.Intersects(ref tcap, out polyhittestdist);
res.Position = (ray.Position + ray.Direction * polyhittestdist);
@ -1079,10 +1092,10 @@ namespace CodeWalker.GameFiles
break;
case BoundPolygonType.Box:
var pbox = polygon as BoundPolygonBox;
p1 = GetVertex(pbox.boxIndex1);// + cg; //corner
p2 = GetVertex(pbox.boxIndex2);// + cg;
p3 = GetVertex(pbox.boxIndex3);// + cg;
p4 = GetVertex(pbox.boxIndex4);// + cg;
p1 = GetVertexPos(pbox.boxIndex1);//corner
p2 = GetVertexPos(pbox.boxIndex2);
p3 = GetVertexPos(pbox.boxIndex3);
p4 = GetVertexPos(pbox.boxIndex4);
a1 = ((p3 + p4) - (p1 + p2)) * 0.5f;
a2 = p3 - (p1 + a1);
a3 = p4 - (p1 + a1);
@ -1093,7 +1106,7 @@ namespace CodeWalker.GameFiles
if ((bs.X < bs.Y) && (bs.X < bs.Z)) m1 = Vector3.Cross(m2, m3);
else if (bs.Y < bs.Z) m2 = Vector3.Cross(m3, m1);
else m3 = Vector3.Cross(m1, m2);
Vector3 tp = rp - (p1 + cg);
Vector3 tp = rp - (p1);//+cg
rayt.Position = new Vector3(Vector3.Dot(tp, m1), Vector3.Dot(tp, m2), Vector3.Dot(tp, m3));
rayt.Direction = new Vector3(Vector3.Dot(rd, m1), Vector3.Dot(rd, m2), Vector3.Dot(rd, m3));
box.Minimum = Vector3.Zero;
@ -1116,8 +1129,8 @@ namespace CodeWalker.GameFiles
case BoundPolygonType.Cylinder:
var pcyl = polygon as BoundPolygonCylinder;
var tcyl = new BoundingCylinder();
tcyl.PointA = GetVertex(pcyl.cylinderIndex1) + cg;
tcyl.PointB = GetVertex(pcyl.cylinderIndex2) + cg;
tcyl.PointA = GetVertexPos(pcyl.cylinderIndex1);
tcyl.PointB = GetVertexPos(pcyl.cylinderIndex2);
tcyl.Radius = pcyl.cylinderRadius;
polyhit = ray.Intersects(ref tcyl, out polyhittestdist, out n1);
break;
@ -1350,6 +1363,8 @@ namespace CodeWalker.GameFiles
[TC(typeof(EXP))] public abstract class BoundPolygon
{
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 void Read(byte[] bytes, int offset);
public abstract void Write(BinaryWriter bw);
public override string ToString()
@ -1374,6 +1389,21 @@ namespace CodeWalker.GameFiles
public bool vertFlag2 { get { return (triIndex2 & 0x8000) > 0; } }
public bool vertFlag3 { get { return (triIndex3 & 0x8000) > 0; } }
public Vector3 Vertex1
{
get { return (Owner != null) ? Owner.GetVertexPos(vertIndex1) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(vertIndex1, value); }
}
public Vector3 Vertex2
{
get { return (Owner != null) ? Owner.GetVertexPos(vertIndex2) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(vertIndex2, value); }
}
public Vector3 Vertex3
{
get { return (Owner != null) ? Owner.GetVertexPos(vertIndex3) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(vertIndex3, value); }
}
public BoundPolygonTriangle()
{
@ -1412,6 +1442,12 @@ namespace CodeWalker.GameFiles
public uint unused0 { get; set; }
public uint unused1 { get; set; }
public Vector3 Position
{
get { return (Owner != null) ? Owner.GetVertexPos(sphereIndex) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(sphereIndex, value); }
}
public BoundPolygonSphere()
{
Type = BoundPolygonType.Sphere;
@ -1446,6 +1482,17 @@ namespace CodeWalker.GameFiles
public ushort unused0 { get; set; }
public uint unused1 { get; set; }
public Vector3 Vertex1
{
get { return (Owner != null) ? Owner.GetVertexPos(capsuleIndex1) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(capsuleIndex1, value); }
}
public Vector3 Vertex2
{
get { return (Owner != null) ? Owner.GetVertexPos(capsuleIndex2) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(capsuleIndex2, value); }
}
public BoundPolygonCapsule()
{
Type = BoundPolygonType.Capsule;
@ -1482,6 +1529,27 @@ namespace CodeWalker.GameFiles
public short boxIndex4 { get; set; }
public uint unused0 { get; set; }
public Vector3 Vertex1
{
get { return (Owner != null) ? Owner.GetVertexPos(boxIndex1) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(boxIndex1, value); }
}
public Vector3 Vertex2
{
get { return (Owner != null) ? Owner.GetVertexPos(boxIndex2) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(boxIndex2, value); }
}
public Vector3 Vertex3
{
get { return (Owner != null) ? Owner.GetVertexPos(boxIndex3) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(boxIndex3, value); }
}
public Vector3 Vertex4
{
get { return (Owner != null) ? Owner.GetVertexPos(boxIndex4) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(boxIndex4, value); }
}
public BoundPolygonBox()
{
Type = BoundPolygonType.Box;
@ -1518,6 +1586,17 @@ namespace CodeWalker.GameFiles
public ushort unused0 { get; set; }
public uint unused1 { get; set; }
public Vector3 Vertex1
{
get { return (Owner != null) ? Owner.GetVertexPos(cylinderIndex1) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(cylinderIndex1, value); }
}
public Vector3 Vertex2
{
get { return (Owner != null) ? Owner.GetVertexPos(cylinderIndex2) : Vector3.Zero; }
set { if (Owner != null) Owner.SetVertexPos(cylinderIndex2, value); }
}
public BoundPolygonCylinder()
{
Type = BoundPolygonType.Cylinder;

View File

@ -715,14 +715,14 @@ namespace CodeWalker.Rendering
const int Reso = 36;
const float MaxDeg = 360f;
const float DegToRad = 0.0174533f;
const float Ang = MaxDeg / Reso;
const float Ang = DegToRad * MaxDeg / Reso;
var axis = Vector3.Cross(dir, up);
var c = new VertexTypePC[Reso];
for (var i = 0; i < Reso; i++)
{
var rDir = Quaternion.RotationAxis(dir, (i * Ang) * DegToRad).Multiply(axis);
var rDir = Quaternion.RotationAxis(dir, i * Ang).Multiply(axis);
c[i].Position = position + (rDir * radius);
c[i].Colour = col;
}
@ -737,6 +737,27 @@ namespace CodeWalker.Rendering
SelectionLineVerts.Add(new VertexTypePC { Colour = col, Position = position + dir * 2f});
}
public void RenderMouseHit(BoundsShaderMode mode, ref Vector3 camrel, ref Vector3 bbmin, ref Vector3 bbmax, ref Vector3 scale, ref Quaternion ori, float bsphrad)
{
if (mode == BoundsShaderMode.Box)
{
var wbox = new MapBox();
wbox.CamRelPos = camrel;
wbox.BBMin = bbmin;
wbox.BBMax = bbmax;
wbox.Scale = scale;
wbox.Orientation = ori;
WhiteBoxes.Add(wbox);
}
else if (mode == BoundsShaderMode.Sphere)
{
var wsph = new MapSphere();
wsph.CamRelPos = camrel;
wsph.Radius = bsphrad;
WhiteSpheres.Add(wsph);
}
}
public void RenderSelectionArrowOutline(Vector3 pos, Vector3 dir, Vector3 up, Quaternion ori, float len, float rad, uint colour)
{
Vector3 ax = Vector3.Cross(dir, up);
@ -812,6 +833,63 @@ namespace CodeWalker.Rendering
}
public void RenderSelectionCircle(Vector3 position, float radius, uint col)
{
const int Reso = 36;
const float MaxDeg = 360f;
const float DegToRad = 0.0174533f;
const float Ang = DegToRad * MaxDeg / Reso;
var dir = Vector3.Normalize(position - camera.Position);
var up = Vector3.Normalize(dir.GetPerpVec());
var axis = Vector3.Cross(dir, up);
var c = new VertexTypePC[Reso];
for (var i = 0; i < Reso; i++)
{
var rDir = Quaternion.RotationAxis(dir, i * Ang).Multiply(axis);
c[i].Position = position + (rDir * radius);
c[i].Colour = col;
}
for (var i = 0; i < c.Length; i++)
{
SelectionLineVerts.Add(c[i]);
SelectionLineVerts.Add(c[(i + 1) % c.Length]);
}
}
public void RenderSelectionBox(Vector3 p1, Vector3 p2, Vector3 a2, Vector3 a3, uint col)
{
VertexTypePC v = new VertexTypePC();
v.Colour = col;
var c1 = p1 - a2 - a3;
var c2 = p1 - a2 + a3;
var c3 = p1 + a2 + a3;
var c4 = p1 + a2 - a3;
var c5 = p2 - a2 - a3;
var c6 = p2 - a2 + a3;
var c7 = p2 + a2 + a3;
var c8 = p2 + a2 - a3;
v.Position = c1; SelectionLineVerts.Add(v);
v.Position = c2; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = c3; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = c4; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = c1; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = c5; SelectionLineVerts.Add(v);
v.Position = c2; SelectionLineVerts.Add(v);
v.Position = c6; SelectionLineVerts.Add(v);
v.Position = c3; SelectionLineVerts.Add(v);
v.Position = c7; SelectionLineVerts.Add(v);
v.Position = c4; SelectionLineVerts.Add(v);
v.Position = c8; SelectionLineVerts.Add(v);
v.Position = c5; SelectionLineVerts.Add(v);
v.Position = c6; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = c7; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = c8; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = c5; SelectionLineVerts.Add(v);
}
public void RenderSelectionNavPoly(YnvPoly poly)
{
////draw poly triangles
@ -915,6 +993,78 @@ namespace CodeWalker.Rendering
//}
}
public void RenderSelectionCollisionPolyOutline(BoundPolygon poly, uint colourval, YmapEntityDef entity)
{
var bgeom = poly?.Owner;
if (bgeom == null) return;
VertexTypePC v = new VertexTypePC();
v.Colour = colourval;
var ori = Quaternion.Identity;
var pos = Vector3.Zero;
var sca = Vector3.One;
if (entity != null)
{
ori = entity.Orientation;
pos = entity.Position;
sca = entity.Scale;
}
if (poly is BoundPolygonTriangle ptri)
{
var p1 = pos + (ori.Multiply(ptri.Vertex1) * sca);
var p2 = pos + (ori.Multiply(ptri.Vertex2) * sca);
var p3 = pos + (ori.Multiply(ptri.Vertex3) * sca);
v.Position = p1; SelectionLineVerts.Add(v);
v.Position = p2; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = p3; SelectionLineVerts.Add(v); SelectionLineVerts.Add(v);
v.Position = p1; SelectionLineVerts.Add(v);
}
else if (poly is BoundPolygonSphere psph)
{
var p1 = pos + (ori.Multiply(psph.Position) * sca);
RenderSelectionCircle(p1, psph.sphereRadius * 1.03f, colourval);//enlarge the circle to make it more visible..
}
else if (poly is BoundPolygonCapsule pcap)
{
var p1 = pos + (ori.Multiply(pcap.Vertex1) * sca);
var p2 = pos + (ori.Multiply(pcap.Vertex2) * sca);
var a1 = Vector3.Normalize(p2 - p1);
var a2 = Vector3.Normalize(a1.GetPerpVec());
var a3 = Vector3.Normalize(Vector3.Cross(a1, a2));
a1 *= pcap.capsuleRadius;
a2 *= pcap.capsuleRadius;
a3 *= pcap.capsuleRadius;
RenderSelectionBox(p1 - a1, p2 + a1, a2, a3, colourval);
}
else if (poly is BoundPolygonBox pbox)
{
var p1 = pos + (ori.Multiply(pbox.Vertex1) * sca);
var p2 = pos + (ori.Multiply(pbox.Vertex2) * sca);
var p3 = pos + (ori.Multiply(pbox.Vertex3) * sca);
var p4 = pos + (ori.Multiply(pbox.Vertex4) * sca);
var p5 = (p1 + p2) * 0.5f;
var p6 = (p3 + p4) * 0.5f;
var a1 = (p6 - p5);
var a2 = (p3 - (p1 + a1)) * 0.5f;
var a3 = (p4 - (p1 + a1)) * 0.5f;
RenderSelectionBox(p5, p6, a2, a3, colourval);
}
else if (poly is BoundPolygonCylinder pcyl)
{
var p1 = pos + (ori.Multiply(pcyl.Vertex1) * sca);
var p2 = pos + (ori.Multiply(pcyl.Vertex2) * sca);
var a1 = Vector3.Normalize(p2 - p1);
var a2 = Vector3.Normalize(a1.GetPerpVec());
var a3 = Vector3.Normalize(Vector3.Cross(a1, a2));
a2 *= pcyl.cylinderRadius;
a3 *= pcyl.cylinderRadius;
RenderSelectionBox(p1, p2, a2, a3, colourval);
}
}
public void RenderSelectionGeometry(MapSelectionMode mode)
{
@ -954,13 +1104,6 @@ namespace CodeWalker.Rendering
shader.SetShader(context);
shader.SetInputLayout(context, VertexType.Default);
shader.SetSceneVars(context, camera, null, globalLights);
shader.SetColourVars(context, new Vector4(colourwht, 1));
for (int i = 0; i < WhiteBoxes.Count; i++)
{
MapBox mb = WhiteBoxes[i];
shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale);
shader.DrawBox(context);
}
shader.SetColourVars(context, new Vector4(coloursel, 1));
for (int i = 0; i < SelectionBoxes.Count; i++)
{
@ -968,6 +1111,13 @@ namespace CodeWalker.Rendering
shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale);
shader.DrawBox(context);
}
shader.SetColourVars(context, new Vector4(colourwht, 1));
for (int i = 0; i < WhiteBoxes.Count; i++)
{
MapBox mb = WhiteBoxes[i];
shader.SetBoxVars(context, mb.CamRelPos, mb.BBMin, mb.BBMax, mb.Orientation, mb.Scale);
shader.DrawBox(context);
}
shader.UnbindResources(context);
}
@ -977,13 +1127,6 @@ namespace CodeWalker.Rendering
shader.SetShader(context);
shader.SetInputLayout(context, VertexType.Default);
shader.SetSceneVars(context, camera, null, globalLights);
shader.SetColourVars(context, new Vector4(colourwht, 1));
for (int i = 0; i < WhiteSpheres.Count; i++)
{
MapSphere ms = WhiteSpheres[i];
shader.SetSphereVars(context, ms.CamRelPos, ms.Radius);
shader.DrawSphere(context);
}
shader.SetColourVars(context, new Vector4(coloursel, 1));
for (int i = 0; i < SelectionSpheres.Count; i++)
{
@ -991,41 +1134,19 @@ namespace CodeWalker.Rendering
shader.SetSphereVars(context, ms.CamRelPos, ms.Radius);
shader.DrawSphere(context);
}
shader.SetColourVars(context, new Vector4(colourwht, 1));
for (int i = 0; i < WhiteSpheres.Count; i++)
{
MapSphere ms = WhiteSpheres[i];
shader.SetSphereVars(context, ms.CamRelPos, ms.Radius);
shader.DrawSphere(context);
}
shader.UnbindResources(context);
}
}
public void RenderMouseHit(BoundsShaderMode mode, bool clip, ref Vector3 camrel, ref Vector3 bbmin, ref Vector3 bbmax, ref Vector3 scale, ref Quaternion ori, float bsphrad)
{
Vector3 colour = new Vector3(1, 1, 1);
colour *= globalLights.HdrIntensity * 5.0f;
shaders.SetDepthStencilMode(context, clip ? DepthStencilMode.Enabled : DepthStencilMode.DisableAll);
//render moused object box.
var shader = shaders.Bounds;
shader.SetMode(mode);
shader.SetShader(context);
shader.SetInputLayout(context, VertexType.Default);
shader.SetSceneVars(context, camera, null, globalLights);
shader.SetColourVars(context, new Vector4(colour, 1)); //white box
if (mode == BoundsShaderMode.Box)
{
shader.SetBoxVars(context, camrel, bbmin, bbmax, ori, scale);
shader.DrawBox(context);
}
else if (mode == BoundsShaderMode.Sphere)
{
shader.SetSphereVars(context, camrel, bsphrad);
shader.DrawSphere(context);
}
shader.UnbindResources(context);
}
public void RenderBounds(MapSelectionMode mode)
{

View File

@ -187,6 +187,7 @@ namespace CodeWalker
public MCMloRoomDef MloRoomDef { get; set; }
public WaterQuad WaterQuad { get; set; }
public Bounds CollisionBounds { get; set; }
public BoundPolygon CollisionPoly { get; set; }
public YnvPoly NavPoly { get; set; }
public YnvPoint NavPoint { get; set; }
public YnvPortal NavPortal { get; set; }
@ -224,6 +225,7 @@ namespace CodeWalker
(GrassBatch != null) ||
(WaterQuad != null) ||
(CollisionBounds != null) ||
(CollisionPoly != null) ||
(NavPoly != null) ||
(NavPoint != null) ||
(NavPortal != null) ||
@ -261,6 +263,7 @@ namespace CodeWalker
|| (OccludeModel != mhit.OccludeModel)
|| (WaterQuad != mhit.WaterQuad)
|| (CollisionBounds != mhit.CollisionBounds)
|| (CollisionPoly != mhit.CollisionPoly)
|| (NavPoly != mhit.NavPoly)
|| (NavPoint != mhit.NavPoint)
|| (NavPortal != mhit.NavPortal)
@ -286,6 +289,7 @@ namespace CodeWalker
|| (OccludeModel != null)
|| (WaterQuad != null)
|| (CollisionBounds != null)
|| (CollisionPoly != null)
|| (NavPoly != null)
|| (NavPoint != null)
|| (NavPortal != null)
@ -313,6 +317,7 @@ namespace CodeWalker
OccludeModel = null;
WaterQuad = null;
CollisionBounds = null;
CollisionPoly = null;
NavPoly = null;
NavPoint = null;
NavPortal = null;
@ -366,6 +371,10 @@ namespace CodeWalker
{
name = "OccludeModel " + (OccludeModel.Ymap?.Name ?? "") + ": " + OccludeModel.Index.ToString();
}
else if (CollisionPoly != null)
{
name = "Poly " + CollisionPoly.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty);
}
else if (CollisionBounds != null)
{
name = CollisionBounds.GetName();
@ -432,6 +441,10 @@ namespace CodeWalker
{
name = Archetype.Hash.ToString();
}
else if (CollisionPoly != null)
{
name = "Poly " + CollisionPoly.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty);
}
else if (CollisionBounds != null)
{
name = CollisionBounds.GetName();

View File

@ -181,6 +181,11 @@ namespace CodeWalker
SelectionExtensionTabPage.Text = "Archetype Extension";
SelExtensionPropertyGrid.SelectedObject = item.ArchetypeExtension;
}
else if (item.CollisionPoly != null)
{
SelectionExtensionTabPage.Text = "Collision Polygon";
SelExtensionPropertyGrid.SelectedObject = item.CollisionPoly;
}
else if (item.CollisionBounds != null)
{
SelectionExtensionTabPage.Text = "Collision Bounds";

View File

@ -446,14 +446,14 @@ namespace CodeWalker
RenderSelection();
RenderMoused();
Renderer.RenderQueued();
Renderer.RenderBounds(SelectionMode);
Renderer.RenderSelectionGeometry(SelectionMode);
RenderMoused();
Renderer.RenderFinalPass();
RenderMarkers();
@ -1137,7 +1137,8 @@ namespace CodeWalker
change = change || (LastMouseHit.WaterQuad != PrevMouseHit.WaterQuad);
break;
case MapSelectionMode.Collision:
change = change || (LastMouseHit.CollisionBounds != PrevMouseHit.CollisionBounds);
change = change || (LastMouseHit.CollisionBounds != PrevMouseHit.CollisionBounds)
|| (LastMouseHit.CollisionPoly != PrevMouseHit.CollisionPoly);
break;
case MapSelectionMode.NavMesh:
change = change || (LastMouseHit.NavPoly != PrevMouseHit.NavPoly)
@ -1169,14 +1170,6 @@ namespace CodeWalker
{ return; }
if ((SelectionMode == MapSelectionMode.NavMesh) && (CurMouseHit.NavPoly != null))
{
return;//navmesh poly isn't needing a selection box..
}
bool clip = Renderer.renderboundsclip;
BoundsShaderMode mode = BoundsShaderMode.Box;
float bsphrad = CurMouseHit.BSphere.Radius;
Vector3 bbmin = CurMouseHit.AABB.Minimum;
@ -1215,11 +1208,9 @@ namespace CodeWalker
if (CurMouseHit.MloEntityDef != null)
{
scale = Vector3.One;
clip = false;
}
if (CurMouseHit.WaterQuad != null)
{
clip = false;
}
if (CurMouseHit.ScenarioNode != null)
{
@ -1238,6 +1229,11 @@ namespace CodeWalker
{
ori = CurMouseHit.NavPortal.Orientation;
}
if (CurMouseHit.NavPoly != null)
{
Renderer.RenderSelectionNavPolyOutline(CurMouseHit.NavPoly, 0xFFFFFFFF);
return;
}
if (CurMouseHit.Audio != null)
{
ori = CurMouseHit.Audio.Orientation;
@ -1246,13 +1242,17 @@ namespace CodeWalker
mode = BoundsShaderMode.Sphere;
}
}
if (CurMouseHit.CollisionPoly != null)
{
Renderer.RenderSelectionCollisionPolyOutline(CurMouseHit.CollisionPoly, 0xFFFFFFFF, CurMouseHit.EntityDef);
}
if (CurMouseHit.CollisionBounds != null)
{
ori = ori * CurMouseHit.BBOrientation;
}
Renderer.RenderMouseHit(mode, clip, ref camrel, ref bbmin, ref bbmax, ref scale, ref ori, bsphrad);
Renderer.RenderMouseHit(mode, ref camrel, ref bbmin, ref bbmax, ref scale, ref ori, bsphrad);
}
private void RenderSelection()
@ -1282,12 +1282,12 @@ namespace CodeWalker
if (ControlBrushEnabled && MouseRayCollision.Hit)
{
var arup = GetPerpVec(MouseRayCollision.Normal);
var arup = MouseRayCollision.Normal.GetPerpVec();
Renderer.RenderBrushRadiusOutline(MouseRayCollision.Position, MouseRayCollision.Normal, arup, ProjectForm.GetInstanceBrushRadius(), cgrn);
}
if (MouseRayCollisionVisible && MouseRayCollision.Hit)
{
var arup = GetPerpVec(MouseRayCollision.Normal);
var arup = MouseRayCollision.Normal.GetPerpVec();
Renderer.RenderSelectionArrowOutline(MouseRayCollision.Position, MouseRayCollision.Normal, arup, Quaternion.Identity, 1.0f, 0.05f, cgrn);
}
@ -1544,6 +1544,10 @@ namespace CodeWalker
Renderer.WhiteBoxes.Add(wbox);
}
}
if (selectionItem.CollisionPoly != null)
{
Renderer.RenderSelectionCollisionPolyOutline(selectionItem.CollisionPoly, cgrn, selectionItem.EntityDef);
}
if (selectionItem.CollisionBounds != null)
{
camrel += ori.Multiply(selectionItem.BBOffset);
@ -2060,27 +2064,6 @@ namespace CodeWalker
}
public static Vector3 GetPerpVec(Vector3 n)
{
//make a vector perpendicular to the given one
float nx = Math.Abs(n.X);
float ny = Math.Abs(n.Y);
float nz = Math.Abs(n.Z);
if ((nx < ny) && (nx < nz))
{
return Vector3.Cross(n, Vector3.Right);
}
else if (ny < nz)
{
return Vector3.Cross(n, Vector3.Up);
}
else
{
return Vector3.Cross(n, Vector3.ForwardLH);
}
}
private void SpawnTestEntity(bool cameraCenter = false)
{
if (!space.Inited) return;
@ -2264,10 +2247,6 @@ namespace CodeWalker
{
UpdateMouseHits(rd.Drawable, rd.Archetype, rd.Entity);
}
//foreach (var rb in Renderer.RenderedBoundComps)
//{
// UpdateMouseHits(rb.BoundComp, rb.Entity);
//}
}
private void UpdateMouseHitsFromSpace()
{
@ -2286,6 +2265,7 @@ namespace CodeWalker
var camrel = position - camera.Position;
var trans = MouseRayCollision.HitBounds?.Transform.TranslationVector ?? Vector3.Zero;
CurMouseHit.CollisionPoly = MouseRayCollision.HitPolygon;
CurMouseHit.CollisionBounds = MouseRayCollision.HitBounds;
CurMouseHit.EntityDef = MouseRayCollision.HitEntity;
CurMouseHit.Archetype = MouseRayCollision.HitEntity?.Archetype;
@ -2294,21 +2274,8 @@ namespace CodeWalker
CurMouseHit.BBOffset = trans;
CurMouseHit.BBOrientation = Quaternion.RotationMatrix(rmat);
CurMouseHit.AABB = new BoundingBox(MouseRayCollision.HitBounds?.BoundingBoxMin ?? Vector3.Zero, MouseRayCollision.HitBounds?.BoundingBoxMax ?? Vector3.Zero);
MapBox mb = new MapBox();
mb.CamRelPos = MouseRayCollision.Position - camera.Position;
mb.Orientation = Quaternion.Identity;
mb.Scale = Vector3.One;
mb.BBMin = new Vector3(-0.01f);
mb.BBMax = new Vector3(+0.01f);
Renderer.BoundingBoxes.Add(mb);
}
}
}
private void UpdateMouseHits(DrawableBase drawable, Archetype arche, YmapEntityDef entity)
{
@ -2614,65 +2581,6 @@ namespace CodeWalker
//{ }
}
private void UpdateMouseHits(RenderableBoundComposite rndbc, YmapEntityDef entity)
{
if (SelectionMode != MapSelectionMode.Collision) return;
var position = entity?.Position ?? Vector3.Zero;
var orientation = entity?.Orientation ?? Quaternion.Identity;
var scale = entity?.Scale ?? Vector3.One;
var camrel = position - camera.Position;
BoundingBox bbox = new BoundingBox();
Ray mray = new Ray();
mray.Position = camera.MouseRay.Position + camera.Position;
mray.Direction = camera.MouseRay.Direction;
float hitdist = float.MaxValue;
Ray mraytrn = new Ray();
MapBox mb = new MapBox();
mb.CamRelPos = camrel;// rbginst.Inst.CamRel;
mb.Orientation = orientation;
mb.Scale = scale;
foreach (var geom in rndbc.Geometries)
{
if (geom == null) continue;
mb.BBMin = geom.BBMin;
mb.BBMax = geom.BBMax;
mb.CamRelPos = camrel + orientation.Multiply(geom.BBOffset);
mb.Orientation = orientation * geom.BBOrientation;
var cent = mb.CamRelPos + (mb.BBMin + mb.BBMax) * 0.5f;
if (cent.Length() > Renderer.renderboundsmaxdist) continue;
Renderer.BoundingBoxes.Add(mb);
Quaternion orinv = Quaternion.Invert(mb.Orientation);
mraytrn.Position = orinv.Multiply(camera.MouseRay.Position - mb.CamRelPos);
mraytrn.Direction = orinv.Multiply(mray.Direction);
bbox.Minimum = mb.BBMin * scale;
bbox.Maximum = mb.BBMax * scale;
if (mraytrn.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0))
{
CurMouseHit.CollisionBounds = geom.Bound;
CurMouseHit.EntityDef = entity;
CurMouseHit.Archetype = entity?.Archetype;
CurMouseHit.HitDist = hitdist;
CurMouseHit.CamRel = mb.CamRelPos;
CurMouseHit.BBOffset = geom.BBOffset;
CurMouseHit.BBOrientation = geom.BBOrientation;
CurMouseHit.AABB = bbox;
}
}
}
private void UpdateMouseHits(YmapFile ymap)
{
@ -2954,11 +2862,6 @@ namespace CodeWalker
}
}
if ((CurMouseHit.NavPoly != null) && MouseSelectEnabled)
{
Renderer.RenderSelectionNavPolyOutline(CurMouseHit.NavPoly, 0xFFFFFFFF);
}
}
private void UpdateMouseHits(YnvFile ynv, NavMeshSector navsector, NavMeshSector rootsec, ref Ray mray)
{
@ -3955,6 +3858,11 @@ namespace CodeWalker
SelExtensionPropertyGrid.SelectedObject = item.ArchetypeExtension;
ShowSelectedExtensionTab(true);
}
else if (item.CollisionPoly != null)
{
SelExtensionPropertyGrid.SelectedObject = item.CollisionPoly;
ShowSelectedExtensionTab(true, "Coll");
}
else if (item.CollisionBounds != null)
{
SelExtensionPropertyGrid.SelectedObject = item.CollisionBounds;