Splashpack fixes, added GTE scaling option

This commit is contained in:
2025-03-23 00:05:33 +01:00
parent 0d639acf78
commit 1e4f5673e8
5 changed files with 44 additions and 62 deletions

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Diagnostics;
namespace SplashEdit.RuntimeCode
{
@@ -44,7 +45,7 @@ namespace SplashEdit.RuntimeCode
/// <param name="textureHeight">Height of the texture (default is 256).</param>
/// <param name="transform">Optional transform to convert vertices to world space.</param>
/// <returns>A new PSXMesh containing the converted triangles.</returns>
public static PSXMesh CreateFromUnityMesh(Mesh mesh, int textureWidth = 256, int textureHeight = 256, Transform transform = null)
public static PSXMesh CreateFromUnityMesh(Mesh mesh, float GTEScaling, int textureWidth = 256, int textureHeight = 256, Transform transform = null)
{
PSXMesh psxMesh = new PSXMesh { Triangles = new List<Tri>() };
@@ -72,9 +73,9 @@ namespace SplashEdit.RuntimeCode
Vector3 v2 = transform ? transform.TransformPoint(vertices[vid2]) : vertices[vid2];
// Convert vertices to PSX format including fixed-point conversion and shading.
PSXVertex psxV0 = ConvertToPSXVertex(v0, normals[vid0], uv[vid0], lightDir, lightColor, textureWidth, textureHeight);
PSXVertex psxV1 = ConvertToPSXVertex(v1, normals[vid1], uv[vid1], lightDir, lightColor, textureWidth, textureHeight);
PSXVertex psxV2 = ConvertToPSXVertex(v2, normals[vid2], uv[vid2], lightDir, lightColor, textureWidth, textureHeight);
PSXVertex psxV0 = ConvertToPSXVertex(v0, GTEScaling, normals[vid0], uv[vid0], lightDir, lightColor, textureWidth, textureHeight);
PSXVertex psxV1 = ConvertToPSXVertex(v1, GTEScaling, normals[vid1], uv[vid1], lightDir, lightColor, textureWidth, textureHeight);
PSXVertex psxV2 = ConvertToPSXVertex(v2, GTEScaling, normals[vid2], uv[vid2], lightDir, lightColor, textureWidth, textureHeight);
// Add the constructed triangle to the mesh.
psxMesh.Triangles.Add(new Tri { v0 = psxV0, v1 = psxV1, v2 = psxV2 });
@@ -94,12 +95,10 @@ namespace SplashEdit.RuntimeCode
/// <param name="textureWidth">Width of the texture for UV scaling.</param>
/// <param name="textureHeight">Height of the texture for UV scaling.</param>
/// <returns>A PSXVertex with converted coordinates, normals, UVs, and color.</returns>
private static PSXVertex ConvertToPSXVertex(Vector3 vertex, Vector3 normal, Vector2 uv, Vector3 lightDir, Color lightColor, int textureWidth, int textureHeight)
private static PSXVertex ConvertToPSXVertex(Vector3 vertex, float GTEScaling, Vector3 normal, Vector2 uv, Vector3 lightDir, Color lightColor, int textureWidth, int textureHeight)
{
// Calculate light intensity based on the angle between the normalized normal and light direction.
float lightIntensity = Mathf.Clamp01(Vector3.Dot(normal.normalized, lightDir));
// Remap the intensity to a specific range for a softer shading effect.
lightIntensity = Mathf.Lerp(0.4f, 0.7f, lightIntensity);
// Compute the final shaded color by multiplying the light color by the intensity.
Color shadedColor = lightColor * lightIntensity;
@@ -107,14 +106,14 @@ namespace SplashEdit.RuntimeCode
PSXVertex psxVertex = new PSXVertex
{
// Convert position to fixed-point, clamping values to a defined range.
vx = (short)(Mathf.Clamp(vertex.x, -4f, 3.999f) * 4096),
vy = (short)(Mathf.Clamp(-vertex.y, -4f, 3.999f) * 4096),
vz = (short)(Mathf.Clamp(vertex.z, -4f, 3.999f) * 4096),
vx = (short)PSXTrig.ConvertCoordinateToPSX(vertex.x, GTEScaling),
vy = (short)PSXTrig.ConvertCoordinateToPSX(-vertex.y, GTEScaling),
vz = (short)PSXTrig.ConvertCoordinateToPSX(vertex.z, GTEScaling),
// Convert normals to fixed-point.
nx = (short)(Mathf.Clamp(normal.x, -4f, 3.999f) * 4096),
ny = (short)(Mathf.Clamp(-normal.y, -4f, 3.999f) * 4096),
nz = (short)(Mathf.Clamp(normal.z, -4f, 3.999f) * 4096),
nx = (short)PSXTrig.ConvertCoordinateToPSX(normal.x),
ny = (short)PSXTrig.ConvertCoordinateToPSX(-normal.y),
nz = (short)PSXTrig.ConvertCoordinateToPSX(normal.z),
// Map UV coordinates to a byte range after scaling based on texture dimensions.
u = (byte)(Mathf.Clamp((uv.x * (textureWidth - 1)), 0, 255)),

View File

@@ -29,7 +29,7 @@ namespace SplashEdit.RuntimeCode
/// <summary>
/// Converts the object's mesh into a PlayStation-compatible mesh.
/// </summary>
public void CreatePSXMesh()
public void CreatePSXMesh(float GTEScaling)
{
MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>();
if (meshFilter != null)
@@ -37,12 +37,12 @@ namespace SplashEdit.RuntimeCode
if (MeshIsStatic)
{
// Static meshes take object transformation into account
Mesh = PSXMesh.CreateFromUnityMesh(meshFilter.sharedMesh, Texture.Width, Texture.Height, transform);
Mesh = PSXMesh.CreateFromUnityMesh(meshFilter.sharedMesh, GTEScaling, Texture.Width, Texture.Height, transform);
}
else
{
// Dynamic meshes do not consider object transformation
Mesh = PSXMesh.CreateFromUnityMesh(meshFilter.sharedMesh, Texture.Width, Texture.Height);
Mesh = PSXMesh.CreateFromUnityMesh(meshFilter.sharedMesh, GTEScaling, Texture.Width, Texture.Height);
}
}
}

View File

@@ -1,13 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Overlays;
using UnityEngine;
using UnityEngine.Diagnostics;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore.Text;
namespace SplashEdit.RuntimeCode
{
@@ -15,6 +9,9 @@ namespace SplashEdit.RuntimeCode
[ExecuteInEditMode]
public class PSXSceneExporter : MonoBehaviour
{
public float GTEScaling = 100.0f;
private PSXObjectExporter[] _exporters;
private TextureAtlas[] _atlases;
@@ -36,7 +33,7 @@ namespace SplashEdit.RuntimeCode
foreach (PSXObjectExporter exp in _exporters)
{
exp.CreatePSXTexture2D();
exp.CreatePSXMesh();
exp.CreatePSXMesh(GTEScaling);
}
PackTextures();
ExportFile();
@@ -107,17 +104,17 @@ namespace SplashEdit.RuntimeCode
// Set up texture page attributes
TPageAttr tpage = new TPageAttr();
tpage.SetPageX(exporter.Texture.TexpageX);
tpage.SetPageX(exporter.Texture.TexpageY);
tpage.SetPageY(exporter.Texture.TexpageY);
switch (exporter.Texture.BitDepth)
{
case PSXBPP.TEX_4BIT:
tpage.Set(ColorMode.Mode4Bit);
tpage.Set(TPageAttr.ColorMode.Mode4Bit);
break;
case PSXBPP.TEX_8BIT:
tpage.Set(ColorMode.Mode8Bit);
tpage.Set(TPageAttr.ColorMode.Mode8Bit);
break;
case PSXBPP.TEX_16BIT:
tpage.Set(ColorMode.Mode16Bit);
tpage.Set(TPageAttr.ColorMode.Mode16Bit);
break;
}
tpage.SetDithering(true);
@@ -282,6 +279,10 @@ namespace SplashEdit.RuntimeCode
void OnDrawGizmos()
{
Gizmos.DrawIcon(transform.position, "Packages/net.psxsplash.splashedit/Icons/PSXSceneExporter.png", true);
Vector3 sceneOrigin = new Vector3(0,0,0);
Vector3 cubeSize = new Vector3(8.0f * GTEScaling, 8.0f * GTEScaling, 8.0f * GTEScaling);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(sceneOrigin, cubeSize);
}
}
}

View File

@@ -299,19 +299,5 @@ namespace SplashEdit.RuntimeCode
return !(overlapsAtlas || overlapsReserved || overlapsCLUT);
}
/// <summary>
/// Calculates the texpage index from given VRAM coordinates.
/// This helper method divides VRAM into columns and rows.
/// </summary>
/// <param name="x">The X coordinate in VRAM.</param>
/// <param name="y">The Y coordinate in VRAM.</param>
/// <returns>The calculated texpage index.</returns>
private int CalculateTexpage(int x, int y)
{
int columns = 16;
int colIndex = x / 64;
int rowIndex = y / 256;
return (rowIndex * columns) + colIndex;
}
}
}

