Separate some mesh stuff
This commit is contained in:
parent
39dbede993
commit
a0b287b9fa
|
@ -8,13 +8,6 @@ namespace KeepersCompound.Lightmapper;
|
|||
|
||||
public class LightMapper
|
||||
{
|
||||
private enum SurfaceType
|
||||
{
|
||||
Solid,
|
||||
Sky,
|
||||
Water,
|
||||
}
|
||||
|
||||
private class Settings
|
||||
{
|
||||
public Vector3 AmbientLight;
|
||||
|
@ -30,7 +23,7 @@ public class LightMapper
|
|||
private ObjectHierarchy _hierarchy;
|
||||
private Raytracer _scene;
|
||||
private List<Light> _lights;
|
||||
private List<SurfaceType> _triangleTypeMap;
|
||||
private SurfaceType[] _triangleTypeMap;
|
||||
|
||||
public LightMapper(
|
||||
string installPath,
|
||||
|
@ -42,9 +35,17 @@ public class LightMapper
|
|||
_misPath = _campaign.GetResourcePath(ResourceType.Mission, missionName);
|
||||
_mission = Timing.TimeStage("Parse DB", () => new DbFile(_misPath));
|
||||
_hierarchy = Timing.TimeStage("Build Hierarchy", BuildHierarchy);
|
||||
_triangleTypeMap = [];
|
||||
_scene = Timing.TimeStage("Build Scene", BuildRaytracingScene);
|
||||
_lights = [];
|
||||
|
||||
var mesh = Timing.TimeStage("Build Mesh", BuildMesh);
|
||||
_triangleTypeMap = mesh.TriangleSurfaceMap;
|
||||
_scene = Timing.TimeStage("Build RT Scene", () =>
|
||||
{
|
||||
var rt = new Raytracer();
|
||||
rt.AddMesh(new TriangleMesh(mesh.Vertices, mesh.Indices));
|
||||
rt.CommitScene();
|
||||
return rt;
|
||||
});
|
||||
}
|
||||
|
||||
public void Light()
|
||||
|
@ -109,16 +110,17 @@ public class LightMapper
|
|||
return new ObjectHierarchy(_mission);
|
||||
}
|
||||
|
||||
private Raytracer BuildRaytracingScene()
|
||||
private Mesh BuildMesh()
|
||||
{
|
||||
// TODO: Should this throw?
|
||||
if (!_mission.TryGetChunk<WorldRep>("WREXT", out var worldRep))
|
||||
if (!_mission.TryGetChunk<WorldRep>("WREXT", out var worldRep) ||
|
||||
!_mission.TryGetChunk<BrList>("BRLIST", out var brList))
|
||||
{
|
||||
return null;
|
||||
return new Mesh(0, [], [], []);
|
||||
}
|
||||
|
||||
var vertices = new List<Vector3>();
|
||||
var indices = new List<int>();
|
||||
var meshBuilder = new MeshBuilder();
|
||||
var polyVertices = new List<Vector3>();
|
||||
|
||||
// Worldrep mesh
|
||||
foreach (var cell in worldRep.Cells)
|
||||
|
@ -138,12 +140,12 @@ public class LightMapper
|
|||
for (var polyIdx = 0; polyIdx < numRenderPolys; polyIdx++)
|
||||
{
|
||||
var poly = cell.Polys[polyIdx];
|
||||
var meshIndexOffset = vertices.Count;
|
||||
var numPolyVertices = poly.VertexCount;
|
||||
for (var j = 0; j < numPolyVertices; j++)
|
||||
|
||||
polyVertices.Clear();
|
||||
polyVertices.EnsureCapacity(poly.VertexCount);
|
||||
for (var i = 0; i < poly.VertexCount; i++)
|
||||
{
|
||||
var vertex = cell.Vertices[cell.Indices[cellIdxOffset + j]];
|
||||
vertices.Add(vertex);
|
||||
polyVertices.Add(cell.Vertices[cell.Indices[cellIdxOffset + i]]);
|
||||
}
|
||||
|
||||
// We need to know what type of surface this poly is so we can map Embree primitive IDs to surface
|
||||
|
@ -158,26 +160,12 @@ public class LightMapper
|
|||
primType = SurfaceType.Water;
|
||||
}
|
||||
|
||||
// Cell polygons are n-sided, but fortunately they're convex so we can just do a fan triangulation
|
||||
for (var j = 1; j < numPolyVertices - 1; j++)
|
||||
{
|
||||
indices.Add(meshIndexOffset);
|
||||
indices.Add(meshIndexOffset + j);
|
||||
indices.Add(meshIndexOffset + j + 1);
|
||||
_triangleTypeMap.Add(primType);
|
||||
}
|
||||
|
||||
cellIdxOffset += cell.Polys[polyIdx].VertexCount;
|
||||
meshBuilder.AddPolygon(polyVertices, primType);
|
||||
cellIdxOffset += poly.VertexCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Object meshes??
|
||||
// TODO: Should this throw?
|
||||
if (!_mission.TryGetChunk<BrList>("BRLIST", out var brList))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Object meshes
|
||||
foreach (var brush in brList.Brushes)
|
||||
{
|
||||
if (brush.media != BrList.Brush.Media.Object)
|
||||
|
@ -198,7 +186,7 @@ public class LightMapper
|
|||
var renderMode = renderTypeProp?.mode ?? PropRenderType.Mode.Normal;
|
||||
|
||||
// TODO: Check which rendermodes cast shadows :)
|
||||
if (modelNameProp == null || !castsShadows || renderMode != PropRenderType.Mode.Normal)
|
||||
if (modelNameProp == null || !castsShadows || renderMode == PropRenderType.Mode.CoronaOnly)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -246,29 +234,21 @@ public class LightMapper
|
|||
}
|
||||
}
|
||||
|
||||
// for each polygon slam it's vertices and indices :)
|
||||
// for each polygon slam its vertices and indices :)
|
||||
foreach (var poly in model.Polygons)
|
||||
{
|
||||
var indexOffset = vertices.Count;
|
||||
polyVertices.Clear();
|
||||
polyVertices.EnsureCapacity(poly.VertexCount);
|
||||
foreach (var idx in poly.VertexIndices)
|
||||
{
|
||||
vertices.Add(model.Vertices[idx]);
|
||||
polyVertices.Add(model.Vertices[idx]);
|
||||
}
|
||||
|
||||
for (int i = 1; i < poly.VertexCount - 1; i++)
|
||||
{
|
||||
indices.Add(indexOffset);
|
||||
indices.Add(indexOffset + i);
|
||||
indices.Add(indexOffset + i + 1);
|
||||
_triangleTypeMap.Add(SurfaceType.Solid);
|
||||
}
|
||||
meshBuilder.AddPolygon(polyVertices, SurfaceType.Solid);
|
||||
}
|
||||
}
|
||||
|
||||
var rt = new Raytracer();
|
||||
rt.AddMesh(new TriangleMesh([.. vertices], [.. indices]));
|
||||
rt.CommitScene();
|
||||
return rt;
|
||||
|
||||
return meshBuilder.Build();
|
||||
}
|
||||
|
||||
private void BuildLightList()
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace KeepersCompound.Lightmapper;
|
||||
|
||||
public enum SurfaceType
|
||||
{
|
||||
Solid,
|
||||
Sky,
|
||||
Water,
|
||||
}
|
||||
|
||||
public class Mesh(int triangleCount, List<Vector3> vertices, List<int> indices, List<SurfaceType> triangleSurfaceMap)
|
||||
{
|
||||
public int TriangleCount { get; } = triangleCount;
|
||||
public Vector3[] Vertices { get; } = [..vertices];
|
||||
public int[] Indices { get; } = [..indices];
|
||||
public SurfaceType[] TriangleSurfaceMap { get; } = [..triangleSurfaceMap];
|
||||
}
|
||||
|
||||
public class MeshBuilder
|
||||
{
|
||||
private int _triangleCount = 0;
|
||||
private readonly List<Vector3> _vertices = [];
|
||||
private readonly List<int> _indices = [];
|
||||
private readonly List<SurfaceType> _primSurfaceMap = [];
|
||||
|
||||
public void AddPolygon(List<Vector3> vertices, SurfaceType surfaceType)
|
||||
{
|
||||
var vertexCount = vertices.Count;
|
||||
var indexOffset = _vertices.Count;
|
||||
|
||||
// Polygons are n-sided, but fortunately they're convex so we can just do a fan triangulation
|
||||
_vertices.AddRange(vertices);
|
||||
for (var i = 1; i < vertexCount - 1; i++)
|
||||
{
|
||||
_indices.Add(indexOffset);
|
||||
_indices.Add(indexOffset + i);
|
||||
_indices.Add(indexOffset + i + 1);
|
||||
_primSurfaceMap.Add(surfaceType);
|
||||
_triangleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public Mesh Build()
|
||||
{
|
||||
return new Mesh(_triangleCount, _vertices, _indices, _primSurfaceMap);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue