code refactoring and improvement

add more "Unity" way of handling static object
add RequireComponent to ensure that object have mesh and texture
add some handling of empty texture on objects
removed repetition from code
set all formatting to be the same
This commit is contained in:
aliaksei.kalosha
2025-03-18 01:11:45 +01:00
parent 3e914ac71f
commit e2a9c13fe5
4 changed files with 153 additions and 166 deletions

View File

@@ -104,26 +104,28 @@ namespace SplashEdit.RuntimeCode
// Compute the final shaded color by multiplying the light color by the intensity. // Compute the final shaded color by multiplying the light color by the intensity.
Color shadedColor = lightColor * lightIntensity; Color shadedColor = lightColor * lightIntensity;
static short clampPosition(float v) => (short)(Mathf.Clamp(v, -4f, 3.999f) * 4096);
static byte clamp0255(float v) => (byte)(Mathf.Clamp(v, 0, 255));
PSXVertex psxVertex = new PSXVertex PSXVertex psxVertex = new PSXVertex
{ {
// Convert position to fixed-point, clamping values to a defined range. // Convert position to fixed-point, clamping values to a defined range.
vx = (short)(Mathf.Clamp(vertex.x, -4f, 3.999f) * 4096), vx = clampPosition(vertex.x),
vy = (short)(Mathf.Clamp(-vertex.y, -4f, 3.999f) * 4096), vy = clampPosition(-vertex.y),
vz = (short)(Mathf.Clamp(vertex.z, -4f, 3.999f) * 4096), vz = clampPosition(vertex.z),
// Convert normals to fixed-point. // Convert normals to fixed-point.
nx = (short)(Mathf.Clamp(normal.x, -4f, 3.999f) * 4096), nx = clampPosition(normal.x),
ny = (short)(Mathf.Clamp(-normal.y, -4f, 3.999f) * 4096), ny = clampPosition(-normal.y),
nz = (short)(Mathf.Clamp(normal.z, -4f, 3.999f) * 4096), nz = clampPosition(normal.z),
// Map UV coordinates to a byte range after scaling based on texture dimensions. // Map UV coordinates to a byte range after scaling based on texture dimensions.
u = (byte)(Mathf.Clamp((uv.x * (textureWidth - 1)), 0, 255)), u = clamp0255(uv.x * (textureWidth - 1)),
v = (byte)(Mathf.Clamp(((1.0f - uv.y) * (textureHeight - 1)), 0, 255)), v = clamp0255((1.0f - uv.y) * (textureHeight - 1)),
// Convert the computed color to a byte range. // Convert the computed color to a byte range.
r = (byte)(Mathf.Clamp(shadedColor.r * 255, 0, 255)), r = clamp0255(shadedColor.r * 255),
g = (byte)(Mathf.Clamp(shadedColor.g * 255, 0, 255)), g = clamp0255(shadedColor.g * 255),
b = (byte)(Mathf.Clamp(shadedColor.b * 255, 0, 255)) b = clamp0255(shadedColor.b * 255)
}; };
return psxVertex; return psxVertex;

View File

@@ -2,16 +2,14 @@ using UnityEngine;
namespace SplashEdit.RuntimeCode namespace SplashEdit.RuntimeCode
{ {
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(Renderer))]
public class PSXObjectExporter : MonoBehaviour public class PSXObjectExporter : MonoBehaviour
{ {
public PSXBPP BitDepth = PSXBPP.TEX_8BIT; // Defines the bit depth of the texture (e.g., 4BPP, 8BPP) public PSXBPP BitDepth = PSXBPP.TEX_8BIT; // Defines the bit depth of the texture (e.g., 4BPP, 8BPP)
public bool MeshIsStatic = true; // Determines if the mesh is static, affecting how it's processed. Non-static meshes don't export correctly as of now.
[HideInInspector] public PSXTexture2D Texture { get; set; } // Stores the converted PlayStation-style texture
public PSXTexture2D Texture; // Stores the converted PlayStation-style texture public PSXMesh Mesh { get; set; } // Stores the converted PlayStation-style mesh
[HideInInspector]
public PSXMesh Mesh; // Stores the converted PlayStation-style mesh
/// <summary> /// <summary>
/// Converts the object's material texture into a PlayStation-compatible texture. /// Converts the object's material texture into a PlayStation-compatible texture.
@@ -19,11 +17,22 @@ namespace SplashEdit.RuntimeCode
public void CreatePSXTexture2D() public void CreatePSXTexture2D()
{ {
Renderer renderer = GetComponent<Renderer>(); Renderer renderer = GetComponent<Renderer>();
if (renderer != null && renderer.sharedMaterial != null && renderer.sharedMaterial.mainTexture is Texture2D texture) if (renderer.sharedMaterial != null && renderer.sharedMaterial.mainTexture is Texture2D texture)
{ {
Texture = PSXTexture2D.CreateFromTexture2D(texture, BitDepth); Texture = PSXTexture2D.CreateFromTexture2D(texture, BitDepth);
Texture.OriginalTexture = texture; // Stores reference to the original texture Texture.OriginalTexture = texture; // Stores reference to the original texture
} }
else
{
//TODO: Better handle object with default texture
Texture = new PSXTexture2D()
{
BitDepth = BitDepth,
Width = 0,
Height = 0,
};
Texture.OriginalTexture = null;
}
} }
/// <summary> /// <summary>
@@ -31,10 +40,8 @@ namespace SplashEdit.RuntimeCode
/// </summary> /// </summary>
public void CreatePSXMesh() public void CreatePSXMesh()
{ {
MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>(); MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter != null) if (gameObject.isStatic)
{
if (MeshIsStatic)
{ {
// Static meshes take object transformation into account // Static meshes take object transformation into account
Mesh = PSXMesh.CreateFromUnityMesh(meshFilter.sharedMesh, Texture.Width, Texture.Height, transform); Mesh = PSXMesh.CreateFromUnityMesh(meshFilter.sharedMesh, Texture.Width, Texture.Height, transform);
@@ -47,4 +54,3 @@ namespace SplashEdit.RuntimeCode
} }
} }
} }
}

