Implemented water calming and wave quad selection

This commit is contained in:
PNWParksFan 2021-12-02 00:15:12 -08:00
parent e812674e69
commit 5cc94f049c
8 changed files with 188 additions and 63 deletions

View File

@ -34,7 +34,7 @@ namespace CodeWalker.World
for (int i = 0; i < waterquads.Count; i++)
{
var waterquad = new WaterQuad();
waterquad.Init(waterquads[i]);
waterquad.Init(waterquads[i], i);
WaterQuads.Add(waterquad);
}
@ -43,7 +43,7 @@ namespace CodeWalker.World
for (int i = 0; i < calmingquads.Count; i++)
{
var calmingquad = new WaterCalmingQuad();
calmingquad.Init(calmingquads[i]);
calmingquad.Init(calmingquads[i], i);
CalmingQuads.Add(calmingquad);
}
@ -52,7 +52,7 @@ namespace CodeWalker.World
for (int i = 0; i < wavequads.Count; i++)
{
var wavequad = new WaterWaveQuad();
wavequad.Init(wavequads[i]);
wavequad.Init(wavequads[i], i);
WaveQuads.Add(wavequad);
}
@ -61,48 +61,68 @@ namespace CodeWalker.World
public void GetVisibleQuads(Camera camera, List<WaterQuad> quads)
public List<T> GetVisibleQuads<T>(Camera camera, IEnumerable<T> allQuads) where T : BaseWaterQuad
{
if (!Inited) return;
List<T> quads = new List<T>();
if (!Inited) return quads;
var vf = camera.ViewFrustum;
for (int i = 0; i < WaterQuads.Count; i++)
foreach (var quad in allQuads)
{
var quad = WaterQuads[i];
Vector3 camrel = quad.BSCenter - camera.Position;
if (vf.ContainsSphereNoClipNoOpt(ref camrel, quad.BSRadius))
{
quads.Add(quad);
}
}
return quads;
}
}
public class WaterQuad
public abstract class BaseWaterQuad
{
public int xmlNodeIndex { get; set; }
public float minX { get; set; }
public float maxX { get; set; }
public float minY { get; set; }
public float maxY { get; set; }
public float? z { get; set; } = null;
public abstract void Init(XmlNode node, int index);
public void CalcBS()
{
BSCenter = new Vector3((minX + maxX) * 0.5f, (minY + maxY) * 0.5f, z ?? 0);
BSRadius = new Vector2(maxX - minX, maxY - minY).Length() * 0.5f;
}
public Vector3 BSCenter { get; private set; }
public float BSRadius { get; private set; }
public override string ToString()
{
return string.Format("[{0}] X=({1} : {2}), Y=({3} : {4})", xmlNodeIndex, minX, maxX, minY, maxY);
}
}
public class WaterQuad : BaseWaterQuad
{
public int Type { get; set; }
public bool IsInvisible { get; set; }
public bool HasLimitedDepth { get; set; }
public float z { get; set; }
public float a1 { get; set; }
public float a2 { get; set; }
public float a3 { get; set; }
public float a4 { get; set; }
public bool NoStencil { get; set; }
public Vector3 BSCenter;
public float BSRadius;
public void Init(XmlNode node)
public override void Init(XmlNode node, int index)
{
xmlNodeIndex = index;
minX = Xml.GetChildFloatAttribute(node, "minX", "value");
maxX = Xml.GetChildFloatAttribute(node, "maxX", "value");
minY = Xml.GetChildFloatAttribute(node, "minY", "value");
@ -133,29 +153,17 @@ namespace CodeWalker.World
<NoStencil value="false" />
*/
BSCenter = new Vector3((minX + maxX) * 0.5f, (minY + maxY) * 0.5f, z);
BSRadius = new Vector2(maxX - minX, maxY - minY).Length() * 0.5f;
CalcBS();
}
public override string ToString()
{
return string.Format("{0}, {1}, {2}", FloatUtil.ToString(minX), FloatUtil.ToString(minY), FloatUtil.ToString(z), FloatUtil.ToString(maxX), FloatUtil.ToString(maxY));
}
}
public class WaterCalmingQuad
public class WaterCalmingQuad : BaseWaterQuad
{
public float minX { get; set; }
public float maxX { get; set; }
public float minY { get; set; }
public float maxY { get; set; }
public float fDampening { get; set; }
public void Init(XmlNode node)
public override void Init(XmlNode node, int index)
{
xmlNodeIndex = index;
minX = Xml.GetChildFloatAttribute(node, "minX", "value");
maxX = Xml.GetChildFloatAttribute(node, "maxX", "value");
minY = Xml.GetChildFloatAttribute(node, "minY", "value");
@ -170,22 +178,22 @@ namespace CodeWalker.World
<fDampening value="0.05" />
*/
CalcBS();
}
}
public class WaterWaveQuad
public class WaterWaveQuad : BaseWaterQuad
{
public float minX { get; set; }
public float maxX { get; set; }
public float minY { get; set; }
public float maxY { get; set; }
public float Amplitude { get; set; }
public float XDirection { get; set; }
public float YDirection { get; set; }
public Quaternion WaveOrientation { get; set; }
public void Init(XmlNode node)
public override void Init(XmlNode node, int index)
{
xmlNodeIndex = index;
minX = Xml.GetChildFloatAttribute(node, "minX", "value");
maxX = Xml.GetChildFloatAttribute(node, "maxX", "value");
minY = Xml.GetChildFloatAttribute(node, "minY", "value");
@ -194,6 +202,9 @@ namespace CodeWalker.World
XDirection = Xml.GetChildFloatAttribute(node, "XDirection", "value");
YDirection = Xml.GetChildFloatAttribute(node, "YDirection", "value");
float angl = (float)Math.Atan2(YDirection, XDirection);
WaveOrientation = Quaternion.RotationYawPitchRoll(0.0f, 0.0f, angl);
/*
<minX value="1664" />
<maxX value="1988" />
@ -204,6 +215,7 @@ namespace CodeWalker.World
<YDirection value="-0.797584" />
*/
CalcBS();
}
}

View File

@ -7244,7 +7244,7 @@ namespace CodeWalker.Project
}
public void GetVisibleWaterQuads(Camera camera, List<WaterQuad> quads)
public void GetVisibleWaterQuads<T>(Camera camera, List<T> quads) where T : BaseWaterQuad
{
if (hidegtavmap)
{

View File

@ -1767,16 +1767,16 @@ namespace CodeWalker.Rendering
VertexCount = 4;
Vertices = new VertexTypePCT[4];
Vertices[0].Position = new Vector3(key.minX, key.minY, key.z);
Vertices[0].Position = new Vector3(key.minX, key.minY, key.z.Value);
Vertices[0].Texcoord = new Vector2(0.0f, 0.0f);
Vertices[0].Colour = (uint)new Color4(key.a1 / 255.0f).ToRgba();
Vertices[1].Position = new Vector3(key.maxX, key.minY, key.z);
Vertices[1].Position = new Vector3(key.maxX, key.minY, key.z.Value);
Vertices[1].Texcoord = new Vector2(sx, 0.0f);
Vertices[1].Colour = (uint)new Color4(key.a2 / 255.0f).ToRgba();
Vertices[2].Position = new Vector3(key.minX, key.maxY, key.z);
Vertices[2].Position = new Vector3(key.minX, key.maxY, key.z.Value);
Vertices[2].Texcoord = new Vector2(0.0f, sy);
Vertices[2].Colour = (uint)new Color4(key.a3 / 255.0f).ToRgba();
Vertices[3].Position = new Vector3(key.maxX, key.maxY, key.z);
Vertices[3].Position = new Vector3(key.maxX, key.maxY, key.z.Value);
Vertices[3].Texcoord = new Vector2(sx, sy);
Vertices[3].Colour = (uint)new Color4(key.a4 / 255.0f).ToRgba();

View File

@ -1242,6 +1242,8 @@ namespace CodeWalker.Rendering
{
case MapSelectionMode.NavMesh:
case MapSelectionMode.WaterQuad:
case MapSelectionMode.CalmingQuad:
case MapSelectionMode.WaveQuad:
case MapSelectionMode.MloInstance:
clip = false;
break;
@ -1326,6 +1328,8 @@ namespace CodeWalker.Rendering
switch (mode)
{
case MapSelectionMode.WaterQuad:
case MapSelectionMode.CalmingQuad:
case MapSelectionMode.WaveQuad:
case MapSelectionMode.MloInstance:
clip = false;
break;

View File

@ -36,6 +36,8 @@ namespace CodeWalker
Watermap = 17,
Audio = 18,
Occlusion = 19,
CalmingQuad = 20,
WaveQuad = 21,
}
@ -58,6 +60,8 @@ namespace CodeWalker
public YmapEntityDef MloEntityDef { get; set; }
public MCMloRoomDef MloRoomDef { get; set; }
public WaterQuad WaterQuad { get; set; }
public WaterCalmingQuad CalmingQuad { get; set; }
public WaterWaveQuad WaveQuad { get; set; }
public Bounds CollisionBounds { get; set; }
public BoundPolygon CollisionPoly { get; set; }
public BoundVertex CollisionVertex { get; set; }
@ -100,6 +104,8 @@ namespace CodeWalker
(CarGenerator != null) ||
(GrassBatch != null) ||
(WaterQuad != null) ||
(CalmingQuad != null) ||
(WaveQuad != null) ||
(CollisionBounds != null) ||
(CollisionPoly != null) ||
(CollisionVertex != null) ||
@ -139,6 +145,8 @@ namespace CodeWalker
|| (BoxOccluder != mhit.BoxOccluder)
|| (OccludeModelTri != mhit.OccludeModelTri)
|| (WaterQuad != mhit.WaterQuad)
|| (CalmingQuad != mhit.CalmingQuad)
|| (WaveQuad != mhit.WaveQuad)
|| (CollisionBounds != mhit.CollisionBounds)
|| (CollisionPoly != mhit.CollisionPoly)
|| (CollisionVertex != mhit.CollisionVertex)
@ -166,6 +174,8 @@ namespace CodeWalker
|| (BoxOccluder != null)
|| (OccludeModelTri != null)
|| (WaterQuad != null)
|| (CalmingQuad != null)
|| (WaveQuad != null)
|| (CollisionBounds != null)
|| (CollisionPoly != null)
|| (CollisionVertex != null)
@ -195,6 +205,8 @@ namespace CodeWalker
BoxOccluder = null;
OccludeModelTri = null;
WaterQuad = null;
CalmingQuad = null;
WaveQuad = null;
CollisionBounds = null;
CollisionPoly = null;
CollisionVertex = null;
@ -277,6 +289,14 @@ namespace CodeWalker
{
name = "WaterQuad " + WaterQuad.ToString();
}
else if (CalmingQuad != null)
{
name = "WaterCalmingQuad " + CalmingQuad.ToString();
}
else if (WaveQuad != null)
{
name = "WaterWaveQuad " + WaveQuad.ToString();
}
else if (NavPoly != null)
{
name = "NavPoly " + NavPoly.ToString();

View File

@ -129,6 +129,16 @@ namespace CodeWalker.World
SelectionEntityTabPage.Text = "Water Quad";
SelEntityPropertyGrid.SelectedObject = item.WaterQuad;
}
else if (item.CalmingQuad != null)
{
SelectionEntityTabPage.Text = "Water Calming Quad";
SelEntityPropertyGrid.SelectedObject = item.CalmingQuad;
}
else if (item.WaveQuad != null)
{
SelectionEntityTabPage.Text = "Water Wave Quad";
SelEntityPropertyGrid.SelectedObject = item.WaveQuad;
}
else if (item.NavPoly != null)
{
SelectionEntityTabPage.Text = "Nav Poly";

View File

@ -312,6 +312,8 @@ namespace CodeWalker
this.ToolbarPanel = new System.Windows.Forms.Panel();
this.SubtitleLabel = new System.Windows.Forms.Label();
this.SubtitleTimer = new System.Windows.Forms.Timer(this.components);
this.ToolbarSelectCalmingQuadButton = new System.Windows.Forms.ToolStripMenuItem();
this.ToolbarSelectWaveQuadButton = new System.Windows.Forms.ToolStripMenuItem();
this.StatusStrip.SuspendLayout();
this.ToolsPanel.SuspendLayout();
this.ToolsTabControl.SuspendLayout();
@ -1084,6 +1086,8 @@ namespace CodeWalker
"Car Generator",
"Grass",
"Water Quad",
"Water Calming Quad",
"Water Wave Quad",
"Collision",
"Nav Mesh",
"Path",
@ -3080,6 +3084,8 @@ namespace CodeWalker
this.ToolbarSelectCarGeneratorButton,
this.ToolbarSelectGrassButton,
this.ToolbarSelectWaterQuadButton,
this.ToolbarSelectCalmingQuadButton,
this.ToolbarSelectWaveQuadButton,
this.ToolbarSelectCollisionButton,
this.ToolbarSelectNavMeshButton,
this.ToolbarSelectPathButton,
@ -3604,6 +3610,20 @@ namespace CodeWalker
//
this.SubtitleTimer.Tick += new System.EventHandler(this.SubtitleTimer_Tick);
//
// ToolbarSelectCalmingQuadButton
//
this.ToolbarSelectCalmingQuadButton.Name = "ToolbarSelectCalmingQuadButton";
this.ToolbarSelectCalmingQuadButton.Size = new System.Drawing.Size(185, 22);
this.ToolbarSelectCalmingQuadButton.Text = "Water Calming Quad";
this.ToolbarSelectCalmingQuadButton.Click += new System.EventHandler(this.ToolbarSelectCalmingQuadButton_Click);
//
// ToolbarSelectWaveQuadButton
//
this.ToolbarSelectWaveQuadButton.Name = "ToolbarSelectWaveQuadButton";
this.ToolbarSelectWaveQuadButton.Size = new System.Drawing.Size(185, 22);
this.ToolbarSelectWaveQuadButton.Text = "Water Wave Quad";
this.ToolbarSelectWaveQuadButton.Click += new System.EventHandler(this.ToolbarSelectWaveQuadButton_Click);
//
// WorldForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -3975,5 +3995,7 @@ namespace CodeWalker
private System.Windows.Forms.ToolStripMenuItem ToolbarRotationSnapping90Button;
private System.Windows.Forms.ToolStripMenuItem ToolbarSnapGridSizeButton;
private System.Windows.Forms.CheckBox HDLightsCheckBox;
private System.Windows.Forms.ToolStripMenuItem ToolbarSelectCalmingQuadButton;
private System.Windows.Forms.ToolStripMenuItem ToolbarSelectWaveQuadButton;
}
}

View File

@ -127,7 +127,6 @@ namespace CodeWalker
List<YndFile> renderpathynds = new List<YndFile>();
bool renderwaterquads = true;
List<WaterQuad> renderwaterquadlist = new List<WaterQuad>();
bool rendertraintracks = false;
List<TrainTrack> rendertraintracklist = new List<TrainTrack>();
@ -710,6 +709,14 @@ namespace CodeWalker
{
RenderWorldWaterQuads();
}
if (SelectionMode == MapSelectionMode.WaveQuad)
{
RenderWorldWaterWaveQuads();
}
if (SelectionMode == MapSelectionMode.CalmingQuad)
{
RenderWorldWaterCalmingQuads();
}
if (rendercollisionmeshes || (SelectionMode == MapSelectionMode.Collision))
{
RenderWorldCollisionMeshes();
@ -804,19 +811,23 @@ namespace CodeWalker
private void RenderWorldWaterQuads()
{
renderwaterquadlist.Clear();
var quads = RenderWorldBaseWaterQuads(water.WaterQuads, MapSelectionMode.WaterQuad);
Renderer.RenderWaterQuads(quads);
}
water.GetVisibleQuads(camera, renderwaterquadlist);
private void RenderWorldWaterCalmingQuads() => RenderWorldBaseWaterQuads(water.CalmingQuads, MapSelectionMode.CalmingQuad);
if (ProjectForm != null)
{
ProjectForm.GetVisibleWaterQuads(camera, renderwaterquadlist);
}
private void RenderWorldWaterWaveQuads() => RenderWorldBaseWaterQuads(water.WaveQuads, MapSelectionMode.WaveQuad);
Renderer.RenderWaterQuads(renderwaterquadlist);
private List<T> RenderWorldBaseWaterQuads<T>(IEnumerable<T> quads, MapSelectionMode requiredMode) where T : BaseWaterQuad
{
List<T> renderwaterquadlist = water.GetVisibleQuads<T>(camera, quads);
UpdateMouseHits(renderwaterquadlist);
ProjectForm?.GetVisibleWaterQuads<T>(camera, renderwaterquadlist);
if(SelectionMode == requiredMode) UpdateMouseHits(renderwaterquadlist);
return renderwaterquadlist;
}
private void RenderWorldPaths()
@ -1379,6 +1390,15 @@ namespace CodeWalker
Renderer.RenderCar(cg.Position, cgori, cg._CCarGen.carModel, cg._CCarGen.popGroup);
}
}
if (selectionItem.WaveQuad != null)
{
var quad = selectionItem.WaveQuad;
Vector3 quadArrowPos = new Vector3(quad.minX + (quad.maxX - quad.minX) * 0.5f, quad.minY + (quad.maxY - quad.minY) * 0.5f, 5);
Quaternion waveOri = quad.WaveOrientation;
float arrowlen = quad.Amplitude * 50;
float arrowrad = arrowlen * 0.066f;
Renderer.RenderSelectionArrowOutline(quadArrowPos, Vector3.UnitX, Vector3.UnitY, waveOri, arrowlen, arrowrad, cgrn);
}
if (selectionItem.LodLight != null)
{
Renderer.RenderSelectionLodLight(selectionItem.LodLight);
@ -2900,35 +2920,42 @@ namespace CodeWalker
}
}
private void UpdateMouseHits(List<WaterQuad> waterquads)
private void UpdateMouseHits<T>(List<T> waterquads) where T : BaseWaterQuad
{
if (SelectionMode != MapSelectionMode.WaterQuad) return;
BoundingBox bbox = new BoundingBox();
Ray mray = new Ray();
mray.Position = camera.MouseRay.Position + camera.Position;
mray.Direction = camera.MouseRay.Direction;
float hitdist = float.MaxValue;
float hitdist;
foreach (var quad in waterquads)
foreach (T quad in waterquads)
{
MapBox mb = new MapBox();
mb.CamRelPos = -camera.Position;
mb.BBMin = new Vector3(quad.minX, quad.minY, quad.z);
mb.BBMax = new Vector3(quad.maxX, quad.maxY, quad.z);
mb.BBMin = new Vector3(quad.minX, quad.minY, quad.z ?? 0);
mb.BBMax = new Vector3(quad.maxX, quad.maxY, quad.z ?? 0);
mb.Orientation = Quaternion.Identity;
mb.Scale = Vector3.One;
Renderer.BoundingBoxes.Add(mb);
bbox.Minimum = mb.BBMin;
bbox.Maximum = mb.BBMax;
if (mray.Intersects(ref bbox, out hitdist) && (hitdist < CurMouseHit.HitDist) && (hitdist > 0))
if(mray.Intersects(ref bbox, out hitdist) && hitdist > 0 && hitdist <= CurMouseHit.HitDist)
{
CurMouseHit.WaterQuad = quad;
CurMouseHit.HitDist = hitdist;
CurMouseHit.CamRel = mb.CamRelPos;
CurMouseHit.AABB = bbox;
float curSize = CurMouseHit.AABB.Size.X * CurMouseHit.AABB.Size.Y;
float newSize = bbox.Size.X * bbox.Size.Y;
if ((curSize == 0) || (newSize < curSize))
{
CurMouseHit.HitDist = hitdist;
CurMouseHit.CamRel = mb.CamRelPos;
CurMouseHit.AABB = bbox;
CurMouseHit.WaterQuad = quad as WaterQuad;
CurMouseHit.WaveQuad = quad as WaterWaveQuad;
CurMouseHit.CalmingQuad = quad as WaterCalmingQuad;
}
}
}
}
@ -3722,6 +3749,16 @@ namespace CodeWalker
SelectionEntityTabPage.Text = "WaterQuad";
SelEntityPropertyGrid.SelectedObject = item.WaterQuad;
}
else if (item.CalmingQuad != null)
{
SelectionEntityTabPage.Text = "CalmingQuad";
SelEntityPropertyGrid.SelectedObject = item.CalmingQuad;
}
else if (item.WaveQuad != null)
{
SelectionEntityTabPage.Text = "WaveQuad";
SelEntityPropertyGrid.SelectedObject = item.WaveQuad;
}
else if (item.PathNode != null)
{
SelectionEntityTabPage.Text = "PathNode";
@ -5551,6 +5588,14 @@ namespace CodeWalker
mode = MapSelectionMode.WaterQuad;
ToolbarSelectWaterQuadButton.Checked = true;
break;
case "Water Calming Quad":
mode = MapSelectionMode.CalmingQuad;
ToolbarSelectCalmingQuadButton.Checked = true;
break;
case "Water Wave Quad":
mode = MapSelectionMode.WaveQuad;
ToolbarSelectWaveQuadButton.Checked = true;
break;
case "Collision":
mode = MapSelectionMode.Collision;
ToolbarSelectCollisionButton.Checked = true;
@ -7309,6 +7354,18 @@ namespace CodeWalker
SetMouseSelect(true);
}
private void ToolbarSelectCalmingQuadButton_Click(object sender, EventArgs e)
{
SetSelectionMode("Water Calming Quad");
SetMouseSelect(true);
}
private void ToolbarSelectWaveQuadButton_Click(object sender, EventArgs e)
{
SetSelectionMode("Water Wave Quad");
SetMouseSelect(true);
}
private void ToolbarSelectCollisionButton_Click(object sender, EventArgs e)
{
SetSelectionMode("Collision");