Set GameObjects using combined meshes as static

This commit is contained in:
Jeremy Pritts 2023-07-17 11:04:14 -04:00
parent 21db2fe3ae
commit c1707679c3
7 changed files with 84 additions and 55 deletions

View File

@ -1,25 +1,9 @@
using AssetRipper.Assets;
using AssetRipper.Numerics;
using AssetRipper.SourceGenerated.Classes.ClassID_25;
using AssetRipper.SourceGenerated.Classes.ClassID_4;
using AssetRipper.SourceGenerated.Enums;
using AssetRipper.SourceGenerated.Classes.ClassID_25;
using AssetRipper.SourceGenerated.Enums;
using AssetRipper.SourceGenerated.Extensions;
using System.Numerics;
namespace AssetRipper.Processing.Editor;
/// <summary>
///
/// </summary>
/// <remarks>
/// Rules for the methods in this class:
/// <list type="bullet">
/// <item>All methods must be static.</item>
/// <item>All public methods must return void and be named Convert.</item>
/// <item>Each public method must only take one parameter, and that parameter's type must inherit from <see cref="IUnityObjectBase"/>.</item>
/// <item>They must not resolve any PPtrs.</item>
/// </list>
/// </remarks>
internal static class EditorFormatConverter
{
public static void Convert(IRenderer renderer)
@ -35,22 +19,19 @@ internal static class EditorFormatConverter
renderer.AutoUVMaxDistance_C25 = 0.5f;
renderer.AutoUVMaxAngle_C25 = 89.0f;
renderer.LightmapParameters_C25P = null;
}
public static void Convert(ITransform transform)
{
if (transform.Has_RootOrder_C4())
if (renderer.Has_StaticBatchInfo_C25())
{
transform.RootOrder_C4 = transform.CalculateRootOrder();
if (!renderer.StaticBatchInfo_C25.IsDefault())
{
renderer.MarkGameObjectAsStatic();
}
}
if (transform.Has_LocalEulerAnglesHint_C4())
else if (renderer.Has_SubsetIndices_C25())
{
Vector3 eulerHints = new Quaternion(
transform.LocalRotation_C4.X,
transform.LocalRotation_C4.Y,
transform.LocalRotation_C4.Z,
transform.LocalRotation_C4.W).ToEulerAngle(true);
transform.LocalEulerAnglesHint_C4.SetValues(eulerHints.X, eulerHints.Y, eulerHints.Z);
if (renderer.SubsetIndices_C25.Count != 0)
{
renderer.MarkGameObjectAsStatic();
}
}
}
}

View File

@ -0,0 +1,39 @@
using AssetRipper.Assets;
using AssetRipper.Numerics;
using AssetRipper.SourceGenerated.Classes.ClassID_4;
using AssetRipper.SourceGenerated.Extensions;
using System.Numerics;
namespace AssetRipper.Processing.Editor;
/// <summary>
///
/// </summary>
/// <remarks>
/// Rules for the methods in this class:
/// <list type="bullet">
/// <item>All methods must be static.</item>
/// <item>All public methods must return void and be named Convert.</item>
/// <item>Each public method must only take one parameter, and that parameter's type must inherit from <see cref="IUnityObjectBase"/>.</item>
/// <item>They must not resolve any PPtrs.</item>
/// </list>
/// </remarks>
internal static class EditorFormatConverterAsync
{
public static void Convert(ITransform transform)
{
if (transform.Has_RootOrder_C4())
{
transform.RootOrder_C4 = transform.CalculateRootOrder();
}
if (transform.Has_LocalEulerAnglesHint_C4())
{
Vector3 eulerHints = new Quaternion(
transform.LocalRotation_C4.X,
transform.LocalRotation_C4.Y,
transform.LocalRotation_C4.Z,
transform.LocalRotation_C4.W).ToEulerAngle(true);
transform.LocalEulerAnglesHint_C4.SetValues(eulerHints.X, eulerHints.Y, eulerHints.Z);
}
}
}

View File

@ -100,6 +100,9 @@ namespace AssetRipper.Processing.Editor
case IGameObject gameObject:
gameObject.ConvertToEditorFormat(tagManager);
break;
case IRenderer renderer:
EditorFormatConverter.Convert(renderer);
break;
case ISpriteAtlas spriteAtlas:
spriteAtlas.ConvertToEditorFormat();
break;
@ -124,10 +127,7 @@ namespace AssetRipper.Processing.Editor
{
//ordered by approximate frequency
case ITransform transform:
EditorFormatConverter.Convert(transform);
break;
case IRenderer renderer:
EditorFormatConverter.Convert(renderer);
EditorFormatConverterAsync.Convert(transform);
break;
case IMesh mesh:
mesh.SetMeshOptimizationFlags(MeshOptimizationFlags.Everything);

View File

@ -317,7 +317,7 @@ namespace AssetRipper.Processing.StaticMeshes
{
meshFilter.Mesh_C33P = mesh;
renderer.ClearStaticBatchInfo();
renderer.SetStaticEditorFlagsOnGameObject();
renderer.MarkGameObjectAsStatic();
}
private static IMesh MakeMeshFromData(string cleanName, MeshData instanceMeshData, ProcessedAssetCollection processedCollection)

View File

@ -3,6 +3,7 @@ using AssetRipper.SourceGenerated.Classes.ClassID_1;
using AssetRipper.SourceGenerated.Classes.ClassID_137;
using AssetRipper.SourceGenerated.Classes.ClassID_23;
using AssetRipper.SourceGenerated.Classes.ClassID_25;
using AssetRipper.SourceGenerated.Extensions;
using System.Collections;
namespace AssetRipper.Processing.StaticMeshes
@ -11,13 +12,13 @@ namespace AssetRipper.Processing.StaticMeshes
{
public static bool IsStaticMeshRenderer(this IUnityObjectBase asset, [NotNullWhen(true)] out IRenderer? renderer)
{
renderer = (IRenderer?)(asset as IMeshRenderer) ?? (asset as ISkinnedMeshRenderer);
renderer = asset as IRenderer;
return renderer is not null && !renderer.ReferencesDynamicMesh();
}
private static bool ReferencesDynamicMesh(this IRenderer renderer)
{
return renderer.Has_StaticBatchInfo_C25() && renderer.StaticBatchInfo_C25.SubMeshCount == 0
return renderer.Has_StaticBatchInfo_C25() && renderer.StaticBatchInfo_C25.IsDefault()
|| renderer.Has_SubsetIndices_C25() && renderer.SubsetIndices_C25.Count == 0;
}
@ -28,26 +29,11 @@ namespace AssetRipper.Processing.StaticMeshes
: renderer.SubsetIndices_C25;
}
public static void SetStaticEditorFlagsOnGameObject(this IRenderer renderer)
{
//https://github.com/AssetRipper/AssetRipper/issues/702
IGameObject? gameObject = renderer.GameObject_C25P;
if (gameObject is not null)
{
//When enabling Everything, Unity sets all bits even though it only uses the first 7 bits.
//In the yaml, this appropriately uint.MaxValue
//If ContributeGI is disabled, it does not set the reserved bits and displays 126 in the yaml.
gameObject.StaticEditorFlags_C1 = uint.MaxValue;
}
//Should this be done even if the static meshes aren't separated?
}
public static void ClearStaticBatchInfo(this IRenderer renderer)
{
if (renderer.Has_StaticBatchInfo_C25())
{
renderer.StaticBatchInfo_C25.FirstSubMesh = 0;
renderer.StaticBatchInfo_C25.SubMeshCount = 0;
renderer.StaticBatchInfo_C25.Reset();
}
else if (renderer.Has_SubsetIndices_C25())
{

View File

@ -1,4 +1,5 @@
using AssetRipper.SourceGenerated.Classes.ClassID_21;
using AssetRipper.SourceGenerated.Classes.ClassID_1;
using AssetRipper.SourceGenerated.Classes.ClassID_21;
using AssetRipper.SourceGenerated.Classes.ClassID_25;
using AssetRipper.SourceGenerated.Enums;
using System.Diagnostics;
@ -20,6 +21,23 @@ namespace AssetRipper.SourceGenerated.Extensions
return null;
}
/// <summary>
/// Set <see cref="IGameObject.StaticEditorFlags_C1"/> on <see cref="IRenderer.GameObject_C25P"/> to indicate that the object is static.
/// </summary>
/// <param name="renderer">The renderer attached to a static gameobject.</param>
public static void MarkGameObjectAsStatic(this IRenderer renderer)
{
//https://github.com/AssetRipper/AssetRipper/issues/702
IGameObject? gameObject = renderer.GameObject_C25P;
if (gameObject is not null)
{
//When enabling Everything, Unity sets all bits even though it only uses the first 7 bits.
//In the yaml, this appropriately uint.MaxValue
//If ContributeGI is disabled, it does not set the reserved bits and displays 126 in the yaml.
gameObject.StaticEditorFlags_C1 = uint.MaxValue;
}
}
public static ShadowCastingMode GetShadowCastingMode(this IRenderer renderer)
{
return renderer.Has_CastShadows_C25_Byte()

View File

@ -24,5 +24,10 @@ namespace AssetRipper.SourceGenerated.Extensions
}
}
}
public static bool IsDefault(this IStaticBatchInfo staticBatchInfo)
{
return staticBatchInfo.FirstSubMesh == 0 && staticBatchInfo.SubMeshCount == 0;
}
}
}