diff --git a/src/SA3D.Modeling/Mesh/Chunk/ChunkTypeExtensions.cs b/src/SA3D.Modeling/Mesh/Chunk/ChunkTypeExtensions.cs
index 2427a1f..bfdf95e 100644
--- a/src/SA3D.Modeling/Mesh/Chunk/ChunkTypeExtensions.cs
+++ b/src/SA3D.Modeling/Mesh/Chunk/ChunkTypeExtensions.cs
@@ -115,18 +115,6 @@ public static bool CheckHasWeights(this VertexChunkType type)
or VertexChunkType.NormalAttributes;
}
- ///
- /// Checks whether a vertex chunktype has diffuse colors
- ///
- /// The type to check.
- ///
- public static bool CheckStripHasColor(this PolyChunkType type)
- {
- return type is PolyChunkType.Strip_Color
- or PolyChunkType.Strip_TexColor
- or PolyChunkType.Strip_HDTexColor;
- }
-
///
/// Returns the number of 4-byte values a chunk vertex has.
///
@@ -167,5 +155,89 @@ public static ushort GetIntegerSize(this VertexChunkType type)
throw new ArgumentException($"Invalid vertex chunk type: {type}", nameof(type));
}
}
+
+
+ ///
+ /// Checks whether a polychunk type is a type of strip chunk.
+ ///
+ /// The type to check.
+ public static bool CheckIsStrip(this PolyChunkType type)
+ {
+ return (int)type >= _strip && type <= PolyChunkType.Strip_HDTexDouble;
+ }
+
+ ///
+ /// Returns the number of texture coordinate sets by strip chunk type.
+ ///
Throws an error if is not a strip chunk type.
+ ///
+ /// Type to get the strip chunk texture coordinate set count of.
+ public static int GetStripTexCoordCount(this PolyChunkType type)
+ {
+ if(!type.CheckIsStrip())
+ {
+ throw new ArgumentException($"Polychunk type \"{type}\" is not a strip chunk type!", nameof(type));
+ }
+ else if(type is PolyChunkType.Strip_Tex
+ or PolyChunkType.Strip_HDTex
+ or PolyChunkType.Strip_TexNormal
+ or PolyChunkType.Strip_HDTexNormal
+ or PolyChunkType.Strip_TexColor
+ or PolyChunkType.Strip_HDTexColor)
+ {
+ return 1;
+ }
+ else if(type is PolyChunkType.Strip_TexDouble
+ or PolyChunkType.Strip_HDTexDouble)
+ {
+ return 2;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ ///
+ /// Checks whether a strip chunk type contains HD texture coordinates.
+ ///
Throws an error if is not a strip chunk type.
+ ///
+ /// Type to check
+ public static bool CheckStripHasHDTexcoords(this PolyChunkType type)
+ {
+ return !type.CheckIsStrip()
+ ? throw new ArgumentException($"Polychunk type \"{type}\" is not a strip chunk type!", nameof(type))
+ : type is PolyChunkType.Strip_HDTex
+ or PolyChunkType.Strip_HDTexColor
+ or PolyChunkType.Strip_HDTexNormal
+ or PolyChunkType.Strip_HDTexDouble;
+ }
+
+ ///
+ /// Checks whether a strip chunk type contains colors.
+ ///
Throws an error if is not a strip chunk type.
+ ///
+ /// Type to check
+ public static bool CheckStripHasColors(this PolyChunkType type)
+ {
+ return !type.CheckIsStrip()
+ ? throw new ArgumentException($"Polychunk type \"{type}\" is not a strip chunk type!", nameof(type))
+ : type is PolyChunkType.Strip_Color
+ or PolyChunkType.Strip_TexColor
+ or PolyChunkType.Strip_HDTexColor;
+ }
+
+ ///
+ /// Checks whether a strip chunk type contains normals.
+ ///
Throws an error if is not a strip chunk type.
+ ///
+ /// Type to check
+ public static bool CheckStripHasNormals(this PolyChunkType type)
+ {
+ return !type.CheckIsStrip()
+ ? throw new ArgumentException($"Polychunk type \"{type}\" is not a strip chunk type!", nameof(type))
+ : type is PolyChunkType.Strip_Normal
+ or PolyChunkType.Strip_TexNormal
+ or PolyChunkType.Strip_HDTexNormal;
+ }
}
}
diff --git a/src/SA3D.Modeling/Mesh/Chunk/PolyChunks/StripChunk.cs b/src/SA3D.Modeling/Mesh/Chunk/PolyChunks/StripChunk.cs
index 5e07f5e..f87cbf4 100644
--- a/src/SA3D.Modeling/Mesh/Chunk/PolyChunks/StripChunk.cs
+++ b/src/SA3D.Modeling/Mesh/Chunk/PolyChunks/StripChunk.cs
@@ -17,55 +17,22 @@ public class StripChunk : SizedChunk
///
/// The number of texture coordinate sets the polygons utilize.
///
- public int TexcoordCount
- {
- get
- {
- if(Type is PolyChunkType.Strip_Tex
- or PolyChunkType.Strip_HDTex
- or PolyChunkType.Strip_TexNormal
- or PolyChunkType.Strip_HDTexNormal
- or PolyChunkType.Strip_TexColor
- or PolyChunkType.Strip_HDTexColor)
- {
- return 1;
- }
- else if(Type is PolyChunkType.Strip_TexDouble
- or PolyChunkType.Strip_HDTexDouble)
- {
- return 2;
- }
- else
- {
- return 0;
- }
- }
- }
+ public int TexcoordCount => Type.GetStripTexCoordCount();
///
/// Whether texture coordinates are in the 0-1023 range, instead of 0-255.
///
- public bool HasHDTexcoords =>
- Type is PolyChunkType.Strip_HDTex
- or PolyChunkType.Strip_HDTexColor
- or PolyChunkType.Strip_HDTexNormal
- or PolyChunkType.Strip_HDTexDouble;
+ public bool HasHDTexcoords => Type.CheckStripHasHDTexcoords();
///
/// Whether polygons utilize normals.
///
- public bool HasNormals =>
- Type is PolyChunkType.Strip_Normal
- or PolyChunkType.Strip_TexNormal
- or PolyChunkType.Strip_HDTexNormal;
+ public bool HasNormals => Type.CheckStripHasNormals();
///
/// Whether polygons utilize colors.
///
- public bool HasColors =>
- Type is PolyChunkType.Strip_Color
- or PolyChunkType.Strip_TexColor
- or PolyChunkType.Strip_HDTexColor;
+ public bool HasColors => Type.CheckStripHasColors();
#endregion
@@ -222,7 +189,7 @@ public override ushort Size
{
uint result = RawSize;
- if(result > ushort.MaxValue)
+ if(result * 2 > ushort.MaxValue)
{
throw new InvalidOperationException($"Strip chunk size ({result}) exceeds maximum size ({ushort.MaxValue}).");
}
diff --git a/src/SA3D.Modeling/Mesh/Chunk/Structs/ChunkStrip.cs b/src/SA3D.Modeling/Mesh/Chunk/Structs/ChunkStrip.cs
index d82223d..16535ba 100644
--- a/src/SA3D.Modeling/Mesh/Chunk/Structs/ChunkStrip.cs
+++ b/src/SA3D.Modeling/Mesh/Chunk/Structs/ChunkStrip.cs
@@ -9,6 +9,11 @@ namespace SA3D.Modeling.Mesh.Chunk.Structs
///
public struct ChunkStrip : ICloneable
{
+ ///
+ /// Maximum allowed size of a (collection of) strip chunk(s)
+ ///
+ public const uint MaxByteSize = ushort.MaxValue - 4;
+
///
/// Triangle corners.
///
The first two corners are only used for their index.
diff --git a/src/SA3D.Modeling/Mesh/Converters/ChunkConverter.cs b/src/SA3D.Modeling/Mesh/Converters/ChunkConverter.cs
index dacf9f0..d6f6018 100644
--- a/src/SA3D.Modeling/Mesh/Converters/ChunkConverter.cs
+++ b/src/SA3D.Modeling/Mesh/Converters/ChunkConverter.cs
@@ -548,14 +548,6 @@ protected override ChunkResult ConvertWeightless(WeightedMesh wba, bool optimize
private static PolyChunk[] CreateStripChunk(ChunkCorner[] corners, BufferMaterial material, bool writeSpecular, byte texcoordPrecision)
{
- ChunkCorner[][] stripCorners = TriangleStrippifier.Global.StrippifyNoDegen(corners, out bool[] reversed);
- ChunkStrip[] strips = new ChunkStrip[stripCorners.Length];
-
- for(int i = 0; i < strips.Length; i++)
- {
- strips[i] = new(stripCorners[i], reversed[i]);
- }
-
bool hasUV = material.UseTexture && !material.NormalMapping;
PolyChunkType stripType = !hasUV
? PolyChunkType.Strip_Blank
@@ -563,16 +555,47 @@ private static PolyChunk[] CreateStripChunk(ChunkCorner[] corners, BufferMateria
? PolyChunkType.Strip_HDTex
: PolyChunkType.Strip_Tex;
- StripChunk stripchunk = new(stripType, strips, 0)
+ ChunkCorner[][] stripCorners = TriangleStrippifier.Global.StrippifyNoDegen(corners, out bool[] reversed);
+ List stripCollections = [];
+ List currentStrips = [];
+ uint currentStripsSize = 0;
+
+ int stripTexcoordCount = stripType.GetStripTexCoordCount();
+ bool stripHasNormals = stripType.CheckStripHasNormals();
+ bool stripHasColors = stripType.CheckStripHasColors();
+
+ for(int i = 0; i < stripCorners.Length; i++)
{
- FlatShading = material.Flat,
- IgnoreAmbient = material.NoAmbient,
- IgnoreLight = material.NoLighting,
- IgnoreSpecular = material.NoSpecular,
- EnvironmentMapping = material.NormalMapping,
- UseAlpha = material.UseAlpha,
- DoubleSide = !material.BackfaceCulling
- };
+ ChunkStrip strip = new(stripCorners[i], reversed[i]);
+
+ uint stripSize = strip.Size(stripTexcoordCount, stripHasNormals, stripHasColors, 0);
+ if(currentStripsSize + stripSize > ChunkStrip.MaxByteSize)
+ {
+ currentStripsSize = 0;
+ stripCollections.Add([.. currentStrips]);
+ currentStrips.Clear();
+ }
+
+ currentStripsSize += stripSize;
+ currentStrips.Add(strip);
+ }
+
+ stripCollections.Add([.. currentStrips]);
+
+ StripChunk[] stripchunks = new StripChunk[stripCollections.Count];
+ for(int i = 0; i < stripchunks.Length; i++)
+ {
+ stripchunks[i] = new(stripType, stripCollections[i], 0)
+ {
+ FlatShading = material.Flat,
+ IgnoreAmbient = material.NoAmbient,
+ IgnoreLight = material.NoLighting,
+ IgnoreSpecular = material.NoSpecular,
+ EnvironmentMapping = material.NormalMapping,
+ UseAlpha = material.UseAlpha,
+ DoubleSide = !material.BackfaceCulling
+ };
+ }
TextureChunk textureChunk = new()
{
@@ -599,7 +622,7 @@ private static PolyChunk[] CreateStripChunk(ChunkCorner[] corners, BufferMateria
materialChunk.SpecularExponent = (byte)material.SpecularExponent;
}
- return new PolyChunk[] { materialChunk, textureChunk, stripchunk };
+ return [materialChunk, textureChunk, .. stripchunks];
}
protected override void CorrectSpace(Attach attach, Matrix4x4 vertexMatrix, Matrix4x4 normalMatrix)
diff --git a/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Shipped.txt b/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Shipped.txt
index 8a65d26..dac5358 100644
--- a/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Shipped.txt
+++ b/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Shipped.txt
@@ -1846,7 +1846,6 @@ static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckHasSpecularColor(this S
static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckHasWeights(this SA3D.Modeling.Mesh.Chunk.VertexChunkType type) -> bool
static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckIsNormal32(this SA3D.Modeling.Mesh.Chunk.VertexChunkType type) -> bool
static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckIsVec4(this SA3D.Modeling.Mesh.Chunk.VertexChunkType type) -> bool
-static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckStripHasColor(this SA3D.Modeling.Mesh.Chunk.PolyChunkType type) -> bool
static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.GetIntegerSize(this SA3D.Modeling.Mesh.Chunk.VertexChunkType type) -> ushort
static SA3D.Modeling.Mesh.Chunk.PolyChunk.Read(SA3D.Common.IO.EndianStackReader! reader, ref uint address, SA3D.Modeling.Structs.PointerLUT! lut) -> SA3D.Modeling.Mesh.Chunk.PolyChunk!
static SA3D.Modeling.Mesh.Chunk.PolyChunk.ReadArray(SA3D.Common.IO.EndianStackReader! reader, uint address, SA3D.Modeling.Structs.PointerLUT! lut) -> SA3D.Modeling.Mesh.Chunk.PolyChunk?[]!
diff --git a/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Unshipped.txt
index 6ca9704..02a07a0 100644
--- a/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Unshipped.txt
+++ b/src/SA3D.Modeling/PublicAPI/net8.0/PublicAPI.Unshipped.txt
@@ -1,2 +1,8 @@
-SA3D.Modeling.Mesh.Weighted.WeightedMesh.ToAttach(SA3D.Modeling.Mesh.AttachFormat format, bool optimize, out int[]?[]! vertexMapping) -> SA3D.Modeling.Mesh.Attach!
+const SA3D.Modeling.Mesh.Chunk.Structs.ChunkStrip.MaxByteSize = 65531 -> uint
+SA3D.Modeling.Mesh.Weighted.WeightedMesh.ToAttach(SA3D.Modeling.Mesh.AttachFormat format, bool optimize, out int[]?[]! vertexMapping) -> SA3D.Modeling.Mesh.Attach!
+static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckIsStrip(this SA3D.Modeling.Mesh.Chunk.PolyChunkType type) -> bool
+static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckStripHasColors(this SA3D.Modeling.Mesh.Chunk.PolyChunkType type) -> bool
+static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckStripHasHDTexcoords(this SA3D.Modeling.Mesh.Chunk.PolyChunkType type) -> bool
+static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.CheckStripHasNormals(this SA3D.Modeling.Mesh.Chunk.PolyChunkType type) -> bool
+static SA3D.Modeling.Mesh.Chunk.ChunkTypeExtensions.GetStripTexCoordCount(this SA3D.Modeling.Mesh.Chunk.PolyChunkType type) -> int
static SA3D.Modeling.Mesh.Weighted.WeightedMesh.ToModel(SA3D.Modeling.ObjectData.Node! model, SA3D.Modeling.Mesh.Weighted.WeightedMesh![]! meshes, SA3D.Modeling.Mesh.AttachFormat format, bool optimize, out int[]?[]! vertexMapping) -> void
\ No newline at end of file