View File

@@ -85,47 +85,26 @@ namespace SplashEdit.RuntimeCode
writer.Write((ushort)exporter.Texture.ClutPackingX); writer.Write((ushort)exporter.Texture.ClutPackingX);
writer.Write((ushort)exporter.Texture.ClutPackingY); writer.Write((ushort)exporter.Texture.ClutPackingY);
writer.Write((byte)0); writer.Write((byte)0);
void writePSXVertex(PSXVertex vertex)
{
writer.Write((short)vertex.vx);
writer.Write((short)vertex.vy);
writer.Write((short)vertex.vz);
writer.Write((short)vertex.nx);
writer.Write((short)vertex.ny);
writer.Write((short)vertex.nz);
writer.Write((byte)(vertex.u + exporter.Texture.PackingX * expander));
writer.Write((byte)(vertex.v + exporter.Texture.PackingY));
writer.Write((byte)vertex.r);
writer.Write((byte)vertex.g);
writer.Write((byte)vertex.b);
for (int i = 0; i < 7; i++) writer.Write((byte)0);
}
foreach (Tri tri in exporter.Mesh.Triangles) foreach (Tri tri in exporter.Mesh.Triangles)
{ {
writer.Write((short)tri.v0.vx); writePSXVertex(tri.v0);
writer.Write((short)tri.v0.vy); writePSXVertex(tri.v1);
writer.Write((short)tri.v0.vz); writePSXVertex(tri.v2);
writer.Write((short)tri.v0.nx);
writer.Write((short)tri.v0.ny);
writer.Write((short)tri.v0.nz);
writer.Write((byte)(tri.v0.u + exporter.Texture.PackingX * expander));
writer.Write((byte)(tri.v0.v + exporter.Texture.PackingY));
writer.Write((byte) tri.v0.r);
writer.Write((byte) tri.v0.g);
writer.Write((byte) tri.v0.b);
for(int i = 0; i < 7; i ++) writer.Write((byte) 0);
writer.Write((short)tri.v1.vx);
writer.Write((short)tri.v1.vy);
writer.Write((short)tri.v1.vz);
writer.Write((short)tri.v1.nx);
writer.Write((short)tri.v1.ny);
writer.Write((short)tri.v1.nz);
writer.Write((byte)(tri.v1.u + exporter.Texture.PackingX * expander));
writer.Write((byte)(tri.v1.v + exporter.Texture.PackingY));
writer.Write((byte) tri.v1.r);
writer.Write((byte) tri.v1.g);
writer.Write((byte) tri.v1.b);
for(int i = 0; i < 7; i ++) writer.Write((byte) 0);
writer.Write((short)tri.v2.vx);
writer.Write((short)tri.v2.vy);
writer.Write((short)tri.v2.vz);
writer.Write((short)tri.v2.nx);
writer.Write((short)tri.v2.ny);
writer.Write((short)tri.v2.nz);
writer.Write((byte)(tri.v2.u + exporter.Texture.PackingX * expander));
writer.Write((byte)(tri.v2.v + exporter.Texture.PackingY));
writer.Write((byte) tri.v2.r);
writer.Write((byte) tri.v2.g);
writer.Write((byte) tri.v2.b);
for(int i = 0; i < 7; i ++) writer.Write((byte) 0);
} }
} }
} }

View File

@@ -87,7 +87,7 @@ namespace SplashEdit.RuntimeCode
foreach (var obj in group.OrderByDescending(obj => obj.Texture.QuantizedWidth * obj.Texture.Height)) foreach (var obj in group.OrderByDescending(obj => obj.Texture.QuantizedWidth * obj.Texture.Height))
{ {
// Remove duplicate textures // Remove duplicate textures
if (uniqueTextures.Any(tex => tex.OriginalTexture.GetInstanceID() == obj.Texture.OriginalTexture.GetInstanceID() && tex.BitDepth == obj.Texture.BitDepth)) if (uniqueTextures.Where(tex => tex.OriginalTexture != null).Any(tex => tex.OriginalTexture.GetInstanceID() == obj.Texture.OriginalTexture.GetInstanceID() && tex.BitDepth == obj.Texture.BitDepth))
{ {
obj.Texture = uniqueTextures.First(tex => tex.OriginalTexture.GetInstanceID() == obj.Texture.OriginalTexture.GetInstanceID()); obj.Texture = uniqueTextures.First(tex => tex.OriginalTexture.GetInstanceID() == obj.Texture.OriginalTexture.GetInstanceID());
continue; continue;