Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Chroma/ChromaController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ internal static class ChromaController
internal const string V2_COLLISION = "_collision";
internal const string V2_MATERIALS = "_materials";
internal const string V2_MATERIAL = "_material";
internal const string V2_MESH = "_mesh";
internal const string V2_VERTICES = "_vertices";
internal const string V2_UV = "_uv";
internal const string V2_TRIANGLES = "_triangles";

internal const string V2_ATTENUATION = "_attenuation";
internal const string V2_OFFSET = "_offset";
Expand Down Expand Up @@ -74,6 +78,10 @@ internal static class ChromaController
internal const string COLLISION = "collision";
internal const string MATERIALS = "materials";
internal const string MATERIAL = "material";
internal const string MESH = "mesh";
internal const string VERTICES = "vertices";
internal const string UV = "uv";
internal const string TRIANGLES = "triangles";

internal const string ASSIGN_FOG_TRACK = "AssignFogTrack";
internal const string ANIMATE_COMPONENT = "AnimateComponent";
Expand Down
59 changes: 54 additions & 5 deletions Chroma/EnvironmentEnhancement/GeometryFactory.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Chroma.Colorizer;
using Chroma.Extras;
using Chroma.HarmonyPatches.Colorizer.Initialize;
using Chroma.HarmonyPatches.EnvironmentComponent;
using CustomJSONData.CustomBeatmap;
using Heck;
using IPA.Utilities;
using JetBrains.Annotations;
using UnityEngine;
Expand All @@ -24,7 +26,8 @@ internal enum GeometryType
Cube,
Plane,
Quad,
Triangle
Triangle,
Custom
}

internal enum ShaderType
Expand All @@ -34,6 +37,44 @@ internal enum ShaderType
TransparentLight
}

internal struct MeshData
{
public Vector3[] Vertices; // vertex positions
public Vector2[]? Uv; // texture coordinates UV0. must be in 0-1 range
public int[]? Triangles; // must be in order of vertices and multiple of 3

public MeshData(CustomData customData, bool v2)
{
Vertices = customData.GetRequiredFromArrayOfFloatArray(v2 ? V2_VERTICES : VERTICES, v => new Vector3(v[0], v[1], v[2])).ToArray();
Uv = customData.GetFromArrayOfFloatArray(v2 ? V2_UV : UV, v => new Vector2(v[0], v[1]))?.ToArray();
Triangles = customData.Get<IEnumerable<object>>(v2 ? V2_TRIANGLES : TRIANGLES)?.Select(Convert.ToInt32).ToArray();
}

public Mesh ToMesh()
{
Mesh mesh = new()
{
vertices = Vertices,
};

if (Uv != null)
{
mesh.uv = Uv;
}

if (Triangles != null)
{
mesh.triangles = Triangles;
}

mesh.RecalculateBounds();
mesh.RecalculateNormals();
mesh.RecalculateTangents();

return mesh;
}
}

internal class GeometryFactory
{
private static readonly FieldAccessor<TubeBloomPrePassLight, BoolSO>.Accessor _mainEffectPostProcessEnabledAccessor = FieldAccessor<TubeBloomPrePassLight, BoolSO>.GetAccessor("_mainEffectPostProcessEnabled");
Expand Down Expand Up @@ -94,6 +135,7 @@ internal GameObject Create(CustomData customData)
GeometryType.Plane => PrimitiveType.Plane,
GeometryType.Quad => PrimitiveType.Quad,
GeometryType.Triangle => PrimitiveType.Quad,
GeometryType.Custom => PrimitiveType.Quad,
_ => throw new ArgumentOutOfRangeException($"Geometry type {geometryType} does not match a primitive!", nameof(geometryType))
};

Expand All @@ -109,16 +151,23 @@ internal GameObject Create(CustomData customData)
// Shared material is usually better performance as far as I know
meshRenderer.sharedMaterial = materialInfo.Material;

if (geometryType == GeometryType.Triangle)
Mesh? customMesh = geometryType switch
{
Mesh mesh = ChromaUtils.CreateTriangleMesh();
gameObject.GetComponent<MeshFilter>().sharedMesh = mesh;
GeometryType.Custom => new MeshData(customData.GetRequired<CustomData>(_v2 ? V2_MESH : MESH), _v2).ToMesh(),
GeometryType.Triangle => ChromaUtils.CreateTriangleMesh(),
_ => null
};

if (customMesh != null)
{
gameObject.GetComponent<MeshFilter>().sharedMesh = customMesh;

if (collision)
{
MeshCollider meshCollider = gameObject.GetComponent<MeshCollider>();
if (meshCollider != null)
{
meshCollider.sharedMesh = mesh;
meshCollider.sharedMesh = customMesh;
}
}
}
Expand Down
22 changes: 22 additions & 0 deletions Chroma/Extras/CustomDataExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CustomJSONData;
using CustomJSONData.CustomBeatmap;

namespace Heck
{
// TODO: Move to CustomJsonData
public static class CustomDataExtensions
{
public static IEnumerable<T>? GetFromArrayOfFloatArray<T>(this CustomData customData, string key, Func<float[], T> convert)
{
return customData.Get<IEnumerable<IEnumerable<object>>>(key)?.Select(o => convert(o.Select(Convert.ToSingle).ToArray()));
}

public static IEnumerable<T> GetRequiredFromArrayOfFloatArray<T>(this CustomData customData, string key, Func<float[], T> convert)
{
return customData.GetFromArrayOfFloatArray(key, convert) ?? throw new JsonNotDefinedException(key);
}
}
}