diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs index 7c35958..8507876 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs @@ -405,6 +405,7 @@ namespace CodeWalker.GameFiles LODLights.coneInnerAngle = MetaTypes.GetByteArray(Meta, soa.coneInnerAngle); LODLights.coneOuterAngleOrCapExt = MetaTypes.GetByteArray(Meta, soa.coneOuterAngleOrCapExt); LODLights.coronaIntensity = MetaTypes.GetByteArray(Meta, soa.coronaIntensity); + LODLights.CalcBB(); } } @@ -875,6 +876,36 @@ namespace CodeWalker.GameFiles } + public void ConnectToParent(YmapFile pymap) + { + Parent = pymap; + if (RootEntities != null) //parent changed or first set, make sure to link entities hierarchy + { + for (int i = 0; i < RootEntities.Length; i++) + { + var ent = RootEntities[i]; + int pind = ent._CEntityDef.parentIndex; + if (pind >= 0) //connect root entities to parents if they have them.. + { + YmapEntityDef p = null; + if ((pymap != null) && (pymap.AllEntities != null)) + { + if ((pind < pymap.AllEntities.Length)) + { + p = pymap.AllEntities[pind]; + ent.Parent = p; + ent.ParentName = p._CEntityDef.archetypeName; + } + } + else + { }//should only happen if parent ymap not loaded yet... + } + } + } + } + + + public void AddEntity(YmapEntityDef ent) @@ -2261,6 +2292,15 @@ namespace CodeWalker.GameFiles } } + + public override string ToString() + { + if (Ymap != null) + { + return Ymap.ToString(); + } + return base.ToString(); + } } [TypeConverter(typeof(ExpandableObjectConverter))] @@ -2280,26 +2320,185 @@ namespace CodeWalker.GameFiles public Vector3 BBMax { get; set; } public YmapFile Ymap { get; set; } + public YmapLODLight[] Lights { get; set; } + + public PathBVH BVH { get; set; } + + public void Init(YmapDistantLODLights parent) + { + if (parent == null) return; + + var n = direction?.Length ?? 0; + n = Math.Min(n, parent.positions?.Length ?? 0); + n = Math.Min(n, parent.colours?.Length ?? 0); + n = Math.Min(n, falloff?.Length ?? 0); + n = Math.Min(n, falloffExponent?.Length ?? 0); + n = Math.Min(n, timeAndStateFlags?.Length ?? 0); + n = Math.Min(n, hash?.Length ?? 0); + n = Math.Min(n, coneInnerAngle?.Length ?? 0); + n = Math.Min(n, coneOuterAngleOrCapExt?.Length ?? 0); + n = Math.Min(n, coronaIntensity?.Length ?? 0); + if (n == 0) return; + + Lights = new YmapLODLight[n]; + for (int i = 0; i < n; i++) + { + var l = new YmapLODLight(); + l.Init(this, parent, i); + Lights[i] = l; + } + + BuildBVH(); + } + + public void BuildBVH() + { + BVH = new PathBVH(Lights, 10, 10); + } + + public void CalcBB() { - //if (positions != null) - //{ - // Vector3 min = new Vector3(float.MaxValue); - // Vector3 max = new Vector3(float.MinValue); - // for (int i = 0; i < positions.Length; i++) - // { - // var p = positions[i]; - // Vector3 pv = p.ToVector3(); - // min = Vector3.Min(min, pv); - // max = Vector3.Max(max, pv); - // } - // BBMin = min; - // BBMax = max; - //} + var positions = Ymap?.Parent?.DistantLODLights?.positions; + if (positions != null) + { + Vector3 min = new Vector3(float.MaxValue); + Vector3 max = new Vector3(float.MinValue); + for (int i = 0; i < positions.Length; i++) + { + var p = positions[i]; + Vector3 pv = p.ToVector3(); + min = Vector3.Min(min, pv); + max = Vector3.Max(max, pv); + } + BBMin = min; + BBMax = max; + } + else if (Ymap != null) + { + BBMin = Ymap._CMapData.entitiesExtentsMin; + BBMax = Ymap._CMapData.entitiesExtentsMax; + } + else + { } + } + public override string ToString() + { + if (Ymap != null) + { + return Ymap.ToString(); + } + return base.ToString(); } } + [TypeConverter(typeof(ExpandableObjectConverter))] + public class YmapLODLight : BasePathNode + { + public YmapLODLights LodLights { get; set; } + public YmapDistantLODLights DistLodLights { get; set; } + public int Index { get; set; } + public Color Colour { get; set; } + public Vector3 Position { get; set; } + public Vector3 Direction { get; set; } + public float Falloff { get; set; } + public float FalloffExponent { get; set; } + public FlagsUint TimeAndStateFlags { get; set; } + public uint Hash { get; set; } + public byte ConeInnerAngle { get; set; } + public byte ConeOuterAngleOrCapExt { get; set; } + public byte CoronaIntensity { get; set; } + + public Quaternion Orientation { get; set; } + public Vector3 Scale { get; set; } + + public Vector3 TangentX { get; set; } + public Vector3 TangentY { get; set; } + + public LightType Type + { + get + { + return (LightType)((TimeAndStateFlags >> 26) & 7); + } + } + + + public void Init(YmapLODLights l, YmapDistantLODLights p, int i) + { + LodLights = l; + DistLodLights = p; + Index = i; + + if (p.colours == null) return; + if ((i < 0) || (i >= p.colours.Length)) return; + + Colour = Color.FromBgra(p.colours[i]); + Position = p.positions[i].ToVector3(); + Direction = l.direction[i].ToVector3(); + Falloff = l.falloff[i]; + FalloffExponent = l.falloffExponent[i]; + TimeAndStateFlags = l.timeAndStateFlags[i]; + Hash = l.hash[i]; + ConeInnerAngle = l.coneInnerAngle[i]; + ConeOuterAngleOrCapExt = l.coneOuterAngleOrCapExt[i]; + CoronaIntensity = l.coronaIntensity[i]; + + switch (Type) + { + default: + case LightType.Point: + TangentX = Vector3.UnitX; + TangentY = Vector3.UnitY; + Orientation = Quaternion.Identity; + break; + case LightType.Spot: + TangentX = Vector3.Normalize(Direction.GetPerpVec()); + TangentY = Vector3.Normalize(Vector3.Cross(Direction, TangentX)); + break; + case LightType.Capsule: + TangentX = -Vector3.Normalize(Direction.GetPerpVec()); + TangentY = Vector3.Normalize(Vector3.Cross(Direction, TangentX)); + break; + } + + if (Type == LightType.Point) + { + Orientation = Quaternion.Identity; + } + else + { + var m = new Matrix(); + m.Row1 = new Vector4(TangentX, 0); + m.Row2 = new Vector4(TangentY, 0); + m.Row3 = new Vector4(Direction, 0); + Orientation = Quaternion.RotationMatrix(m); + } + + + Scale = Vector3.One; + } + + public void SetPosition(Vector3 pos) + { + Position = pos; + } + public void SetOrientation(Quaternion ori) + { + Orientation = ori; + } + public void SetScale(Vector3 scale) + { + Scale = scale; + } + + + public override string ToString() + { + return Index.ToString() + ": " + Position.ToString(); + } + } [TypeConverter(typeof(ExpandableObjectConverter))] public class YmapTimeCycleModifier diff --git a/CodeWalker/Rendering/Renderable.cs b/CodeWalker/Rendering/Renderable.cs index f107405..7ef9d94 100644 --- a/CodeWalker/Rendering/Renderable.cs +++ b/CodeWalker/Rendering/Renderable.cs @@ -1483,16 +1483,15 @@ namespace CodeWalker.Rendering if (ll == null) return; if (dll == null) return; - var n = dll.positions?.Length ?? 0; - n = Math.Min(n, dll.colours?.Length ?? 0); - n = Math.Min(n, ll.direction?.Length ?? 0); - n = Math.Min(n, ll.falloff?.Length ?? 0); - n = Math.Min(n, ll.falloffExponent?.Length ?? 0); - n = Math.Min(n, ll.timeAndStateFlags?.Length ?? 0); - n = Math.Min(n, ll.hash?.Length ?? 0); - n = Math.Min(n, ll.coneInnerAngle?.Length ?? 0); - n = Math.Min(n, ll.coneOuterAngleOrCapExt?.Length ?? 0); - n = Math.Min(n, ll.coronaIntensity?.Length ?? 0); + if (ll.Lights == null) + { + ll.Init(dll); + } + + if (ll.Lights == null) + { return; } + + var n = ll.Lights.Length; if (n <= 0) { return; } @@ -1504,18 +1503,19 @@ namespace CodeWalker.Rendering for (int i = 0; i < n; i++) { + var l = ll.Lights[i]; var light = new LODLight(); - light.Position = dll.positions[i].ToVector3(); - light.Colour = dll.colours[i]; - light.Direction = ll.direction[i].ToVector3(); - light.TimeAndStateFlags = ll.timeAndStateFlags[i]; - light.TangentX = new Vector4(Vector3.Normalize(light.Direction.GetPerpVec()), 0.0f); - light.TangentY = new Vector4(Vector3.Cross(light.Direction, light.TangentX.XYZ()), 0.0f); - light.Falloff = ll.falloff[i]; - light.FalloffExponent = Math.Max(ll.falloffExponent[i]*0.01f, 0.5f);//is this right? - light.InnerAngle = ll.coneInnerAngle[i] * 0.0087266462f; //pi/360 - light.OuterAngleOrCapExt = ll.coneOuterAngleOrCapExt[i] * 0.0087266462f; //pi/360 - var type = (LightType)((light.TimeAndStateFlags >> 26) & 7); + light.Position = l.Position; + light.Colour = (uint)l.Colour.ToBgra(); + light.Direction = l.Direction; + light.TimeAndStateFlags = l.TimeAndStateFlags; + light.TangentX = new Vector4(l.TangentX, 0.0f); + light.TangentY = new Vector4(l.TangentY, 0.0f); + light.Falloff = l.Falloff; + light.FalloffExponent = Math.Max(l.FalloffExponent*0.01f, 0.5f);//is this right? + light.InnerAngle = l.ConeInnerAngle * 0.0087266462f; //pi/360 + light.OuterAngleOrCapExt = l.ConeOuterAngleOrCapExt * 0.0087266462f; //pi/360 + var type = l.Type; switch (type) { case LightType.Point: @@ -1525,7 +1525,7 @@ namespace CodeWalker.Rendering spots.Add(light); break; case LightType.Capsule: - light.OuterAngleOrCapExt = ll.coneOuterAngleOrCapExt[i] * 0.25f; + light.OuterAngleOrCapExt = l.ConeOuterAngleOrCapExt * 0.25f; caps.Add(light); break; default: break;//just checking... diff --git a/CodeWalker/Rendering/Renderer.cs b/CodeWalker/Rendering/Renderer.cs index 878601e..b0f2d40 100644 --- a/CodeWalker/Rendering/Renderer.cs +++ b/CodeWalker/Rendering/Renderer.cs @@ -862,6 +862,109 @@ namespace CodeWalker.Rendering } } + public void RenderSelectionCircle(Vector3 position, Vector3 ax, Vector3 ay, float radius, uint col) + { + const int Reso = 36; + const float MaxDeg = 360f; + const float DegToRad = 0.0174533f; + const float Ang = DegToRad * MaxDeg / Reso; + + var c = new VertexTypePC[Reso]; + + for (var i = 0; i < Reso; i++) + { + var a = i * Ang; + var x = (float)Math.Sin(a); + var y = (float)Math.Cos(a); + c[i].Position = position + (ax * (x * radius)) + (ay * (y * 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 RenderSelectionArc(Vector3 position, Vector3 ax, Vector3 ay, float radius, float angle, uint col) + { + int res = (int)(angle * 0.1f); + const float DegToRad = 0.0174533f; + float ang = DegToRad * angle / res; + + var c = new VertexTypePC[res+1]; + + for (var i = 0; i <= res; i++) + { + var a = i * ang; + var x = (float)Math.Sin(a); + var y = (float)Math.Cos(a); + c[i].Position = position + (ax * (x * radius)) + (ay * (y * radius)); + c[i].Colour = col; + } + + for (var i = 1; i < c.Length; i++) + { + SelectionLineVerts.Add(c[i-1]); + SelectionLineVerts.Add(c[i]); + } + } + + public void RenderSelectionLine(Vector3 p1, Vector3 p2, uint col) + { + SelectionLineVerts.Add(new VertexTypePC() { Position = p1, Colour = col }); + SelectionLineVerts.Add(new VertexTypePC() { Position = p2, Colour = col }); + } + + public void RenderSelectionCone(Vector3 position, Vector3 ax, Vector3 ay, Vector3 dir, float radius, float height, uint col) + { + const int Reso = 36; + const float MaxDeg = 360f; + const float DegToRad = 0.0174533f; + const float Ang = DegToRad * MaxDeg / Reso; + + var c = new VertexTypePC[Reso]; + var p = new VertexTypePC() { Position = position, Colour = col }; + + var circpos = position + (dir * height); + + for (var i = 0; i < Reso; i++) + { + var a = i * Ang; + var x = (float)Math.Sin(a); + var y = (float)Math.Cos(a); + c[i].Position = circpos + (ax * (x * radius)) + (ay * (y * radius)); + c[i].Colour = col; + } + + for (var i = 0; i < c.Length; i++) + { + SelectionLineVerts.Add(c[i]); + SelectionLineVerts.Add(c[(i + 1) % c.Length]); + SelectionLineVerts.Add(c[i]); + SelectionLineVerts.Add(p); + } + } + + public void RenderSelectionCapsule(Vector3 position, Vector3 ax, Vector3 ay, Vector3 dir, float radius, float height, uint col) + { + var cp1 = position - (dir * height); + var cp2 = position + (dir * height); + var axr = ax * radius; + var ayr = ay * radius; + RenderSelectionCircle(cp1, ax, ay, radius, col); + RenderSelectionCircle(cp2, ax, ay, radius, col); + RenderSelectionArc(cp1, -dir, ax, radius, 180, col); + RenderSelectionArc(cp1, -dir, ay, radius, 180, col); + RenderSelectionArc(cp2, dir, ax, radius, 180, col); + RenderSelectionArc(cp2, dir, ay, radius, 180, col); + RenderSelectionLine(cp1 + axr, cp2 + axr, col); + RenderSelectionLine(cp1 + ayr, cp2 + ayr, col); + RenderSelectionLine(cp1 - axr, cp2 - axr, col); + RenderSelectionLine(cp1 - ayr, cp2 - ayr, col); + } + public void RenderSelectionBox(Vector3 p1, Vector3 p2, Vector3 a2, Vector3 a3, uint col) { VertexTypePC v = new VertexTypePC(); @@ -893,6 +996,42 @@ namespace CodeWalker.Rendering v.Position = c5; SelectionLineVerts.Add(v); } + public void RenderSelectionLodLight(YmapLODLight lodlight) + { + + var colblu = (uint)(new Color(0, 0, 255, 255).ToRgba()); + var colwht = (uint)(new Color(255, 255, 255, 255).ToRgba()); + + var pos = lodlight.Position; + var dir = lodlight.Direction; + var tx = lodlight.TangentX; + var ty = lodlight.TangentY; + var extent = lodlight.Falloff; + var innerAngle = lodlight.ConeInnerAngle * 0.0087266462f; //pi/360 + var outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.0087266462f; //pi/360 + var type = lodlight.Type; + switch (type) + { + case LightType.Point: + RenderSelectionCircle(pos, Vector3.UnitX, Vector3.UnitZ, extent, colwht); + RenderSelectionCircle(pos, Vector3.UnitX, Vector3.UnitY, extent, colwht); + RenderSelectionCircle(pos, Vector3.UnitY, Vector3.UnitZ, extent, colwht); + break; + case LightType.Spot: + float coneouterrad = extent * (float)Math.Tan(outerAngle); + float coneinnerrad = extent * (float)Math.Tan(innerAngle); + RenderSelectionCone(pos, tx, ty, dir, coneouterrad, extent, colblu); + RenderSelectionCone(pos, tx, ty, dir, coneinnerrad, extent, colwht); + break; + case LightType.Capsule: + outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.25f; + RenderSelectionCapsule(pos, tx, ty, dir, extent, outerAngle, colwht); + break; + } + + + } + public void RenderSelectionNavPoly(YnvPoly poly) { ////draw poly triangles @@ -3685,38 +3824,14 @@ namespace CodeWalker.Rendering foreach (var kvp in ymaps) { var ymap = kvp.Value; - var pymap = ymap.Parent; if (ymap._CMapData.parent != 0) //ensure parent references on ymaps { - ymaps.TryGetValue(ymap._CMapData.parent, out pymap); + ymaps.TryGetValue(ymap._CMapData.parent, out YmapFile pymap); if (pymap == null) //skip adding ymaps until parents are available { continue; } if (ymap.Parent != pymap) { - ymap.Parent = pymap; - if (ymap.RootEntities != null) //parent changed or first set, make sure to link entities hierarchy - { - for (int i = 0; i < ymap.RootEntities.Length; i++) - { - var ent = ymap.RootEntities[i]; - int pind = ent._CEntityDef.parentIndex; - if (pind >= 0) //connect root entities to parents if they have them.. - { - YmapEntityDef p = null; - if ((pymap != null) && (pymap.AllEntities != null)) - { - if ((pind < pymap.AllEntities.Length)) - { - p = pymap.AllEntities[pind]; - ent.Parent = p; - ent.ParentName = p._CEntityDef.archetypeName; - } - } - else - { }//should only happen if parent ymap not loaded yet... - } - } - } + ymap.ConnectToParent(pymap); } } } diff --git a/CodeWalker/World/MapSelection.cs b/CodeWalker/World/MapSelection.cs index cad95af..4f880ae 100644 --- a/CodeWalker/World/MapSelection.cs +++ b/CodeWalker/World/MapSelection.cs @@ -28,7 +28,7 @@ namespace CodeWalker NavMesh = 9, Path = 10, TrainTrack = 11, - DistantLodLights = 12, + LodLights = 12, MloInstance = 13, Scenario = 14, PopZone = 15, @@ -52,7 +52,7 @@ namespace CodeWalker public YmapTimeCycleModifier TimeCycleModifier { get; set; } public YmapCarGen CarGenerator { get; set; } public YmapGrassInstanceBatch GrassBatch { get; set; } - public YmapDistantLODLights DistantLodLights { get; set; } + public YmapLODLight LodLight { get; set; } public YmapBoxOccluder BoxOccluder { get; set; } public YmapOccludeModel OccludeModel { get; set; } public YmapEntityDef MloEntityDef { get; set; } @@ -108,7 +108,7 @@ namespace CodeWalker (NavPortal != null) || (PathNode != null) || (TrainTrackNode != null) || - (DistantLodLights != null) || + (LodLight != null) || (BoxOccluder != null) || (OccludeModel != null) || (MloEntityDef != null) || @@ -134,7 +134,7 @@ namespace CodeWalker || (EntityExtension != mhit.EntityExtension) || (CarGenerator != mhit.CarGenerator) || (MloEntityDef != mhit.MloEntityDef) - || (DistantLodLights != mhit.DistantLodLights) + || (LodLight != mhit.LodLight) || (GrassBatch != mhit.GrassBatch) || (BoxOccluder != mhit.BoxOccluder) || (OccludeModel != mhit.OccludeModel) @@ -161,7 +161,7 @@ namespace CodeWalker || (EntityExtension != null) || (CarGenerator != null) || (MloEntityDef != null) - || (DistantLodLights != null) + || (LodLight != null) || (GrassBatch != null) || (BoxOccluder != null) || (OccludeModel != null) @@ -204,7 +204,7 @@ namespace CodeWalker PathNode = null; PathLink = null; TrainTrackNode = null; - DistantLodLights = null; + LodLight = null; MloEntityDef = null; ScenarioNode = null; ScenarioEdge = null; @@ -261,9 +261,9 @@ namespace CodeWalker { name = (GrassBatch.Ymap?.Name ?? "") + ": " + GrassBatch.Archetype?.Name ?? ""; } - else if (DistantLodLights != null) + else if (LodLight != null) { - name = DistantLodLights.Ymap?.Name ?? ""; + name = (LodLight.LodLights?.Ymap?.Name ?? "") + ": " + LodLight.Index.ToString(); } else if (BoxOccluder != null) { @@ -484,6 +484,10 @@ namespace CodeWalker { res = true; } + else if (LodLight != null) + { + res = true; + } else if (NavPoly != null) { res = true; @@ -558,6 +562,10 @@ namespace CodeWalker { return CarGenerator.Position; } + else if (LodLight != null) + { + return LodLight.Position; + } else if (NavPoly != null) { return NavPoly.Position; @@ -620,6 +628,10 @@ namespace CodeWalker { return CarGenerator.Orientation; } + else if (LodLight != null) + { + return LodLight.Orientation; + } else if (NavPoly != null) { return Quaternion.Identity; @@ -679,6 +691,10 @@ namespace CodeWalker { return WidgetAxis.Z; } + else if (LodLight != null) + { + return WidgetAxis.XYZ; + } else if (NavPoly != null) { return WidgetAxis.XYZ; @@ -738,6 +754,10 @@ namespace CodeWalker { return new Vector3(CarGenerator.CCarGen.perpendicularLength); } + else if (LodLight != null) + { + return LodLight.Scale; + } else if (NavPoly != null) { return Vector3.One; @@ -810,6 +830,7 @@ namespace CodeWalker else if (CollisionBounds != null) return true; else if (EntityDef != null) return true; else if (CarGenerator != null) return true; + else if (LodLight != null) return true; else if (PathNode != null) return true; else if (NavPoly != null) return true; else if (NavPoint != null) return true; @@ -927,6 +948,10 @@ namespace CodeWalker { CarGenerator.SetPosition(newpos); } + else if (LodLight != null) + { + LodLight.SetPosition(newpos); + } else if (PathNode != null) { PathNode.SetPosition(newpos); @@ -1035,6 +1060,10 @@ namespace CodeWalker { CarGenerator.SetOrientation(newrot); } + else if (LodLight != null) + { + LodLight.SetOrientation(newrot); + } else if (ScenarioNode != null) { ScenarioNode.SetOrientation(newrot); @@ -1122,6 +1151,10 @@ namespace CodeWalker CarGenerator.SetScale(newscale); AABB = new BoundingBox(CarGenerator.BBMin, CarGenerator.BBMax); } + else if (LodLight != null) + { + LodLight.SetScale(newscale); + } } @@ -1278,6 +1311,7 @@ namespace CodeWalker else if (CollisionBounds != null) return CollisionBounds; else if (EntityDef != null) return EntityDef; else if (CarGenerator != null) return CarGenerator; + else if (LodLight != null) return LodLight; else if (PathNode != null) return PathNode; else if (NavPoly != null) return NavPoly; else if (NavPoint != null) return NavPoint; @@ -1317,6 +1351,11 @@ namespace CodeWalker ms.CarGenerator = cargen; ms.AABB = new BoundingBox(cargen.BBMin, cargen.BBMax); } + else if (o is YmapLODLight lodlight) + { + ms.LodLight = lodlight; + ms.AABB = new BoundingBox(new Vector3(-nrad), new Vector3(nrad)); + } else if (o is YmapGrassInstanceBatch batch) { ms.GrassBatch = batch; diff --git a/CodeWalker/World/WorldInfoForm.Designer.cs b/CodeWalker/World/WorldInfoForm.Designer.cs index 569691d..cf5f7b6 100644 --- a/CodeWalker/World/WorldInfoForm.Designer.cs +++ b/CodeWalker/World/WorldInfoForm.Designer.cs @@ -542,7 +542,7 @@ namespace CodeWalker.World "Nav Mesh", "Path", "Train Track", - "Distant Lod Lights", + "Lod Lights", "Mlo Instance", "Scenario", "Audio", diff --git a/CodeWalker/World/WorldInfoForm.cs b/CodeWalker/World/WorldInfoForm.cs index bf31491..48b4450 100644 --- a/CodeWalker/World/WorldInfoForm.cs +++ b/CodeWalker/World/WorldInfoForm.cs @@ -102,10 +102,10 @@ namespace CodeWalker.World SelectionEntityTabPage.Text = "Car Generator"; SelEntityPropertyGrid.SelectedObject = item.CarGenerator; } - else if (item.DistantLodLights != null) + else if (item.LodLight!= null) { - SelectionEntityTabPage.Text = "Distant LOD Lights"; - SelEntityPropertyGrid.SelectedObject = item.DistantLodLights; + SelectionEntityTabPage.Text = "LOD Light"; + SelEntityPropertyGrid.SelectedObject = item.LodLight; } else if (item.GrassBatch != null) { diff --git a/CodeWalker/WorldForm.Designer.cs b/CodeWalker/WorldForm.Designer.cs index d069576..e0e812e 100644 --- a/CodeWalker/WorldForm.Designer.cs +++ b/CodeWalker/WorldForm.Designer.cs @@ -264,7 +264,7 @@ namespace CodeWalker this.ToolbarSelectNavMeshButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolbarSelectPathButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolbarSelectTrainTrackButton = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarSelectDistantLodLightsButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarSelectLodLightsButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolbarSelectMloInstanceButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolbarSelectScenarioButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolbarSelectAudioButton = new System.Windows.Forms.ToolStripMenuItem(); @@ -280,6 +280,16 @@ namespace CodeWalker this.ToolbarSnapToGroundButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolbarSnapToGridButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolbarSnapToGroundGridButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarSnapGridSizeButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnappingButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnappingOffButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnapping1Button = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnapping2Button = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnapping5Button = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnapping10Button = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnapping45Button = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnapping90Button = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarRotationSnappingCustomButton = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.ToolbarUndoButton = new System.Windows.Forms.ToolStripSplitButton(); this.ToolbarUndoListButton = new System.Windows.Forms.ToolStripMenuItem(); @@ -302,16 +312,6 @@ 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.ToolbarRotationSnappingButton = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnappingOffButton = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnapping1Button = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnapping2Button = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnapping5Button = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnapping10Button = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnappingCustomButton = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnapping45Button = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarRotationSnapping90Button = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolbarSnapGridSizeButton = new System.Windows.Forms.ToolStripMenuItem(); this.StatusStrip.SuspendLayout(); this.ToolsPanel.SuspendLayout(); this.ToolsTabControl.SuspendLayout(); @@ -1088,7 +1088,7 @@ namespace CodeWalker "Nav Mesh", "Path", "Train Track", - "Distant Lod Lights", + "Lod Lights", "Mlo Instance", "Scenario", "Audio", @@ -2884,7 +2884,7 @@ namespace CodeWalker this.ToolbarCameraModeButton}); this.Toolbar.Location = new System.Drawing.Point(1, 0); this.Toolbar.Name = "Toolbar"; - this.Toolbar.Size = new System.Drawing.Size(585, 25); + this.Toolbar.Size = new System.Drawing.Size(554, 25); this.Toolbar.TabIndex = 6; this.Toolbar.Text = "toolStrip1"; // @@ -3070,7 +3070,7 @@ namespace CodeWalker this.ToolbarSelectNavMeshButton, this.ToolbarSelectPathButton, this.ToolbarSelectTrainTrackButton, - this.ToolbarSelectDistantLodLightsButton, + this.ToolbarSelectLodLightsButton, this.ToolbarSelectMloInstanceButton, this.ToolbarSelectScenarioButton, this.ToolbarSelectAudioButton, @@ -3162,12 +3162,12 @@ namespace CodeWalker this.ToolbarSelectTrainTrackButton.Text = "Train Track"; this.ToolbarSelectTrainTrackButton.Click += new System.EventHandler(this.ToolbarSelectTrainTrackButton_Click); // - // ToolbarSelectDistantLodLightsButton + // ToolbarSelectLodLightsButton // - this.ToolbarSelectDistantLodLightsButton.Name = "ToolbarSelectDistantLodLightsButton"; - this.ToolbarSelectDistantLodLightsButton.Size = new System.Drawing.Size(182, 22); - this.ToolbarSelectDistantLodLightsButton.Text = "Distant Lod Lights"; - this.ToolbarSelectDistantLodLightsButton.Click += new System.EventHandler(this.ToolbarSelectDistantLodLightsButton_Click); + this.ToolbarSelectLodLightsButton.Name = "ToolbarSelectLodLightsButton"; + this.ToolbarSelectLodLightsButton.Size = new System.Drawing.Size(182, 22); + this.ToolbarSelectLodLightsButton.Text = "Lod Lights"; + this.ToolbarSelectLodLightsButton.Click += new System.EventHandler(this.ToolbarSelectLodLightsButton_Click); // // ToolbarSelectMloInstanceButton // @@ -3254,7 +3254,7 @@ namespace CodeWalker this.ToolbarObjectSpaceButton.CheckState = System.Windows.Forms.CheckState.Checked; this.ToolbarObjectSpaceButton.Image = ((System.Drawing.Image)(resources.GetObject("ToolbarObjectSpaceButton.Image"))); this.ToolbarObjectSpaceButton.Name = "ToolbarObjectSpaceButton"; - this.ToolbarObjectSpaceButton.Size = new System.Drawing.Size(180, 22); + this.ToolbarObjectSpaceButton.Size = new System.Drawing.Size(142, 22); this.ToolbarObjectSpaceButton.Text = "Object space"; this.ToolbarObjectSpaceButton.Click += new System.EventHandler(this.ToolbarObjectSpaceButton_Click); // @@ -3262,7 +3262,7 @@ namespace CodeWalker // this.ToolbarWorldSpaceButton.Image = ((System.Drawing.Image)(resources.GetObject("ToolbarWorldSpaceButton.Image"))); this.ToolbarWorldSpaceButton.Name = "ToolbarWorldSpaceButton"; - this.ToolbarWorldSpaceButton.Size = new System.Drawing.Size(180, 22); + this.ToolbarWorldSpaceButton.Size = new System.Drawing.Size(142, 22); this.ToolbarWorldSpaceButton.Text = "World space"; this.ToolbarWorldSpaceButton.Click += new System.EventHandler(this.ToolbarWorldSpaceButton_Click); // @@ -3307,6 +3307,86 @@ namespace CodeWalker this.ToolbarSnapToGroundGridButton.Text = "Snap to Grid and Ground"; this.ToolbarSnapToGroundGridButton.Click += new System.EventHandler(this.ToolbarSnapToGroundGridButton_Click); // + // ToolbarSnapGridSizeButton + // + this.ToolbarSnapGridSizeButton.Name = "ToolbarSnapGridSizeButton"; + this.ToolbarSnapGridSizeButton.Size = new System.Drawing.Size(205, 22); + this.ToolbarSnapGridSizeButton.Text = "Grid Size..."; + this.ToolbarSnapGridSizeButton.Click += new System.EventHandler(this.ToolbarSnapGridSizeButton_Click); + // + // ToolbarRotationSnappingButton + // + this.ToolbarRotationSnappingButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.ToolbarRotationSnappingOffButton, + this.ToolbarRotationSnapping1Button, + this.ToolbarRotationSnapping2Button, + this.ToolbarRotationSnapping5Button, + this.ToolbarRotationSnapping10Button, + this.ToolbarRotationSnapping45Button, + this.ToolbarRotationSnapping90Button, + this.ToolbarRotationSnappingCustomButton}); + this.ToolbarRotationSnappingButton.Name = "ToolbarRotationSnappingButton"; + this.ToolbarRotationSnappingButton.Size = new System.Drawing.Size(205, 22); + this.ToolbarRotationSnappingButton.Text = "Rotation Snapping"; + // + // ToolbarRotationSnappingOffButton + // + this.ToolbarRotationSnappingOffButton.Name = "ToolbarRotationSnappingOffButton"; + this.ToolbarRotationSnappingOffButton.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnappingOffButton.Text = "Off"; + this.ToolbarRotationSnappingOffButton.Click += new System.EventHandler(this.ToolbarRotationSnappingOffButton_Click); + // + // ToolbarRotationSnapping1Button + // + this.ToolbarRotationSnapping1Button.Name = "ToolbarRotationSnapping1Button"; + this.ToolbarRotationSnapping1Button.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnapping1Button.Text = "1 Degree"; + this.ToolbarRotationSnapping1Button.Click += new System.EventHandler(this.ToolbarRotationSnapping1Button_Click); + // + // ToolbarRotationSnapping2Button + // + this.ToolbarRotationSnapping2Button.Name = "ToolbarRotationSnapping2Button"; + this.ToolbarRotationSnapping2Button.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnapping2Button.Text = "2 Degrees"; + this.ToolbarRotationSnapping2Button.Click += new System.EventHandler(this.ToolbarRotationSnapping2Button_Click); + // + // ToolbarRotationSnapping5Button + // + this.ToolbarRotationSnapping5Button.Checked = true; + this.ToolbarRotationSnapping5Button.CheckState = System.Windows.Forms.CheckState.Checked; + this.ToolbarRotationSnapping5Button.Name = "ToolbarRotationSnapping5Button"; + this.ToolbarRotationSnapping5Button.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnapping5Button.Text = "5 Degrees"; + this.ToolbarRotationSnapping5Button.Click += new System.EventHandler(this.ToolbarRotationSnapping5Button_Click); + // + // ToolbarRotationSnapping10Button + // + this.ToolbarRotationSnapping10Button.Name = "ToolbarRotationSnapping10Button"; + this.ToolbarRotationSnapping10Button.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnapping10Button.Text = "10 Degrees"; + this.ToolbarRotationSnapping10Button.Click += new System.EventHandler(this.ToolbarRotationSnapping10Button_Click); + // + // ToolbarRotationSnapping45Button + // + this.ToolbarRotationSnapping45Button.Name = "ToolbarRotationSnapping45Button"; + this.ToolbarRotationSnapping45Button.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnapping45Button.Text = "45 Degrees"; + this.ToolbarRotationSnapping45Button.Click += new System.EventHandler(this.ToolbarRotationSnapping45Button_Click); + // + // ToolbarRotationSnapping90Button + // + this.ToolbarRotationSnapping90Button.Name = "ToolbarRotationSnapping90Button"; + this.ToolbarRotationSnapping90Button.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnapping90Button.Text = "90 Degrees"; + this.ToolbarRotationSnapping90Button.Click += new System.EventHandler(this.ToolbarRotationSnapping90Button_Click); + // + // ToolbarRotationSnappingCustomButton + // + this.ToolbarRotationSnappingCustomButton.Name = "ToolbarRotationSnappingCustomButton"; + this.ToolbarRotationSnappingCustomButton.Size = new System.Drawing.Size(131, 22); + this.ToolbarRotationSnappingCustomButton.Text = "Custom..."; + this.ToolbarRotationSnappingCustomButton.Click += new System.EventHandler(this.ToolbarRotationSnappingCustomButton_Click); + // // toolStripSeparator2 // this.toolStripSeparator2.Name = "toolStripSeparator2"; @@ -3510,86 +3590,6 @@ namespace CodeWalker // this.SubtitleTimer.Tick += new System.EventHandler(this.SubtitleTimer_Tick); // - // ToolbarRotationSnappingButton - // - this.ToolbarRotationSnappingButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.ToolbarRotationSnappingOffButton, - this.ToolbarRotationSnapping1Button, - this.ToolbarRotationSnapping2Button, - this.ToolbarRotationSnapping5Button, - this.ToolbarRotationSnapping10Button, - this.ToolbarRotationSnapping45Button, - this.ToolbarRotationSnapping90Button, - this.ToolbarRotationSnappingCustomButton}); - this.ToolbarRotationSnappingButton.Name = "ToolbarRotationSnappingButton"; - this.ToolbarRotationSnappingButton.Size = new System.Drawing.Size(205, 22); - this.ToolbarRotationSnappingButton.Text = "Rotation Snapping"; - // - // ToolbarRotationSnappingOffButton - // - this.ToolbarRotationSnappingOffButton.Name = "ToolbarRotationSnappingOffButton"; - this.ToolbarRotationSnappingOffButton.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnappingOffButton.Text = "Off"; - this.ToolbarRotationSnappingOffButton.Click += new System.EventHandler(this.ToolbarRotationSnappingOffButton_Click); - // - // ToolbarRotationSnapping1Button - // - this.ToolbarRotationSnapping1Button.Name = "ToolbarRotationSnapping1Button"; - this.ToolbarRotationSnapping1Button.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnapping1Button.Text = "1 Degree"; - this.ToolbarRotationSnapping1Button.Click += new System.EventHandler(this.ToolbarRotationSnapping1Button_Click); - // - // ToolbarRotationSnapping2Button - // - this.ToolbarRotationSnapping2Button.Name = "ToolbarRotationSnapping2Button"; - this.ToolbarRotationSnapping2Button.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnapping2Button.Text = "2 Degrees"; - this.ToolbarRotationSnapping2Button.Click += new System.EventHandler(this.ToolbarRotationSnapping2Button_Click); - // - // ToolbarRotationSnapping5Button - // - this.ToolbarRotationSnapping5Button.Checked = true; - this.ToolbarRotationSnapping5Button.CheckState = System.Windows.Forms.CheckState.Checked; - this.ToolbarRotationSnapping5Button.Name = "ToolbarRotationSnapping5Button"; - this.ToolbarRotationSnapping5Button.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnapping5Button.Text = "5 Degrees"; - this.ToolbarRotationSnapping5Button.Click += new System.EventHandler(this.ToolbarRotationSnapping5Button_Click); - // - // ToolbarRotationSnapping10Button - // - this.ToolbarRotationSnapping10Button.Name = "ToolbarRotationSnapping10Button"; - this.ToolbarRotationSnapping10Button.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnapping10Button.Text = "10 Degrees"; - this.ToolbarRotationSnapping10Button.Click += new System.EventHandler(this.ToolbarRotationSnapping10Button_Click); - // - // ToolbarRotationSnappingCustomButton - // - this.ToolbarRotationSnappingCustomButton.Name = "ToolbarRotationSnappingCustomButton"; - this.ToolbarRotationSnappingCustomButton.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnappingCustomButton.Text = "Custom..."; - this.ToolbarRotationSnappingCustomButton.Click += new System.EventHandler(this.ToolbarRotationSnappingCustomButton_Click); - // - // ToolbarRotationSnapping45Button - // - this.ToolbarRotationSnapping45Button.Name = "ToolbarRotationSnapping45Button"; - this.ToolbarRotationSnapping45Button.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnapping45Button.Text = "45 Degrees"; - this.ToolbarRotationSnapping45Button.Click += new System.EventHandler(this.ToolbarRotationSnapping45Button_Click); - // - // ToolbarRotationSnapping90Button - // - this.ToolbarRotationSnapping90Button.Name = "ToolbarRotationSnapping90Button"; - this.ToolbarRotationSnapping90Button.Size = new System.Drawing.Size(180, 22); - this.ToolbarRotationSnapping90Button.Text = "90 Degrees"; - this.ToolbarRotationSnapping90Button.Click += new System.EventHandler(this.ToolbarRotationSnapping90Button_Click); - // - // ToolbarSnapGridSizeButton - // - this.ToolbarSnapGridSizeButton.Name = "ToolbarSnapGridSizeButton"; - this.ToolbarSnapGridSizeButton.Size = new System.Drawing.Size(205, 22); - this.ToolbarSnapGridSizeButton.Text = "Grid Size..."; - this.ToolbarSnapGridSizeButton.Click += new System.EventHandler(this.ToolbarSnapGridSizeButton_Click); - // // WorldForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -3900,7 +3900,7 @@ namespace CodeWalker private System.Windows.Forms.ToolStripMenuItem ToolbarSelectWaterQuadButton; private System.Windows.Forms.ToolStripMenuItem ToolbarSelectCollisionButton; private System.Windows.Forms.ToolStripMenuItem ToolbarSelectPathButton; - private System.Windows.Forms.ToolStripMenuItem ToolbarSelectDistantLodLightsButton; + private System.Windows.Forms.ToolStripMenuItem ToolbarSelectLodLightsButton; private System.Windows.Forms.ToolStripMenuItem ToolbarSelectMloInstanceButton; private System.Windows.Forms.ToolStripMenuItem ToolsMenuJenkInd; private System.Windows.Forms.ToolStripMenuItem ToolbarSelectTrainTrackButton; diff --git a/CodeWalker/WorldForm.cs b/CodeWalker/WorldForm.cs index 988902e..5824df5 100644 --- a/CodeWalker/WorldForm.cs +++ b/CodeWalker/WorldForm.cs @@ -1376,6 +1376,17 @@ namespace CodeWalker Renderer.RenderCar(cg.Position, cgori, cg._CCarGen.carModel, cg._CCarGen.popGroup); } } + if (selectionItem.LodLight != null) + { + Renderer.RenderSelectionLodLight(selectionItem.LodLight); + + if (selectionItem.LodLight.LodLights != null) + { + bbmin = selectionItem.LodLight.LodLights.BBMin; + bbmax = selectionItem.LodLight.LodLights.BBMax; + } + + } if (selectionItem.PathNode != null) { camrel = selectionItem.PathNode.Position - camera.Position; @@ -2753,7 +2764,27 @@ namespace CodeWalker } } } - if ((SelectionMode == MapSelectionMode.DistantLodLights) && (ymap.DistantLODLights != null)) + if ((SelectionMode == MapSelectionMode.LodLights) && (ymap.LODLights != null)) + { + var ll = ymap.LODLights; + if ((((ll.BBMin + ll.BBMax) * 0.5f) - camera.Position).Length() <= dmax) + { + + MapBox mb = new MapBox(); + mb.CamRelPos = -camera.Position; + mb.BBMin = ll.BBMin; + mb.BBMax = ll.BBMax; + mb.Orientation = Quaternion.Identity; + mb.Scale = Vector3.One; + Renderer.BoundingBoxes.Add(mb); + + if (ll.BVH != null) + { + UpdateMouseHits(ll.BVH, ref mray); + } + } + } + if ((SelectionMode == MapSelectionMode.LodLights) && (ymap.DistantLODLights != null)) { var dll = ymap.DistantLODLights; if ((((dll.BBMin + dll.BBMax) * 0.5f) - camera.Position).Length() <= dmax) @@ -2765,16 +2796,6 @@ namespace CodeWalker 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)) - { - CurMouseHit.DistantLodLights = dll; - CurMouseHit.HitDist = hitdist; - CurMouseHit.CamRel = mb.CamRelPos; - CurMouseHit.AABB = bbox; - } } } if ((SelectionMode == MapSelectionMode.Occlusion) && (ymap.BoxOccluders != null)) @@ -3296,6 +3317,7 @@ namespace CodeWalker CurMouseHit.PathNode = n as YndNode; CurMouseHit.TrainTrackNode = n as TrainTrackNode; CurMouseHit.ScenarioNode = n as ScenarioNode; + CurMouseHit.LodLight = n as YmapLODLight; CurMouseHit.NavPoint = n as YnvPoint; CurMouseHit.NavPortal = n as YnvPortal; CurMouseHit.NavPoly = null; @@ -3624,10 +3646,10 @@ namespace CodeWalker ToolbarDeleteItemButton.Enabled = true; ToolbarDeleteItemButton.Text = "Delete car generator"; } - else if (item.DistantLodLights != null) + else if (item.LodLight != null) { - SelectionEntityTabPage.Text = "DistLodLight"; - SelEntityPropertyGrid.SelectedObject = item.DistantLodLights; + SelectionEntityTabPage.Text = "LodLight"; + SelEntityPropertyGrid.SelectedObject = item.LodLight; } else if (item.GrassBatch != null) { @@ -5429,9 +5451,9 @@ namespace CodeWalker mode = MapSelectionMode.TrainTrack; ToolbarSelectTrainTrackButton.Checked = true; break; - case "Distant Lod Lights": - mode = MapSelectionMode.DistantLodLights; - ToolbarSelectDistantLodLightsButton.Checked = true; + case "Lod Lights": + mode = MapSelectionMode.LodLights; + ToolbarSelectLodLightsButton.Checked = true; break; case "Mlo Instance": mode = MapSelectionMode.MloInstance; @@ -7184,9 +7206,9 @@ namespace CodeWalker SetMouseSelect(true); } - private void ToolbarSelectDistantLodLightsButton_Click(object sender, EventArgs e) + private void ToolbarSelectLodLightsButton_Click(object sender, EventArgs e) { - SetSelectionMode("Distant Lod Lights"); + SetSelectionMode("Lod Lights"); SetMouseSelect(true); }