View File

@@ -45,15 +45,11 @@ namespace SplashEdit.RuntimeCode
public static class PSXTrig
{
public static short ConvertCoordinateToPSX(float value)
public static short ConvertCoordinateToPSX(float value, float GTEScaling = 1.0f)
{
return (short)(Mathf.Clamp(value, -4f, 3.999f) * 4096);
return (short)(Mathf.Clamp(value/GTEScaling, -4f, 3.999f) * 4096);
}
public static short ConvertRadiansToPSX(float value)
{
return (short)(Mathf.Clamp(value, -4f, 3.999f) * 4096f / Mathf.PI);
}
public static int[,] ConvertRotationToPSXMatrix(Quaternion rotation)
{
@@ -142,23 +138,23 @@ namespace SplashEdit.RuntimeCode
}
public override string ToString() => $"Info: 0x{info:X4}";
}
// Define the enums for SemiTrans and ColorMode (assuming their values)
public enum SemiTrans : uint
{
None = 0,
Type1 = 1,
Type2 = 2,
Type3 = 3
}
public enum ColorMode : uint
{
Mode4Bit = 0,
Mode8Bit = 1,
Mode16Bit = 2
}
// Define the enums for SemiTrans and ColorMode (assuming their values)
public enum SemiTrans : uint
{
None = 0,
Type1 = 1,
Type2 = 2,
Type3 = 3
}
public enum ColorMode : uint
{
Mode4Bit = 0,
Mode8Bit = 1,
Mode16Bit = 2
}
}
}