Compare commits
	
		
			3 Commits
		
	
	
		
			1d32b3ef7b
			...
			940c78e1cf
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 940c78e1cf | |
|  | 13f822673a | |
|  | 5fcf9db59c | 
|  | @ -332,7 +332,7 @@ public class WorldRep : IChunk | ||||||
|         public LightmapInfo[] LightList { get; set; } |         public LightmapInfo[] LightList { get; set; } | ||||||
|         public Lightmap[] Lightmaps { get; set; } |         public Lightmap[] Lightmaps { get; set; } | ||||||
|         public int LightIndexCount { get; set; } |         public int LightIndexCount { get; set; } | ||||||
|         public ushort[] LightIndices { get; set; } |         public List<ushort> LightIndices { get; set; } | ||||||
| 
 | 
 | ||||||
|         public Cell(BinaryReader reader, int bpp) |         public Cell(BinaryReader reader, int bpp) | ||||||
|         { |         { | ||||||
|  | @ -392,10 +392,10 @@ public class WorldRep : IChunk | ||||||
|                 Lightmaps[i] = new Lightmap(reader, info.Width, info.Height, info.AnimLightBitmask, bpp); |                 Lightmaps[i] = new Lightmap(reader, info.Width, info.Height, info.AnimLightBitmask, bpp); | ||||||
|             } |             } | ||||||
|             LightIndexCount = reader.ReadInt32(); |             LightIndexCount = reader.ReadInt32(); | ||||||
|             LightIndices = new ushort[LightIndexCount]; |             LightIndices = new List<ushort>(LightIndexCount); | ||||||
|             for (var i = 0; i < LightIndexCount; i++) |             for (var i = 0; i < LightIndexCount; i++) | ||||||
|             { |             { | ||||||
|                 LightIndices[i] = reader.ReadUInt16(); |                 LightIndices.Add(reader.ReadUInt16()); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -49,6 +49,12 @@ public static class MathUtils | ||||||
|         return d2 < r2; |         return d2 < r2; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static bool Intersects(Sphere sphere, Sphere other) | ||||||
|  |     { | ||||||
|  |         var rsum = sphere.Radius + other.Radius; | ||||||
|  |         return (sphere.Position - other.Position).Length() <= rsum; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static float DistanceFromPlane(Plane plane, Vector3 point) |     public static float DistanceFromPlane(Plane plane, Vector3 point) | ||||||
|     { |     { | ||||||
|         return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length(); |         return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length(); | ||||||
|  |  | ||||||
|  | @ -22,9 +22,9 @@ class Program | ||||||
|         public float spotlightInnerAngle; |         public float spotlightInnerAngle; | ||||||
|         public float spotlightOuterAngle; |         public float spotlightOuterAngle; | ||||||
| 
 | 
 | ||||||
|  |         public int objId; | ||||||
|  |         public int lightTableIndex; | ||||||
|         public bool anim; |         public bool anim; | ||||||
|         public int animObjId; |  | ||||||
|         public int animLightTableIndex; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static void Main(string[] args) |     static void Main(string[] args) | ||||||
|  | @ -36,9 +36,10 @@ class Program | ||||||
|         var campaignName = "JAYRUDE_Tests"; |         var campaignName = "JAYRUDE_Tests"; | ||||||
|         var missionName = "lm_test.cow"; |         var missionName = "lm_test.cow"; | ||||||
| 
 | 
 | ||||||
|  |         // campaignName = "JAYRUDE_1MIL_Mages"; | ||||||
|         // campaignName = "TDP20AC_a_burrick_in_a_room"; |         // campaignName = "TDP20AC_a_burrick_in_a_room"; | ||||||
|         campaignName = "AtdV"; |         // campaignName = "AtdV"; | ||||||
|         missionName = "miss20.mis"; |         // missionName = "miss20.mis"; | ||||||
| 
 | 
 | ||||||
|         // Setup extract path |         // Setup extract path | ||||||
|         var tmpDir = Directory.CreateTempSubdirectory("KCLightmapper"); |         var tmpDir = Directory.CreateTempSubdirectory("KCLightmapper"); | ||||||
|  | @ -143,10 +144,10 @@ class Program | ||||||
|         foreach (var (lightIdx, animCellMaps) in map) |         foreach (var (lightIdx, animCellMaps) in map) | ||||||
|         { |         { | ||||||
|             // Get the appropriate property!! |             // Get the appropriate property!! | ||||||
|             var light = lights.Find((l) => l.anim && l.animLightTableIndex == lightIdx); |             var light = lights.Find((l) => l.anim && l.lightTableIndex == lightIdx); | ||||||
|             foreach (var prop in animLightChunk.properties) |             foreach (var prop in animLightChunk.properties) | ||||||
|             { |             { | ||||||
|                 if (prop.objectId == light.animObjId) |                 if (prop.objectId == light.objId) | ||||||
|                 { |                 { | ||||||
|                     prop.LightTableLightIndex = lightIdx; |                     prop.LightTableLightIndex = lightIdx; | ||||||
|                     prop.LightTableMapIndex = (ushort)worldRep.LightingTable.AnimMapCount; |                     prop.LightTableMapIndex = (ushort)worldRep.LightingTable.AnimMapCount; | ||||||
|  | @ -195,6 +196,7 @@ class Program | ||||||
|                     color = HsbToRgb(sz.Y, sz.Z, Math.Min(sz.X, 255.0f)), |                     color = HsbToRgb(sz.Y, sz.Z, Math.Min(sz.X, 255.0f)), | ||||||
|                     radius = float.MaxValue, |                     radius = float.MaxValue, | ||||||
|                     r2 = float.MaxValue, |                     r2 = float.MaxValue, | ||||||
|  |                     lightTableIndex = worldRep.LightingTable.LightCount, | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 lights.Add(light); |                 lights.Add(light); | ||||||
|  | @ -272,6 +274,7 @@ class Program | ||||||
|                         spotlightDir = baseLight.spotlightDir, |                         spotlightDir = baseLight.spotlightDir, | ||||||
|                         spotlightInnerAngle = baseLight.spotlightInnerAngle, |                         spotlightInnerAngle = baseLight.spotlightInnerAngle, | ||||||
|                         spotlightOuterAngle = baseLight.spotlightOuterAngle, |                         spotlightOuterAngle = baseLight.spotlightOuterAngle, | ||||||
|  |                         lightTableIndex = worldRep.LightingTable.LightCount, | ||||||
|                     }; |                     }; | ||||||
| 
 | 
 | ||||||
|                     if (propLight.Radius == 0) |                     if (propLight.Radius == 0) | ||||||
|  | @ -309,8 +312,8 @@ class Program | ||||||
|                         spotlightInnerAngle = baseLight.spotlightInnerAngle, |                         spotlightInnerAngle = baseLight.spotlightInnerAngle, | ||||||
|                         spotlightOuterAngle = baseLight.spotlightOuterAngle, |                         spotlightOuterAngle = baseLight.spotlightOuterAngle, | ||||||
|                         anim = true, |                         anim = true, | ||||||
|                         animObjId = id, |                         objId = id, | ||||||
|                         animLightTableIndex = propAnimLight.LightTableLightIndex, |                         lightTableIndex = propAnimLight.LightTableLightIndex, | ||||||
|                     }; |                     }; | ||||||
|                     if (propAnimLight.Radius == 0) |                     if (propAnimLight.Radius == 0) | ||||||
|                     { |                     { | ||||||
|  | @ -411,6 +414,41 @@ class Program | ||||||
|     { |     { | ||||||
|         var hdr = wr.DataHeader.LightmapFormat == 2; |         var hdr = wr.DataHeader.LightmapFormat == 2; | ||||||
| 
 | 
 | ||||||
|  |         // We set up light indices in a separate loop because the actual lighting | ||||||
|  |         // phase takes a lot of shortcuts that we don't want | ||||||
|  |         Parallel.ForEach(wr.Cells, cell => | ||||||
|  |         { | ||||||
|  |             cell.LightIndexCount = 0; | ||||||
|  |             cell.LightIndices.Clear(); | ||||||
|  | 
 | ||||||
|  |             // The OG lightmapper uses the cell traversal to work out all the cells that | ||||||
|  |             // are actually visited. We're a lot more coarse and just say if a cell is | ||||||
|  |             // in range then we potentially affect the lighting in the cell and add it  | ||||||
|  |             // to the list. Cells already contain their sphere bounds so we just use | ||||||
|  |             // that for now, but a tighter AABB is another option. | ||||||
|  |             var cellSphere = new MathUtils.Sphere(cell.SphereCenter, cell.SphereRadius); | ||||||
|  |             foreach (var light in lights) | ||||||
|  |             { | ||||||
|  |                 // If the light had radius 0 (represented here with max float) then we | ||||||
|  |                 // always add it to the list | ||||||
|  |                 // TODO: Neaten this up | ||||||
|  |                 if (light.radius == float.MaxValue) | ||||||
|  |                 { | ||||||
|  |                     cell.LightIndexCount++; | ||||||
|  |                     cell.LightIndices.Add((ushort)light.lightTableIndex); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     var lightSphere = new MathUtils.Sphere(light.position, light.radius); | ||||||
|  |                     if (MathUtils.Intersects(cellSphere, lightSphere)) | ||||||
|  |                     { | ||||||
|  |                         cell.LightIndexCount++; | ||||||
|  |                         cell.LightIndices.Add((ushort)light.lightTableIndex); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|         Parallel.ForEach(wr.Cells, cell => |         Parallel.ForEach(wr.Cells, cell => | ||||||
|         { |         { | ||||||
|             // Reset cell AnimLight palette |             // Reset cell AnimLight palette | ||||||
|  | @ -549,12 +587,12 @@ class Program | ||||||
|                                 if (light.anim) |                                 if (light.anim) | ||||||
|                                 { |                                 { | ||||||
|                                     // TODO: Don't recalculate this for every point lol |                                     // TODO: Don't recalculate this for every point lol | ||||||
|                                     var paletteIdx = cell.AnimLights.IndexOf((ushort)light.animLightTableIndex); |                                     var paletteIdx = cell.AnimLights.IndexOf((ushort)light.lightTableIndex); | ||||||
|                                     if (paletteIdx == -1) |                                     if (paletteIdx == -1) | ||||||
|                                     { |                                     { | ||||||
|                                         paletteIdx = cell.AnimLightCount; |                                         paletteIdx = cell.AnimLightCount; | ||||||
|                                         cell.AnimLightCount++; |                                         cell.AnimLightCount++; | ||||||
|                                         cell.AnimLights.Add((ushort)light.animLightTableIndex); |                                         cell.AnimLights.Add((ushort)light.lightTableIndex); | ||||||
|                                     } |                                     } | ||||||
|                                     info.AnimLightBitmask |= 1u << paletteIdx; |                                     info.AnimLightBitmask |= 1u << paletteIdx; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue