diff --git a/Editor/PSXNavMeshEditor.cs b/Editor/PSXNavMeshEditor.cs new file mode 100644 index 0000000..6caebda --- /dev/null +++ b/Editor/PSXNavMeshEditor.cs @@ -0,0 +1,31 @@ +using UnityEngine; +using UnityEditor; +using SplashEdit.RuntimeCode; +using System.Linq; + +namespace SplashEdit.EditorCode +{ + [CustomEditor(typeof(PSXNavMesh))] + public class PSXNavMeshEditor : Editor + { + public override void OnInspectorGUI() + { + DrawDefaultInspector(); + + PSXNavMesh comp = (PSXNavMesh)target; + if (GUILayout.Button("Create preview")) + { + PSXSceneExporter exporter = FindObjectsByType(FindObjectsSortMode.None).FirstOrDefault(); + if(exporter != null) + { + comp.CreateNavmesh(exporter.GTEScaling); + } + else + { + Debug.LogError("No PSXSceneExporter found in the scene. We can't pull the GTE scaling from the exporter."); + } + } + + } + } +} \ No newline at end of file diff --git a/Editor/PSXNavMeshEditor.cs.meta b/Editor/PSXNavMeshEditor.cs.meta new file mode 100644 index 0000000..5a8298d --- /dev/null +++ b/Editor/PSXNavMeshEditor.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9d3bd83aac4c3ce9ab1698a6a2bc735d \ No newline at end of file diff --git a/Icons/PSXNavmesh.png b/Icons/PSXNavmesh.png new file mode 100644 index 0000000..0b07dfb Binary files /dev/null and b/Icons/PSXNavmesh.png differ diff --git a/Icons/PSXNavmesh.png.meta b/Icons/PSXNavmesh.png.meta new file mode 100644 index 0000000..5a379be --- /dev/null +++ b/Icons/PSXNavmesh.png.meta @@ -0,0 +1,130 @@ +fileFormatVersion: 2 +guid: d695ef52da250cdcea6c30ab1122c56e +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Icons/PSXPlayer.png b/Icons/PSXPlayer.png new file mode 100644 index 0000000..ef0d609 Binary files /dev/null and b/Icons/PSXPlayer.png differ diff --git a/Icons/PSXPlayer.png.meta b/Icons/PSXPlayer.png.meta new file mode 100644 index 0000000..d3d9874 --- /dev/null +++ b/Icons/PSXPlayer.png.meta @@ -0,0 +1,130 @@ +fileFormatVersion: 2 +guid: 4d7bd095e76e6f3df976224b15405059 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/PSXNavMesh.cs b/Runtime/PSXNavMesh.cs index a8c9e5f..332263a 100644 --- a/Runtime/PSXNavMesh.cs +++ b/Runtime/PSXNavMesh.cs @@ -3,7 +3,6 @@ using Unity.AI.Navigation; using UnityEngine.AI; using System.Collections.Generic; - namespace SplashEdit.RuntimeCode { public struct PSXNavMeshTri @@ -20,23 +19,35 @@ namespace SplashEdit.RuntimeCode public class PSXNavMesh : MonoBehaviour { + Mesh mesh; + [HideInInspector] public List Navmesh { get; set; } public void CreateNavmesh(float GTEScaling) { + mesh = new Mesh(); Navmesh = new List(); NavMeshSurface navMeshSurface = GetComponent(); + navMeshSurface.overrideTileSize = true; + navMeshSurface.tileSize = 16; + navMeshSurface.overrideVoxelSize = true; + navMeshSurface.voxelSize = 0.1f; navMeshSurface.BuildNavMesh(); NavMeshTriangulation triangulation = NavMesh.CalculateTriangulation(); + navMeshSurface.overrideTileSize = false; + navMeshSurface.overrideVoxelSize = false; int[] triangles = triangulation.indices; Vector3[] vertices = triangulation.vertices; + mesh.vertices = vertices; + mesh.triangles = triangles; + + mesh.RecalculateNormals(); + for (int i = 0; i < triangles.Length; i += 3) { - - int vid0 = triangles[i]; int vid1 = triangles[i + 1]; int vid2 = triangles[i + 2]; @@ -58,5 +69,27 @@ namespace SplashEdit.RuntimeCode Navmesh.Add(tri); } } + + + public void OnDrawGizmos() + { + if (mesh == null) return; + Gizmos.DrawMesh(mesh); + Gizmos.color = Color.green; + + var vertices = mesh.vertices; + var triangles = mesh.triangles; + + for (int i = 0; i < triangles.Length; i += 3) + { + Vector3 v0 = vertices[triangles[i]]; + Vector3 v1 = vertices[triangles[i + 1]]; + Vector3 v2 = vertices[triangles[i + 2]]; + + Gizmos.DrawLine(v0, v1); + Gizmos.DrawLine(v1, v2); + Gizmos.DrawLine(v2, v0); + } + } } } \ No newline at end of file diff --git a/Runtime/PSXNavMesh.cs.meta b/Runtime/PSXNavMesh.cs.meta index 142f03a..00c207d 100644 --- a/Runtime/PSXNavMesh.cs.meta +++ b/Runtime/PSXNavMesh.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 6a2f8d45e1591de1e945b3b7bdfb123b \ No newline at end of file +guid: 6a2f8d45e1591de1e945b3b7bdfb123b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: d695ef52da250cdcea6c30ab1122c56e, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/PSXPlayer.cs b/Runtime/PSXPlayer.cs new file mode 100644 index 0000000..32600d2 --- /dev/null +++ b/Runtime/PSXPlayer.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using UnityEngine.AI; + + +namespace SplashEdit.RuntimeCode +{ + public class PSXPlayer : MonoBehaviour + { + public float PlayerHeight; + + [HideInInspector] + public Vector3 camPoint; + float maxDistance = 1000f; + + public void FindNavmesh() + { + NavMeshHit hit; + if (NavMesh.SamplePosition(transform.position, out hit, maxDistance, NavMesh.AllAreas)) + { + camPoint = hit.position + new Vector3(0, PlayerHeight, 0); + } + } + void OnDrawGizmos() + { + FindNavmesh(); + Gizmos.color = Color.red; + Gizmos.DrawSphere(camPoint, 0.2f); + } + } +} diff --git a/Runtime/PSXPlayer.cs.meta b/Runtime/PSXPlayer.cs.meta new file mode 100644 index 0000000..7245d08 --- /dev/null +++ b/Runtime/PSXPlayer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dee32f3a19300d7a3aae7424f01c9332 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 4d7bd095e76e6f3df976224b15405059, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/PSXSceneExporter.cs b/Runtime/PSXSceneExporter.cs index a42e9d6..ee790db 100644 --- a/Runtime/PSXSceneExporter.cs +++ b/Runtime/PSXSceneExporter.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using JetBrains.Annotations; using UnityEditor; using UnityEngine; using UnityEngine.AI; @@ -26,6 +27,10 @@ namespace SplashEdit.RuntimeCode private bool verticalLayout; private List prohibitedAreas; + private Vector3 _playerPos; + private Quaternion _playerRot; + private float _playerHeight; + public void Export() { _psxData = DataStorage.LoadData(out selectedResolution, out dualBuffering, out verticalLayout, out prohibitedAreas); @@ -44,6 +49,21 @@ namespace SplashEdit.RuntimeCode } PackTextures(); + + PSXPlayer player = FindObjectsByType(FindObjectsSortMode.None).FirstOrDefault(); + if (player != null) + { + player.FindNavmesh(); + _playerPos = player.camPoint; + _playerHeight = player.PlayerHeight; + _playerRot = player.transform.rotation; + } + else + { + Debug.LogError("Can't export a scene without a Player created"); + return; + } + ExportFile(); } @@ -103,14 +123,24 @@ namespace SplashEdit.RuntimeCode using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create))) { // Header - writer.Write('S'); // 1 byte - writer.Write('P'); // 1 byte - writer.Write((ushort)1); // 2 bytes - version - writer.Write((ushort)_exporters.Length); // 2 bytes - writer.Write((ushort)_navmeshes.Length); - writer.Write((ushort)_atlases.Length); // 2 bytes - writer.Write((ushort)clutCount); // 2 bytes - for (int i = 0; i < 2; i++) writer.Write((ushort)0); + writer.Write('S'); // 1 byte // 1 + writer.Write('P'); // 1 byte // 2 + writer.Write((ushort)1); // 2 bytes - version // 4 + writer.Write((ushort)_exporters.Length); // 2 bytes // 6 + writer.Write((ushort)_navmeshes.Length); // 8 + writer.Write((ushort)_atlases.Length); // 2 bytes // 10 + writer.Write((ushort)clutCount); // 2 bytes // 12 + writer.Write((ushort)PSXTrig.ConvertCoordinateToPSX(_playerPos.x, GTEScaling)); // 14 + writer.Write((ushort)PSXTrig.ConvertCoordinateToPSX(-_playerPos.y, GTEScaling)); // 16 + writer.Write((ushort)PSXTrig.ConvertCoordinateToPSX(_playerPos.z, GTEScaling)); // 18 + + writer.Write((ushort)PSXTrig.ConvertToFixed12(_playerRot.eulerAngles.x * Mathf.Deg2Rad)); // 20 + writer.Write((ushort)PSXTrig.ConvertToFixed12(_playerRot.eulerAngles.y * Mathf.Deg2Rad)); // 22 + writer.Write((ushort)PSXTrig.ConvertToFixed12(_playerRot.eulerAngles.z * Mathf.Deg2Rad)); // 24 + + writer.Write((ushort)PSXTrig.ConvertCoordinateToPSX(_playerHeight, GTEScaling)); // 26 + + writer.Write((ushort)0); // GameObject section (exporters) foreach (PSXObjectExporter exporter in _exporters) @@ -253,23 +283,25 @@ namespace SplashEdit.RuntimeCode } } - foreach (PSXNavMesh navmesh in _navmeshes) { + foreach (PSXNavMesh navmesh in _navmeshes) + { AlignToFourBytes(writer); long navmeshDataOffset = writer.BaseStream.Position; navmeshDataOffsets.Add(navmeshDataOffset); - foreach(PSXNavMeshTri tri in navmesh.Navmesh) { - writer.Write((ushort) tri.v0.vx); - writer.Write((ushort) tri.v0.vy); - writer.Write((ushort) tri.v0.vz); + foreach (PSXNavMeshTri tri in navmesh.Navmesh) + { + writer.Write((int)tri.v0.vx); + writer.Write((int)tri.v0.vy); + writer.Write((int)tri.v0.vz); - writer.Write((ushort) tri.v1.vx); - writer.Write((ushort) tri.v1.vy); - writer.Write((ushort) tri.v1.vz); + writer.Write((int)tri.v1.vx); + writer.Write((int)tri.v1.vy); + writer.Write((int)tri.v1.vz); - writer.Write((ushort) tri.v2.vx); - writer.Write((ushort) tri.v2.vy); - writer.Write((ushort) tri.v2.vz); + writer.Write((int)tri.v2.vx); + writer.Write((int)tri.v2.vy); + writer.Write((int)tri.v2.vz); } } diff --git a/Runtime/Utils.cs b/Runtime/Utils.cs index bbe32e2..bf9c30f 100644 --- a/Runtime/Utils.cs +++ b/Runtime/Utils.cs @@ -1,6 +1,7 @@ using UnityEditor; using System.Collections.Generic; using UnityEngine; +using System.Linq; namespace SplashEdit.RuntimeCode { @@ -330,7 +331,8 @@ namespace SplashEdit.RuntimeCode } - public static byte ColorUnityToPSX(float v) => (byte)(Mathf.Clamp(v*255, 0, 255)); + public static byte ColorUnityToPSX(float v) => (byte)(Mathf.Clamp(v * 255, 0, 255)); } + }