Init
This commit is contained in:
3
Assets/MindPowerSdk/Base.meta
generated
Normal file
3
Assets/MindPowerSdk/Base.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96c1ada894b449fcb2c8f293e3a01f7c
|
||||
timeCreated: 1727962178
|
7
Assets/MindPowerSdk/Base/GlobalDefiens.cs
Normal file
7
Assets/MindPowerSdk/Base/GlobalDefiens.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public static class GlobalDefine
|
||||
{
|
||||
public static string ClientDir = "";
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/Base/GlobalDefiens.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/Base/GlobalDefiens.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fc62595d74a4f958f1aaed2f48adb47
|
||||
timeCreated: 1727962264
|
51
Assets/MindPowerSdk/Base/StructReader.cs
Normal file
51
Assets/MindPowerSdk/Base/StructReader.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public static class StructReader
|
||||
{
|
||||
public static T ReadStruct<T>(BinaryReader reader)
|
||||
{
|
||||
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
|
||||
|
||||
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
|
||||
handle.Free();
|
||||
|
||||
return theStructure;
|
||||
}
|
||||
|
||||
public static T ReadStructFromArray<T>(byte[] bytes)
|
||||
{
|
||||
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
|
||||
handle.Free();
|
||||
return theStructure;
|
||||
}
|
||||
|
||||
public static T[] ReadStructArray<T>(BinaryReader reader, int size)
|
||||
{
|
||||
T[] theStructures = new T[size];
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
theStructures[i] = ReadStruct<T>(reader);
|
||||
}
|
||||
|
||||
return theStructures;
|
||||
}
|
||||
|
||||
public static T[] ReadStructArray<T>(BinaryReader reader, uint size)
|
||||
{
|
||||
T[] theStructures = new T[size];
|
||||
|
||||
for (uint i = 0; i < size; i++)
|
||||
{
|
||||
theStructures[i] = ReadStruct<T>(reader);
|
||||
}
|
||||
|
||||
return theStructures;
|
||||
}
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/Base/StructReader.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/Base/StructReader.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 635ded6c26144e1b85bd47293dd9409d
|
||||
timeCreated: 1727962573
|
3
Assets/MindPowerSdk/EditorWindow.meta
generated
Normal file
3
Assets/MindPowerSdk/EditorWindow.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7eb44d88e1ac484a89b4c0f2b1b3dedd
|
||||
timeCreated: 1743586822
|
292
Assets/MindPowerSdk/EditorWindow/MapDataEditorWindow.cs
Normal file
292
Assets/MindPowerSdk/EditorWindow/MapDataEditorWindow.cs
Normal file
@ -0,0 +1,292 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 地图生成工具窗口,用于配置地图数据参数、材质映射,以及生成、清除、保存地图到预制体。
|
||||
/// 注意:每个地图配置项对应一个 MapName 与资源数据名称组合生成一个地图。
|
||||
/// </summary>
|
||||
public class MapGeneratorEditorWindow : EditorWindow
|
||||
{
|
||||
// 文件夹路径设置
|
||||
private string mapDataFolder = "";
|
||||
private string resourceDataFolder = "";
|
||||
|
||||
// 地图数据配置:每个地图对应一个名称与数据资源名称
|
||||
private List<MapInfoEntry> mapEntries = new List<MapInfoEntry>();
|
||||
|
||||
// 其他地图参数
|
||||
private int chunkSize = 64;
|
||||
private Material terrainMaterial;
|
||||
|
||||
// 材质映射设置(草、树等),关键字支持多个,用逗号分隔
|
||||
private List<MaterialMappingEntry> materialMappings = new List<MaterialMappingEntry>();
|
||||
|
||||
// 生成地图时的父物体名称
|
||||
private const string GENERATED_MAPS_PARENT = "GeneratedMaps";
|
||||
|
||||
[MenuItem("Tools/地图生成工具")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
GetWindow<MapGeneratorEditorWindow>("地图生成工具");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// 初始化默认数据
|
||||
if (mapEntries == null) mapEntries = new List<MapInfoEntry>();
|
||||
if (materialMappings == null) materialMappings = new List<MaterialMappingEntry>();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUILayout.Label("文件夹路径设置", EditorStyles.boldLabel);
|
||||
// 数据源文件夹选择
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
mapDataFolder = EditorGUILayout.TextField("数据源文件夹", mapDataFolder);
|
||||
if (GUILayout.Button("选择", GUILayout.Width(60)))
|
||||
{
|
||||
string folder = EditorUtility.OpenFolderPanel("选择数据源文件夹", "", "");
|
||||
if (!string.IsNullOrEmpty(folder))
|
||||
{
|
||||
mapDataFolder = folder;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// 资源数据文件夹选择
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
resourceDataFolder = EditorGUILayout.TextField("资源数据文件夹", resourceDataFolder);
|
||||
if (GUILayout.Button("选择", GUILayout.Width(60)))
|
||||
{
|
||||
string folder = EditorUtility.OpenFolderPanel("选择资源数据文件夹", "", "");
|
||||
if (!string.IsNullOrEmpty(folder))
|
||||
{
|
||||
resourceDataFolder = folder;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.Label("地图数据配置 (每个配置项对应一个地图)", EditorStyles.boldLabel);
|
||||
// 列表显示地图配置项
|
||||
for (int i = 0; i < mapEntries.Count; i++)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
mapEntries[i].mapName = EditorGUILayout.TextField("Map 名称", mapEntries[i].mapName);
|
||||
mapEntries[i].resourceDataName = EditorGUILayout.TextField("资源名称", mapEntries[i].resourceDataName);
|
||||
mapEntries[i].isSmoothing = EditorGUILayout.Toggle("对地形平滑处理", mapEntries[i].isSmoothing);
|
||||
if (GUILayout.Button("删除", GUILayout.Width(60)))
|
||||
{
|
||||
mapEntries.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("添加地图配置"))
|
||||
{
|
||||
mapEntries.Add(new MapInfoEntry());
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.Label("地图其他参数", EditorStyles.boldLabel);
|
||||
chunkSize = EditorGUILayout.IntField("Chunk Size", chunkSize);
|
||||
terrainMaterial =
|
||||
(Material)EditorGUILayout.ObjectField("Terrain Material", terrainMaterial, typeof(Material), false);
|
||||
|
||||
GUILayout.Space(10);
|
||||
GUILayout.Label("材质映射配置 (草、树等)", EditorStyles.boldLabel);
|
||||
// 材质映射配置项
|
||||
for (int i = 0; i < materialMappings.Count; i++)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
// 关键字输入,支持多个关键字,用逗号分隔
|
||||
materialMappings[i].keywords = EditorGUILayout.TextField("匹配关键字(,分隔)", materialMappings[i].keywords);
|
||||
materialMappings[i].targetMaterial =
|
||||
(Material)EditorGUILayout.ObjectField("目标材质", materialMappings[i].targetMaterial, typeof(Material),
|
||||
false);
|
||||
if (GUILayout.Button("删除", GUILayout.Width(60)))
|
||||
{
|
||||
materialMappings.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("添加材质映射配置"))
|
||||
{
|
||||
materialMappings.Add(new MaterialMappingEntry());
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
// 操作按钮
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("生成到场景"))
|
||||
{
|
||||
GenerateMaps();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("清除生成地图"))
|
||||
{
|
||||
ClearGeneratedMaps();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("保存为预制体"))
|
||||
{
|
||||
SaveMapsAsPrefabs();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据当前配置生成所有地图,并生成到场景下的 GENERATED_MAPS_PARENT 父物体内。
|
||||
/// </summary>
|
||||
private void GenerateMaps()
|
||||
{
|
||||
// 检查必要的路径和配置
|
||||
if (string.IsNullOrEmpty(mapDataFolder) || string.IsNullOrEmpty(resourceDataFolder))
|
||||
{
|
||||
Debug.LogError("请先设置数据源和资源数据的文件夹路径!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapEntries.Count == 0)
|
||||
{
|
||||
Debug.LogError("请添加至少一个地图配置项!");
|
||||
return;
|
||||
}
|
||||
|
||||
// 查找或创建生成地图的父物体
|
||||
GameObject parent = GameObject.Find(GENERATED_MAPS_PARENT);
|
||||
if (parent == null)
|
||||
{
|
||||
parent = new GameObject(GENERATED_MAPS_PARENT);
|
||||
}
|
||||
|
||||
// 遍历每个地图配置项生成地图
|
||||
foreach (var entry in mapEntries)
|
||||
{
|
||||
// 拼接完整数据路径
|
||||
string mapDataPath = Path.Combine(mapDataFolder, entry.mapName);
|
||||
string resourceDataPath = Path.Combine(resourceDataFolder, entry.resourceDataName);
|
||||
|
||||
// 读取地图数据
|
||||
using FileStream fs = File.OpenRead(mapDataPath);
|
||||
BinaryReader reader = new BinaryReader(fs);
|
||||
var map = new MPMap();
|
||||
map.Load(reader);
|
||||
Debug.Log($"map size:({map.Width},{map.Height}) | section size:({map.SectionWidth},{map.SectionHeight})");
|
||||
|
||||
// 调用生成 Terrain 的方法,传入 mapName 作为标识
|
||||
TerrainGenerator.GenTerrain(map, chunkSize, terrainMaterial, parent.transform, entry.mapName,
|
||||
entry.isSmoothing);
|
||||
Debug.Log($"生成地图:{entry.mapName}\n数据路径:{mapDataPath}\n资源路径:{resourceDataPath}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除场景中已生成的地图(父物体名称为 GENERATED_MAPS_PARENT)
|
||||
/// </summary>
|
||||
private void ClearGeneratedMaps()
|
||||
{
|
||||
GameObject parent = GameObject.Find(GENERATED_MAPS_PARENT);
|
||||
if (parent != null)
|
||||
{
|
||||
DestroyImmediate(parent);
|
||||
Debug.Log("已清除生成的地图");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("未找到生成的地图");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将生成的每个地图(即每个 MapName 对应的 Terrain 节点)保存为独立预制体,存储在 Assets/Prefabs 下。
|
||||
/// </summary>
|
||||
private void SaveMapsAsPrefabs()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
GameObject parent = GameObject.Find(GENERATED_MAPS_PARENT);
|
||||
if (parent == null)
|
||||
{
|
||||
Debug.LogWarning("没有生成的地图可以保存");
|
||||
return;
|
||||
}
|
||||
|
||||
// 遍历每个地图生成的子对象
|
||||
foreach (Transform mapTransform in parent.transform)
|
||||
{
|
||||
string prefabPath = "Assets/Prefabs/" + mapTransform.name + ".prefab";
|
||||
string directory = Path.GetDirectoryName(prefabPath);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
PrefabUtility.SaveAsPrefabAssetAndConnect(mapTransform.gameObject, prefabPath,
|
||||
InteractionMode.UserAction);
|
||||
Debug.Log($"保存预制体:{prefabPath}");
|
||||
}
|
||||
#else
|
||||
Debug.LogWarning("该功能仅在 Unity Editor 下可用");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据传入的类型名称(如“草”或“树”)进行模糊匹配,
|
||||
/// 遍历材质映射配置,返回第一个匹配的目标材质,未匹配返回 null。
|
||||
/// </summary>
|
||||
public Material GetMappedMaterial(string typeName)
|
||||
{
|
||||
foreach (var mapping in materialMappings)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(mapping.keywords))
|
||||
{
|
||||
// 以逗号分隔关键字,并检查 typeName 是否包含任一关键字
|
||||
string[] keys = mapping.keywords.Split(',');
|
||||
foreach (var key in keys)
|
||||
{
|
||||
if (typeName.Contains(key.Trim()))
|
||||
{
|
||||
return mapping.targetMaterial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地图配置项,每个项对应一个 Map 名称与资源数据名称组合
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class MapInfoEntry
|
||||
{
|
||||
public string mapName = "";
|
||||
public string resourceDataName = "";
|
||||
public bool isSmoothing = true; // 是否平滑处理
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 材质映射配置项,用于配置多个关键字与目标材质的对应关系
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class MaterialMappingEntry
|
||||
{
|
||||
// 支持多个匹配关键字,用逗号分隔
|
||||
public string keywords = "";
|
||||
public Material targetMaterial;
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/EditorWindow/MapDataEditorWindow.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/EditorWindow/MapDataEditorWindow.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73872cce529d488fa96e0ca6eb70fc5b
|
||||
timeCreated: 1743586826
|
221
Assets/MindPowerSdk/EditorWindow/TerrainGenerator.cs
Normal file
221
Assets/MindPowerSdk/EditorWindow/TerrainGenerator.cs
Normal file
@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using MindPowerSdk;
|
||||
|
||||
public static class TerrainGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 利用 MPMap 数据生成 Terrain,采用自定义材质实现贴图混合
|
||||
/// </summary>
|
||||
/// <param name="map">地图数据</param>
|
||||
/// <param name="chunkSize">每块区域的瓦片数(例如 64)</param>
|
||||
/// <param name="terrainMaterial">基于自定义Shader(例如 Custom/TerrainUVBlendShader)的材质</param>
|
||||
/// <param name="parent">生成的 Terrain 父节点</param>
|
||||
/// <param name="isSmoothing"></param>
|
||||
/// <param name="entryMapName"></param>
|
||||
public static void GenTerrain(MPMap map, int chunkSize, Material terrainMaterial, Transform parent,
|
||||
string entryMapName, bool isSmoothing = true)
|
||||
{
|
||||
// 计算全局高度范围(归一化用)
|
||||
(float globalMin, float globalMax) = ComputeGlobalHeightRange(map);
|
||||
|
||||
int xCnt = Mathf.CeilToInt((float)map.Width / chunkSize);
|
||||
int yCnt = Mathf.CeilToInt((float)map.Height / chunkSize);
|
||||
var terrainMap = new GameObject(entryMapName);
|
||||
terrainMap.transform.parent = parent;
|
||||
for (int i = 0; i < yCnt; i++)
|
||||
{
|
||||
for (int j = 0; j < xCnt; j++)
|
||||
{
|
||||
int startX = j * chunkSize;
|
||||
int startY = i * chunkSize;
|
||||
// 为保证边界内不越界,右侧和上侧减1
|
||||
int endX = Mathf.Min(startX + chunkSize, map.Width - 1);
|
||||
int endY = Mathf.Min(startY + chunkSize, map.Height - 1);
|
||||
int resX = (endX - startX) + 1; // 横向瓦片数
|
||||
int resY = (endY - startY) + 1; // 纵向瓦片数
|
||||
|
||||
// 为了保证生成的 Terrain 与原始地图高度一致,并且位置正确,需要使用固定分辨率
|
||||
int newRes = 4097;
|
||||
|
||||
// 创建 TerrainData,设置高度图和混合图分辨率以及尺寸
|
||||
TerrainData terrainData = new TerrainData();
|
||||
terrainData.heightmapResolution = newRes;
|
||||
terrainData.alphamapResolution = newRes;
|
||||
terrainData.size = new Vector3((resX - 1), globalMax - globalMin, (resY - 1));
|
||||
|
||||
// 生成高度图(归一化到 [0,1])
|
||||
float[,] heights = GenerateHeightMap(map, startX, startY, resX, resY, newRes, globalMin, globalMax,
|
||||
isSmoothing);
|
||||
terrainData.SetHeights(0, 0, heights);
|
||||
|
||||
// ---------------------- 新增部分 -------------------------
|
||||
// 生成贴图编号和遮罩贴图(调用你已有的 GenTxtNoTexture 方法)
|
||||
Debug.LogWarning($"{startX} {startY} {chunkSize}");
|
||||
(Texture2D texNo, Texture2D maskNo) = map.GenTxtNoTexture((short)startX, (short)startY, chunkSize);
|
||||
|
||||
|
||||
// 设置每个 tile 在辅助 baked UV 贴图中希望的像素尺寸(建议不小于 4)
|
||||
int cellPixelSize = 7;
|
||||
|
||||
|
||||
// 创建材质实例,并设置贴图
|
||||
Material matInstance = new Material(terrainMaterial);
|
||||
matInstance.SetTexture("_TexNo", texNo);
|
||||
matInstance.SetTexture("_MaskNo", maskNo);
|
||||
|
||||
|
||||
// 计算每个 tile 在 UV 空间内的尺寸(通常为 1/chunkSize)
|
||||
Vector2 mainTileScale = new Vector2(1.0f / chunkSize, 1.0f / chunkSize);
|
||||
matInstance.SetVector("_MainTileOffset", new Vector4(mainTileScale.x, mainTileScale.y, 0, 0));
|
||||
|
||||
// 设置 Terrain 尺寸参数,Shader 内部可根据该参数计算全局 UV0(X:宽度,Z:高度)
|
||||
matInstance.SetVector("_TerrainSize", new Vector4((resX - 1), (resY - 1), 0, 0));
|
||||
|
||||
matInstance.SetFloat("_Repeat", (resX - 1));
|
||||
// ---------------------- 新增部分结束 -------------------------
|
||||
|
||||
// 生成 Terrain 游戏对象并设置位置(Y 坐标偏移 globalMin)
|
||||
GameObject terrainGO = Terrain.CreateTerrainGameObject(terrainData);
|
||||
terrainGO.name = $"terrain_{i}_{j}";
|
||||
terrainGO.transform.parent = terrainMap.transform;
|
||||
terrainGO.transform.position = new Vector3(startX, globalMin, startY - chunkSize);
|
||||
Debug.Log($"terrainGO: {terrainGO.name} | pos: {terrainGO.transform.position}");
|
||||
// 设置 Terrain 为自定义材质模式,并赋予生成的材质实例
|
||||
Terrain terrainComponent = terrainGO.GetComponent<Terrain>();
|
||||
terrainComponent.materialType = Terrain.MaterialType.Custom;
|
||||
terrainComponent.materialTemplate = matInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 以下方法与原有代码一致
|
||||
|
||||
private static float[,] GenerateHeightMap(MPMap map, int startX, int startY, int resX, int resY, int newRes,
|
||||
float globalMin, float globalMax, bool isSmoothing)
|
||||
{
|
||||
// 采集原始高度数据,并归一化到 [0,1]
|
||||
float[,] fullHeights = new float[resY, resX];
|
||||
for (int z = 0; z < resY; z++)
|
||||
{
|
||||
for (int x = 0; x < resX; x++)
|
||||
{
|
||||
int worldX = startX + x;
|
||||
int worldY = startY + z;
|
||||
MPTile tile = map.GetTile(worldX, worldY);
|
||||
float norm = (globalMax - globalMin) > 0 ? (tile.Height - globalMin) / (globalMax - globalMin) : 0f;
|
||||
fullHeights[resY - z - 1, x] = norm;
|
||||
}
|
||||
}
|
||||
|
||||
// 利用双三次插值生成新分辨率高度图
|
||||
float[,] resampled = new float[newRes, newRes];
|
||||
float scaleX = (float)(resX - 1) / (newRes - 1);
|
||||
float scaleY = (float)(resY - 1) / (newRes - 1);
|
||||
for (int z = 0; z < newRes; z++)
|
||||
{
|
||||
float origZ = z * scaleY;
|
||||
for (int x = 0; x < newRes; x++)
|
||||
{
|
||||
float origX = x * scaleX;
|
||||
resampled[z, x] = BicubicInterpolate(fullHeights, origX, origZ, resX, resY);
|
||||
}
|
||||
}
|
||||
|
||||
if (isSmoothing)
|
||||
{
|
||||
// 后处理:高斯模糊平滑
|
||||
float[,] smoothed = ApplyGaussianBlur(resampled, newRes, newRes);
|
||||
return smoothed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return resampled;
|
||||
}
|
||||
}
|
||||
|
||||
private static float BicubicInterpolate(float[,] data, float x, float z, int resX, int resY)
|
||||
{
|
||||
int xInt = Mathf.FloorToInt(x);
|
||||
int zInt = Mathf.FloorToInt(z);
|
||||
float s = x - xInt;
|
||||
float t = z - zInt;
|
||||
|
||||
float[] arr = new float[4];
|
||||
for (int m = -1; m <= 2; m++)
|
||||
{
|
||||
int sampleZ = Mathf.Clamp(zInt + m, 0, resY - 1);
|
||||
float p0 = data[sampleZ, Mathf.Clamp(xInt - 1, 0, resX - 1)];
|
||||
float p1 = data[sampleZ, Mathf.Clamp(xInt, 0, resX - 1)];
|
||||
float p2 = data[sampleZ, Mathf.Clamp(xInt + 1, 0, resX - 1)];
|
||||
float p3 = data[sampleZ, Mathf.Clamp(xInt + 2, 0, resX - 1)];
|
||||
arr[m + 1] = CubicInterpolate(p0, p1, p2, p3, s);
|
||||
}
|
||||
|
||||
return CubicInterpolate(arr[0], arr[1], arr[2], arr[3], t);
|
||||
}
|
||||
|
||||
private static float CubicInterpolate(float p0, float p1, float p2, float p3, float t)
|
||||
{
|
||||
float a0 = p3 - p2 - p0 + p1;
|
||||
float a1 = p0 - p1 - a0;
|
||||
float a2 = p2 - p0;
|
||||
float a3 = p1;
|
||||
return ((a0 * t + a1) * t + a2) * t + a3;
|
||||
}
|
||||
|
||||
private static float[,] ApplyGaussianBlur(float[,] data, int width, int height)
|
||||
{
|
||||
float[,] result = new float[height, width];
|
||||
int kernelSize = 3;
|
||||
int kernelRadius = kernelSize / 2;
|
||||
float[,] kernel = new float[,]
|
||||
{
|
||||
{ 1f, 2f, 1f },
|
||||
{ 2f, 4f, 2f },
|
||||
{ 1f, 2f, 1f }
|
||||
};
|
||||
float kernelSum = 16f;
|
||||
|
||||
for (int z = 0; z < height; z++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
float sum = 0f;
|
||||
for (int kz = -kernelRadius; kz <= kernelRadius; kz++)
|
||||
{
|
||||
int sampleZ = Mathf.Clamp(z + kz, 0, height - 1);
|
||||
for (int kx = -kernelRadius; kx <= kernelRadius; kx++)
|
||||
{
|
||||
int sampleX = Mathf.Clamp(x + kx, 0, width - 1);
|
||||
float weight = kernel[kz + kernelRadius, kx + kernelRadius];
|
||||
sum += data[sampleZ, sampleX] * weight;
|
||||
}
|
||||
}
|
||||
|
||||
result[z, x] = sum / kernelSum;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static (float, float) ComputeGlobalHeightRange(MPMap map)
|
||||
{
|
||||
float min = float.MaxValue;
|
||||
float max = float.MinValue;
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
float h = map.GetTile(x, y).Height;
|
||||
if (h < min) min = h;
|
||||
if (h > max) max = h;
|
||||
}
|
||||
}
|
||||
|
||||
return (min, max);
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/EditorWindow/TerrainGenerator.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/EditorWindow/TerrainGenerator.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4355ef63ea84fa2bb6019260178c157
|
||||
timeCreated: 1742993789
|
8
Assets/MindPowerSdk/Map.meta
generated
Normal file
8
Assets/MindPowerSdk/Map.meta
generated
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dce027637879ccd45b3638e27303089e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
100
Assets/MindPowerSdk/Map/MPActiveMapSection.cs
Normal file
100
Assets/MindPowerSdk/Map/MPActiveMapSection.cs
Normal file
@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
/// <summary>
|
||||
/// 单一贴图层
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MPTileTex
|
||||
{
|
||||
public byte TexNo; // 贴图编号
|
||||
public byte AlphaNo; // Alpha图编号
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{TexNo},{AlphaNo}";
|
||||
}
|
||||
|
||||
public byte SetAlphaNo(byte alphaNo, bool reset = false)
|
||||
{
|
||||
if (reset)
|
||||
{
|
||||
this.AlphaNo = alphaNo;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.AlphaNo |= alphaNo;
|
||||
}
|
||||
|
||||
return alphaNo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
MPTileTex TexLayer[4]; // 最多4层重叠
|
||||
DWORD dwColor; // 左上角第一个顶点的颜色
|
||||
short sRegion; // 区域属性
|
||||
BYTE btIsland; // 岛屿属性
|
||||
BYTE btBlock[4]; // 4个分格的障碍记录
|
||||
|
||||
float fHeight; // 左上角第一个顶点的高度
|
||||
|
||||
//lemon add@2004.10.18
|
||||
DWORD dwTColor; // 临时顶点的颜色
|
||||
DWORD dwXColor; // 混合后的颜色
|
||||
*
|
||||
*/
|
||||
public unsafe struct MPTile
|
||||
{
|
||||
public MPTileTex[] TexLayer; // 最多4层重叠
|
||||
public short Color; // 左上角第一个顶点的颜色
|
||||
public short Region; // 区域属性
|
||||
public byte IsLand; // 岛屿属性
|
||||
public fixed byte Block[4]; // 4个分格的障碍记录
|
||||
|
||||
public float Height; // 左上角第一个顶点的高度
|
||||
|
||||
public int TColor; // 临时顶点颜色
|
||||
public int XColor; // 混合后的颜色
|
||||
|
||||
|
||||
public Color UniColor;
|
||||
|
||||
public void TileInfo_5To8(byte bt, uint dwNew)
|
||||
{
|
||||
byte* pbtTile = stackalloc byte[8];
|
||||
|
||||
pbtTile[0] = bt;
|
||||
pbtTile[1] = 15;
|
||||
pbtTile[2] = (byte)(dwNew >> 26);
|
||||
pbtTile[3] = (byte)((dwNew >> 22) & 0x000F);
|
||||
pbtTile[4] = (byte)((dwNew >> 16) & 63);
|
||||
pbtTile[5] = (byte)((dwNew >> 12) & 0x000F);
|
||||
pbtTile[6] = (byte)((dwNew >> 6) & 63);
|
||||
pbtTile[7] = (byte)((dwNew >> 2) & 0x000F);
|
||||
|
||||
this.TexLayer = new MPTileTex[4];
|
||||
for (int i = 0; i < 8; i += 2)
|
||||
{
|
||||
this.TexLayer[i / 2].TexNo = pbtTile[i];
|
||||
this.TexLayer[i / 2].AlphaNo = pbtTile[i + 1];
|
||||
}
|
||||
|
||||
//Debug.Log($"{TexLayer[0]}|{TexLayer[1]}|{TexLayer[2]}|{TexLayer[3]}");
|
||||
}
|
||||
}
|
||||
|
||||
public struct MPActiveMapSection
|
||||
{
|
||||
public MPTile[] TileData;
|
||||
public int X, Y; // MapSection所在的位置
|
||||
public int ActiveTime; // 最后一次使用的时间
|
||||
public int DataOffset; // 文件数据指针位置 = 0, 表示没有数据
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Map/MPActiveMapSection.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Map/MPActiveMapSection.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c2d672641ccf5748bfcfb41532562a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
235
Assets/MindPowerSdk/Map/MPMap.cs
Normal file
235
Assets/MindPowerSdk/Map/MPMap.cs
Normal file
@ -0,0 +1,235 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public partial class MPMap
|
||||
{
|
||||
public const float SEA_LEVEL = 0.0f;
|
||||
|
||||
private static readonly int[,] Offset =
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ 0, 1 },
|
||||
{ 1, 1 }
|
||||
};
|
||||
|
||||
private MPTile GetGroupTile(int x, int y, int no)
|
||||
{
|
||||
return GetTile(x + Offset[no, 0], y + Offset[no, 1]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取地形的高度
|
||||
/// </summary>
|
||||
/// <param name="fX"></param>
|
||||
/// <param name="fY"></param>
|
||||
/// <returns></returns>
|
||||
public float GetHeight(float fX, float fY)
|
||||
{
|
||||
// 将浮点坐标转换为整数坐标(取整)
|
||||
int nX = (int)fX;
|
||||
int nY = (int)fY;
|
||||
|
||||
// 计算四个角点的坐标(构成一个单位矩形)
|
||||
float fx1 = (float)nX;
|
||||
float fx2 = (float)nX + 1;
|
||||
float fy1 = (float)nY;
|
||||
float fy2 = (float)nY + 1;
|
||||
|
||||
// 初始化四个顶点的高度(默认海平面)
|
||||
float[] fHeight = new float[4] { SEA_LEVEL, SEA_LEVEL, SEA_LEVEL, SEA_LEVEL };
|
||||
|
||||
// 获取基准瓦片
|
||||
MPTile pTile = GetTile(nX, nY);
|
||||
// 遍历四个顶点获取实际高度
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
MPTile pCurTile = GetGroupTile(nX, nY, i);
|
||||
fHeight[i] = pCurTile.Height;
|
||||
}
|
||||
|
||||
// 构建四个三维顶点
|
||||
Vector3 v0 = new Vector3(fx1, fy1, fHeight[0]);
|
||||
Vector3 v1 = new Vector3(fx2, fy1, fHeight[1]);
|
||||
Vector3 v2 = new Vector3(fx1, fy2, fHeight[2]);
|
||||
Vector3 v3 = new Vector3(fx2, fy2, fHeight[3]);
|
||||
|
||||
// 创建射线(从高处垂直向下)
|
||||
Vector3 vOrig = new Vector3(fX, fY, 20.0f); // 起点
|
||||
Vector3 vDir = new Vector3(0, 0, -1); // 方向向下
|
||||
float u, v; // 用于存储交点参数
|
||||
|
||||
Vector3 vPickPos;
|
||||
// 检测与第一个三角形(v0-v1-v2)的相交
|
||||
if (IntersectTri(v0, v1, v2, vOrig, vDir, out u, out v))
|
||||
{
|
||||
vPickPos = v0 + u * (v1 - v0) + v * (v2 - v0);
|
||||
return vPickPos.z; // 返回交点的Z值(高度)
|
||||
}
|
||||
|
||||
// 检测与第二个三角形(v2-v1-v3)的相交
|
||||
if (IntersectTri(v2, v1, v3, vOrig, vDir, out u, out v))
|
||||
{
|
||||
vPickPos = v2 + u * (v1 - v2) + v * (v3 - v2);
|
||||
return vPickPos.z;
|
||||
}
|
||||
|
||||
// 无交点返回0
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// Unity版本的三角形射线相交检测
|
||||
bool IntersectTri(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 origin, Vector3 direction, out float u, out float v)
|
||||
{
|
||||
u = v = 0;
|
||||
Vector3 edge1 = v1 - v0;
|
||||
Vector3 edge2 = v2 - v0;
|
||||
|
||||
// 计算行列式
|
||||
Vector3 pvec = Vector3.Cross(direction, edge2);
|
||||
float det = Vector3.Dot(edge1, pvec);
|
||||
|
||||
// 背面剔除(det > 0 可改为 det < 0 如果需要双面检测)
|
||||
if (det < Mathf.Epsilon)
|
||||
return false;
|
||||
|
||||
// 计算U参数并测试范围
|
||||
Vector3 tvec = origin - v0;
|
||||
u = Vector3.Dot(tvec, pvec);
|
||||
if (u < 0 || u > det) return false;
|
||||
|
||||
// 计算V参数并测试范围
|
||||
Vector3 qvec = Vector3.Cross(tvec, edge1);
|
||||
v = Vector3.Dot(direction, qvec);
|
||||
if (v < 0 || u + v > det) return false;
|
||||
|
||||
// 归一化参数
|
||||
float invDet = 1.0f / det;
|
||||
u *= invDet;
|
||||
v *= invDet;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回结束位置与矩形大小
|
||||
/// </summary>
|
||||
/// <param name="startX"></param>
|
||||
/// <param name="startY"></param>
|
||||
/// <param name="showSize"></param>
|
||||
/// <returns></returns>
|
||||
public RectInt GetRect(short startX, short startY, int showSize)
|
||||
{
|
||||
int endX = Mathf.Min(startX + showSize, Width);
|
||||
int endY = Mathf.Min(startY + showSize, Height);
|
||||
|
||||
// 本次宽高
|
||||
int width = endX - startX;
|
||||
int height = endY - startY;
|
||||
|
||||
return new RectInt(endX, endY, width, height);
|
||||
}
|
||||
|
||||
public Mesh GenMesh(short startX, short startY, int showSize)
|
||||
{
|
||||
RectInt rect = GetRect(startX, startY, showSize);
|
||||
|
||||
// 顶点
|
||||
int verticesNum = (rect.width) * (rect.height) * 4;
|
||||
Vector3[] vertices = new Vector3[verticesNum];
|
||||
int[] triangles = new int[verticesNum * 6];
|
||||
Vector2[] uv0 = new Vector2[verticesNum];
|
||||
Vector2[] uv2 = new Vector2[verticesNum];
|
||||
int vertIdx = 0;
|
||||
int triIdx = 0;
|
||||
|
||||
for (short y = startY; y < rect.y; y++)
|
||||
{
|
||||
for (short x = startX; x < rect.x; x++)
|
||||
{
|
||||
// 添加4个顶点
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
MPTile tile = GetGroupTile(x, y, i);
|
||||
vertices[vertIdx + i] = new Vector3(x + Offset[i, 0], tile.Height, (y + Offset[i, 1]) * -1);
|
||||
// Debug.Log($"{x},{y}");
|
||||
|
||||
// uv 整个mesh映射到一张贴图上
|
||||
int rx = x - startX;
|
||||
// int ry = rect.y - y - 2;
|
||||
int ry = y - startY + 1;
|
||||
uv0[vertIdx + i] = new Vector2((rx + Offset[i, 0]) / (float)rect.width, (ry + Offset[i, 1]) * -1 / (float)rect.height);
|
||||
uv2[vertIdx + i] = new Vector2(Offset[i, 0], Offset[i, 1] * -1);
|
||||
}
|
||||
|
||||
triangles[triIdx + 0] = vertIdx + 2;
|
||||
triangles[triIdx + 1] = vertIdx + 0;
|
||||
triangles[triIdx + 2] = vertIdx + 3;
|
||||
|
||||
triangles[triIdx + 3] = vertIdx + 0;
|
||||
triangles[triIdx + 4] = vertIdx + 1;
|
||||
triangles[triIdx + 5] = vertIdx + 3;
|
||||
|
||||
vertIdx += 4;
|
||||
triIdx += 6;
|
||||
}
|
||||
}
|
||||
|
||||
Mesh mesh = new Mesh();
|
||||
mesh.SetVertices(vertices);
|
||||
mesh.SetTriangles(triangles, 0);
|
||||
mesh.SetUVs(0, uv0);
|
||||
mesh.SetUVs(2, uv2);
|
||||
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public (Texture2D, Texture2D) GenTxtNoTexture(short startX, short startY, int showSize)
|
||||
{
|
||||
RectInt rect = GetRect(startX, startY, showSize);
|
||||
|
||||
Texture2D texture1 = new Texture2D(rect.width, rect.height, TextureFormat.RGBA32, false, true); // 贴图值: texNo
|
||||
texture1.filterMode = FilterMode.Point;
|
||||
|
||||
Texture2D texture2 = new Texture2D(rect.width, rect.height, TextureFormat.RGBA32, false, true); // 遮罩值:alphaNo
|
||||
texture2.filterMode = FilterMode.Point;
|
||||
|
||||
for (short y = startY; y < rect.y; y++)
|
||||
{
|
||||
for (short x = startX; x < rect.x; x++)
|
||||
{
|
||||
MPTile tile = GetTile(x, y);
|
||||
|
||||
// 4层数据
|
||||
float r = (tile.TexLayer[0].TexNo - 1) / 64f;
|
||||
float g = (tile.TexLayer[1].TexNo - 1) / 64f;
|
||||
float b = (tile.TexLayer[2].TexNo - 1) / 64f;
|
||||
float a = (tile.TexLayer[3].TexNo - 1) / 64f;
|
||||
|
||||
int rx = x - startX;
|
||||
int ry = rect.y - 1 - y;
|
||||
texture1.SetPixel(rx, ry, new Color(r, g, b, a));
|
||||
|
||||
var alphaNo = new Color(
|
||||
(tile.TexLayer[0].AlphaNo - 1) / 16f,
|
||||
(tile.TexLayer[1].AlphaNo - 1) / 16f,
|
||||
(tile.TexLayer[2].AlphaNo - 1) / 16f,
|
||||
(tile.TexLayer[3].AlphaNo - 1) / 16f);
|
||||
texture2.SetPixel(rx, ry, alphaNo);
|
||||
|
||||
if (alphaNo.r > 48 || alphaNo.g > 48 || alphaNo.b > 48 || alphaNo.a > 48)
|
||||
{
|
||||
Debug.LogError($"{rx},{ry}|{alphaNo}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
texture1.Apply();
|
||||
texture2.Apply();
|
||||
|
||||
return (texture1, texture2);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Map/MPMap.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Map/MPMap.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16ac39916dae5c146982e3e6194888e4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
194
Assets/MindPowerSdk/Map/MPMap.data.cs
Normal file
194
Assets/MindPowerSdk/Map/MPMap.data.cs
Normal file
@ -0,0 +1,194 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public partial class MPMap
|
||||
{
|
||||
private MPMapFileHeader _mapHeader;
|
||||
|
||||
public int Width => _mapHeader.Width;
|
||||
public int Height => _mapHeader.Height;
|
||||
public int SectionWidth => _mapHeader.SectionWidth;
|
||||
public int SectionHeight => _mapHeader.SectionHeight;
|
||||
|
||||
// 部分数据的数量(地图分块)
|
||||
public int SectionCntX;
|
||||
public int SecitonCntY;
|
||||
public int SectionCnt;
|
||||
|
||||
// 地图块索引偏移
|
||||
private int[] _offsetIdx;
|
||||
|
||||
public MPActiveMapSection[,] ActiveSectionArray;
|
||||
|
||||
// private List<MPActiveMapSection> ActiveSections = new();
|
||||
private BinaryReader _fp;
|
||||
|
||||
private MPTile _defaultTile;
|
||||
|
||||
public MPMap()
|
||||
{
|
||||
_defaultTile = new MPTile();
|
||||
_defaultTile.TexLayer = new MPTileTex[4];
|
||||
|
||||
//_pDefaultTile->TexLayer[0].btTexNo = UNDERWATER_TEXNO;
|
||||
//_pDefaultTile->TexLayer[0].btAlphaNo = 15;
|
||||
//_pDefaultTile->TexLayer[1].btTexNo = 255; // 标示为DefaultTile
|
||||
//_pDefaultTile->fHeight = UNDERWATER_HEIGHT;
|
||||
//_pDefaultTile->dwColor = 0xffffffff;
|
||||
|
||||
_defaultTile.TexLayer[0].TexNo = 22;
|
||||
_defaultTile.TexLayer[0].AlphaNo = 15;
|
||||
_defaultTile.TexLayer[1].TexNo = 255;
|
||||
_defaultTile.Height = -2.0f;
|
||||
}
|
||||
|
||||
public void Load(BinaryReader reader)
|
||||
{
|
||||
_fp = reader;
|
||||
this._mapHeader = MPMapFileHeader.Load(reader);
|
||||
|
||||
Debug.Log($"version: {this._mapHeader.MapFlag}");
|
||||
|
||||
|
||||
SectionCntX = this.Width / SectionWidth;
|
||||
SecitonCntY = this.Height / SectionHeight;
|
||||
SectionCnt = SectionCntX * SecitonCntY;
|
||||
|
||||
// 读取块的偏移位置
|
||||
_offsetIdx = new int[SectionCnt];
|
||||
for (int i = 0; i < _offsetIdx.Length; i++)
|
||||
_offsetIdx[i] = reader.ReadInt32();
|
||||
|
||||
ActiveSectionArray = new MPActiveMapSection[SectionCntX, SecitonCntY];
|
||||
|
||||
FullLoading();
|
||||
}
|
||||
|
||||
private void FullLoading()
|
||||
{
|
||||
for (int i = 0; i < SectionCnt; i++)
|
||||
{
|
||||
int x = i % SectionCntX;
|
||||
int y = i / SectionCntX;
|
||||
if (_offsetIdx[i] != 0)
|
||||
{
|
||||
LoadSectionData(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSectionData(int sectionX, int sectionY)
|
||||
{
|
||||
MPActiveMapSection section = new MPActiveMapSection
|
||||
{
|
||||
X = sectionX,
|
||||
Y = sectionY
|
||||
};
|
||||
|
||||
LoadSectionData(ref section);
|
||||
ActiveSectionArray[sectionX, sectionY] = section;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取地图区块数据
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
private void LoadSectionData(ref MPActiveMapSection section)
|
||||
{
|
||||
int sectionX = section.X;
|
||||
int sectionY = section.Y;
|
||||
section.DataOffset = ReadSectionDataOffset(sectionX, sectionY);
|
||||
if (section.DataOffset == 0)
|
||||
{
|
||||
Debug.LogWarning($"空块数据: {sectionX},{sectionY}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 开始读取tile数据
|
||||
_fp.BaseStream.Seek(section.DataOffset, SeekOrigin.Begin);
|
||||
section.TileData = new MPTile[SectionWidth * SectionHeight];
|
||||
for (int y = 0; y < SectionHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < SectionWidth; x++)
|
||||
{
|
||||
int idx = GetMPTileIndex(x, y);
|
||||
MPTile tile = new MPTile();
|
||||
|
||||
SNewFileTile fileTile = SNewFileTile.Load(_fp);
|
||||
|
||||
// rgb565 to int
|
||||
short rgb = fileTile.Color;
|
||||
byte r = (byte)((rgb & 0xf800) >> 8);
|
||||
byte g = (byte)((rgb & 0x7e0) >> 3);
|
||||
byte b = (byte)((rgb & 0x1f) << 3);
|
||||
|
||||
tile.UniColor = new Color(r / 255f, g / 255f, b / 255f);
|
||||
|
||||
tile.TileInfo_5To8(fileTile.btTileInfo, fileTile.dwTileInfo);
|
||||
|
||||
tile.Height = (fileTile.Height) * 10f / 100.0f;
|
||||
tile.IsLand = fileTile.IsLand;
|
||||
tile.Region = fileTile.Region;
|
||||
|
||||
unsafe
|
||||
{
|
||||
Span<byte> dst = new Span<byte>(tile.Block, 4);
|
||||
Span<byte> src = new Span<byte>(fileTile.Block, 4);
|
||||
src.CopyTo(dst);
|
||||
}
|
||||
|
||||
section.TileData[idx] = tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置读取区块数据的偏移
|
||||
/// </summary>
|
||||
/// <param name="sectionX"></param>
|
||||
/// <param name="sectionY"></param>
|
||||
/// <returns></returns>
|
||||
private int ReadSectionDataOffset(int sectionX, int sectionY)
|
||||
{
|
||||
int loc = sectionY * SectionCntX + sectionX;
|
||||
return _offsetIdx[loc];
|
||||
}
|
||||
|
||||
|
||||
public int GetMPTileIndex(int x, int y)
|
||||
{
|
||||
return SectionWidth * y + x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过地图坐标直接获取Tile点
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns></returns>
|
||||
public MPTile GetTile(int x, int y)
|
||||
{
|
||||
// y = Height - y - 1;
|
||||
|
||||
int sX = x / SectionWidth;
|
||||
int sY = y / SectionHeight;
|
||||
|
||||
if (ActiveSectionArray.GetLength(0) <= sX || ActiveSectionArray.GetLength(1) <= sY)
|
||||
return _defaultTile;
|
||||
|
||||
MPActiveMapSection section = ActiveSectionArray[sX, sY];
|
||||
if (section.TileData is not { Length: > 0 }) return _defaultTile;
|
||||
|
||||
int tX = x % SectionWidth;
|
||||
int tY = y % SectionHeight;
|
||||
int idx = GetMPTileIndex(tX, tY);
|
||||
if (idx >= section.TileData.Length || idx < 0)
|
||||
return _defaultTile;
|
||||
return section.TileData[idx];
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Map/MPMap.data.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Map/MPMap.data.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d48cf981a8a35d488fa8efbbc1d0e56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
50
Assets/MindPowerSdk/Map/MPMapFileHeader.cs
Normal file
50
Assets/MindPowerSdk/Map/MPMapFileHeader.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MPMapFileHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型标识 = 780624
|
||||
/// </summary>
|
||||
public int MapFlag { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地图宽度
|
||||
/// </summary>
|
||||
public int Width { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地图高度
|
||||
/// </summary>
|
||||
public int Height { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每个Section(部分)宽度
|
||||
/// </summary>
|
||||
public int SectionWidth { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每个Section(部分)高度
|
||||
/// </summary>
|
||||
public int SectionHeight { get; private set; }
|
||||
|
||||
public static MPMapFileHeader Load(BinaryReader reader)
|
||||
{
|
||||
MPMapFileHeader header = default;
|
||||
|
||||
header.MapFlag = reader.ReadInt32();
|
||||
header.Width = reader.ReadInt32();
|
||||
header.Height = reader.ReadInt32();
|
||||
header.SectionWidth = reader.ReadInt32();
|
||||
header.SectionHeight = reader.ReadInt32();
|
||||
|
||||
return header;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Map/MPMapFileHeader.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Map/MPMapFileHeader.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01c3951dd660b8c4ebdec0bc39a0d925
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
34
Assets/MindPowerSdk/Map/SNewFileTile.cs
Normal file
34
Assets/MindPowerSdk/Map/SNewFileTile.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public unsafe struct SNewFileTile
|
||||
{
|
||||
// DWORD dwTileInfo; // 保存3个layer的tex no和alpha no
|
||||
// BYTE btTileInfo; // 最下层的tex no
|
||||
// short sColor; // 32bit的颜色保存为565
|
||||
// char cHeight; // 每10cm为一级来保存高度
|
||||
// short sRegion;
|
||||
// BYTE btIsland;
|
||||
// BYTE btBlock[4];
|
||||
|
||||
public uint dwTileInfo;
|
||||
public byte btTileInfo;
|
||||
public short Color;
|
||||
public sbyte Height;
|
||||
public short Region;
|
||||
public byte IsLand;
|
||||
public fixed byte Block[4];
|
||||
|
||||
public static SNewFileTile Load(BinaryReader reader)
|
||||
{
|
||||
SNewFileTile s = new SNewFileTile();
|
||||
Span<byte> bytes = new Span<byte>(&s, sizeof(SNewFileTile));
|
||||
reader.Read(bytes);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Map/SNewFileTile.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Map/SNewFileTile.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7de4f04a34c974247b83bb95ce85ee20
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
157
Assets/MindPowerSdk/Map/SceneObjFile.cs
Normal file
157
Assets/MindPowerSdk/Map/SceneObjFile.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using MindPowerSdk;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct SceneObjInfo
|
||||
{
|
||||
public ushort TypeId; // 高2位是type(0: 场景物件, 1: 特效物件), 其余是ID
|
||||
public int X; // 相对坐标
|
||||
public int Y;
|
||||
|
||||
public short HeightOff;
|
||||
public short YawAngle;
|
||||
public short Scale; // 保留未使用
|
||||
|
||||
public short GetTypeId()
|
||||
{
|
||||
return (short)(TypeId >> 14);
|
||||
}
|
||||
|
||||
public short GetID()
|
||||
{
|
||||
return (short)(TypeId & 0x3FFF);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"type={GetTypeId()},id={GetID()},x={X},y={Y},height_off={HeightOff},yaw_angle={YawAngle},scale={Scale}";
|
||||
}
|
||||
}
|
||||
|
||||
public class SceneObjFile
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件头
|
||||
/// </summary>
|
||||
public struct Header
|
||||
{
|
||||
public string Title; // "HF Object File!" char[16]
|
||||
public int Version;
|
||||
public int FileSize;
|
||||
|
||||
public int SectionCntX; // 地图的横向区域数
|
||||
public int SectionCntY; // 地图的纵向区域数
|
||||
|
||||
public int SectionWidth; // 区域的宽度(单位:Tile)
|
||||
public int SectionHeight; // 区域的高度(单位:Tile)
|
||||
public int SectionObjNum; // 区域允许的最大物件数
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用来索引文件中对象的数据
|
||||
/// </summary>
|
||||
public struct SSectionIndex
|
||||
{
|
||||
public int ObjInfoPos;
|
||||
public int ObjNum;
|
||||
}
|
||||
|
||||
|
||||
public Header FileHeader { get; private set; }
|
||||
|
||||
SSectionIndex[,] sectionIndex;
|
||||
|
||||
public List<SceneObjInfo>[,] objInfos;
|
||||
|
||||
public unsafe int Load(string obj_file)
|
||||
{
|
||||
FileStream fs = File.OpenRead(obj_file);
|
||||
BinaryReader r = new BinaryReader(fs);
|
||||
|
||||
long size = r.BaseStream.Length;
|
||||
|
||||
Header s = new Header();
|
||||
s.Title = Encoding.ASCII.GetString(r.ReadBytes(16));
|
||||
s.Version = r.ReadInt32();
|
||||
s.FileSize = r.ReadInt32(); // 实际是32位
|
||||
|
||||
s.SectionCntX = r.ReadInt32();
|
||||
s.SectionCntY = r.ReadInt32();
|
||||
|
||||
s.SectionWidth = r.ReadInt32();
|
||||
s.SectionHeight = r.ReadInt32();
|
||||
s.SectionObjNum = r.ReadInt32();
|
||||
|
||||
FileHeader = s;
|
||||
|
||||
Debug.Log(JsonUtility.ToJson(s));
|
||||
|
||||
if (s.FileSize != size)
|
||||
{
|
||||
Debug.LogWarning($"{obj_file} 文件szie不匹配: {s.FileSize} != {size}");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s.Version != 600)
|
||||
{
|
||||
Debug.LogWarning($"{obj_file} 版本只支持600: 当前是={s.Version}");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 读取索引信息
|
||||
sectionIndex = new SSectionIndex[s.SectionCntX, s.SectionCntY];
|
||||
for (int y = 0; y < s.SectionCntY; y++)
|
||||
{
|
||||
for (int x = 0; x < s.SectionCntX; x++)
|
||||
{
|
||||
SSectionIndex data = new SSectionIndex();
|
||||
data.ObjInfoPos = r.ReadInt32();
|
||||
data.ObjNum = r.ReadInt32();
|
||||
sectionIndex[x, y] = data;
|
||||
|
||||
if (data.ObjNum != 0)
|
||||
Debug.Log(JsonUtility.ToJson(data));
|
||||
}
|
||||
}
|
||||
|
||||
// 读取场景物体
|
||||
objInfos = new List<SceneObjInfo>[s.SectionCntX, s.SectionCntY];
|
||||
for (int y = 0; y < s.SectionCntY; y++)
|
||||
{
|
||||
for (int x = 0; x < s.SectionCntX; x++)
|
||||
{
|
||||
SSectionIndex idx = sectionIndex[x, y];
|
||||
if (idx.ObjNum == 0)
|
||||
continue;
|
||||
|
||||
var list = objInfos[x, y] ??= new List<SceneObjInfo>();
|
||||
|
||||
r.BaseStream.Seek(idx.ObjInfoPos, SeekOrigin.Begin);
|
||||
|
||||
for (int i = 0; i < idx.ObjNum; i++)
|
||||
{
|
||||
byte[] tmpBytes = r.ReadBytes(sizeof(SceneObjInfo));
|
||||
SceneObjInfo sceneObjInfo = StructReader.ReadStructFromArray<SceneObjInfo>(tmpBytes);
|
||||
|
||||
// 转成绝对坐标
|
||||
int sectionX = x * s.SectionWidth * 100;
|
||||
int sectionY = y * s.SectionHeight * 100;
|
||||
sceneObjInfo.X += sectionX;
|
||||
sceneObjInfo.Y += sectionY;
|
||||
|
||||
list.Add(sceneObjInfo);
|
||||
Debug.Log(sceneObjInfo.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Map/SceneObjFile.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Map/SceneObjFile.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74622940af1063046bc3832a354b4566
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
14
Assets/MindPowerSdk/MindPowerSdk.asmdef
Normal file
14
Assets/MindPowerSdk/MindPowerSdk.asmdef
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "MindPowerSdk",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
7
Assets/MindPowerSdk/MindPowerSdk.asmdef.meta
generated
Normal file
7
Assets/MindPowerSdk/MindPowerSdk.asmdef.meta
generated
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c884d35d4d3a994b950041852df1f65
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
Assets/MindPowerSdk/Model.meta
generated
Normal file
3
Assets/MindPowerSdk/Model.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b50939bf440444d9bde7dfb4d9242f2
|
||||
timeCreated: 1728005406
|
398
Assets/MindPowerSdk/Model/lwAnimDataInfo.cs
Normal file
398
Assets/MindPowerSdk/Model/lwAnimDataInfo.cs
Normal file
@ -0,0 +1,398 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwAnimDataInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPStruct)]
|
||||
/* this+0x4 */
|
||||
public lwAnimDataBone anim_bone;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPStruct)]
|
||||
/* this+0x8 */
|
||||
public lwAnimDataMatrix anim_mat;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPStruct)]
|
||||
/* this+0xc */
|
||||
public lwAnimDataMtlOpacitySet anim_mtlopac;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPStruct)]
|
||||
/* this+0x4c */
|
||||
public lwAnimDataTexUVSet anim_tex;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPStruct)]
|
||||
/* this+0x14c */
|
||||
public lwAnimDataTexImgSet anim_img;
|
||||
}
|
||||
|
||||
public enum lwBoneKeyInfoType
|
||||
{
|
||||
BONE_KEY_TYPE_MAT43 = 1,
|
||||
BONE_KEY_TYPE_MAT44 = 2,
|
||||
BONE_KEY_TYPE_QUAT = 3,
|
||||
BONE_KEY_TYPE_INVALID = -1
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwBoneBaseInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
/* this+0x0 */
|
||||
public char[] name;
|
||||
|
||||
/* this+0x40 */
|
||||
public uint id;
|
||||
|
||||
/* this+0x44 */
|
||||
public uint parent_id;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwBoneDummyInfo
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint id;
|
||||
|
||||
/* this+0x4 */
|
||||
public uint parent_bone_id;
|
||||
|
||||
/* this+0x8 */
|
||||
public Matrix4x4 mat;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwMatrix43
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||
/* this+0x0 */
|
||||
public float[] m;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwBoneKeyInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x0 */
|
||||
public lwMatrix43[] mat43_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x4 */
|
||||
public Matrix4x4[] mat44_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x8 */
|
||||
public Vector3[] pos_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0xc */
|
||||
public Quaternion[] quat_seq;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwAnimDataMatrix
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x4 */
|
||||
public lwMatrix43[] _mat_seq;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint _frame_num;
|
||||
|
||||
public int Load(BinaryReader fp, uint version)
|
||||
{
|
||||
this._frame_num = fp.ReadUInt32();
|
||||
this._mat_seq = StructReader.ReadStructArray<lwMatrix43>(fp, this._frame_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Load(BinaryReader fp, uint version, uint frames)
|
||||
{
|
||||
this._frame_num = fp.ReadUInt32();
|
||||
if (frames < _frame_num)
|
||||
_frame_num = frames;
|
||||
this._mat_seq = StructReader.ReadStructArray<lwMatrix43>(fp, this._frame_num);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwAnimDataBone
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
/* this+0x4 */
|
||||
public struct lwBoneInfoHeader
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint bone_num;
|
||||
|
||||
/* this+0x4 */
|
||||
public uint frame_num;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint dummy_num;
|
||||
|
||||
/* this+0xc */
|
||||
public lwBoneKeyInfoType key_type; // MindPower::lwBoneKeyInfoType
|
||||
};
|
||||
|
||||
/* this+0x4 */
|
||||
public lwBoneInfoHeader _header;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x14 */
|
||||
public lwBoneBaseInfo[] _base_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x18 */
|
||||
public lwBoneDummyInfo[] _dummy_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x1c */
|
||||
public lwBoneKeyInfo[] _key_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x20 */
|
||||
public Matrix4x4[] _invmat_seq;
|
||||
|
||||
public int Load(BinaryReader fp, uint version)
|
||||
{
|
||||
if (version == 0)
|
||||
{
|
||||
uint old_version = fp.ReadUInt32();
|
||||
int x = 0;
|
||||
}
|
||||
|
||||
if (this._base_seq != null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
this._header = StructReader.ReadStruct<lwAnimDataBone.lwBoneInfoHeader>(fp);
|
||||
this._base_seq = StructReader.ReadStructArray<lwBoneBaseInfo>(fp, this._header.bone_num);
|
||||
this._key_seq = new lwBoneKeyInfo[this._header.bone_num];
|
||||
this._invmat_seq = StructReader.ReadStructArray<Matrix4x4>(fp, this._header.bone_num);
|
||||
this._dummy_seq = StructReader.ReadStructArray<lwBoneDummyInfo>(fp, this._header.dummy_num);
|
||||
|
||||
if (this._header.key_type == lwBoneKeyInfoType.BONE_KEY_TYPE_MAT43)
|
||||
{
|
||||
for (uint i = 0; i < this._header.bone_num; i++)
|
||||
{
|
||||
this._key_seq[i] = new lwBoneKeyInfo();
|
||||
lwBoneKeyInfo key = this._key_seq[i];
|
||||
key.mat43_seq = StructReader.ReadStructArray<lwMatrix43>(fp, this._header.frame_num);
|
||||
}
|
||||
}
|
||||
else if (this._header.key_type == lwBoneKeyInfoType.BONE_KEY_TYPE_MAT44)
|
||||
{
|
||||
for (uint i = 0; i < this._header.bone_num; i++)
|
||||
{
|
||||
this._key_seq[i] = new lwBoneKeyInfo();
|
||||
lwBoneKeyInfo key = this._key_seq[i];
|
||||
key.mat44_seq = StructReader.ReadStructArray<Matrix4x4>(fp, this._header.frame_num);
|
||||
}
|
||||
}
|
||||
else if (this._header.key_type == lwBoneKeyInfoType.BONE_KEY_TYPE_QUAT)
|
||||
{
|
||||
if (version >= 0x1003)
|
||||
{
|
||||
for (uint i = 0; i < this._header.bone_num; i++)
|
||||
{
|
||||
this._key_seq[i] = new lwBoneKeyInfo();
|
||||
lwBoneKeyInfo key = this._key_seq[i];
|
||||
key.pos_seq = StructReader.ReadStructArray<Vector3>(fp, this._header.frame_num);
|
||||
key.quat_seq = StructReader.ReadStructArray<Quaternion>(fp, this._header.frame_num);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint i = 0; i < this._header.bone_num; i++)
|
||||
{
|
||||
this._key_seq[i] = new lwBoneKeyInfo();
|
||||
lwBoneKeyInfo key = this._key_seq[i];
|
||||
uint pos_num = this._base_seq[i].parent_id == 0xffffffff ? this._header.frame_num : 1;
|
||||
key.pos_seq = StructReader.ReadStructArray<Vector3>(fp, pos_num);
|
||||
if (pos_num == 1)
|
||||
{
|
||||
for (uint j = 1; j < this._header.frame_num; j++)
|
||||
{
|
||||
key.pos_seq[i] = key.pos_seq[0];
|
||||
}
|
||||
}
|
||||
|
||||
key.quat_seq = StructReader.ReadStructArray<Quaternion>(fp, this._header.frame_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Load(string file)
|
||||
{
|
||||
int ret = -1;
|
||||
if (!File.Exists(file))
|
||||
return -1;
|
||||
FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader fp = new BinaryReader(fs);
|
||||
|
||||
uint version = fp.ReadUInt32();
|
||||
if (version < 0x1000)
|
||||
{
|
||||
version = 0;
|
||||
|
||||
Debug.LogError("old animation file: " + file + ", need re-export it");
|
||||
|
||||
fp.Close();
|
||||
fs.Close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (this.Load(fp, version) >= 0)
|
||||
{
|
||||
// Overloaded version
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
fp.Close();
|
||||
fs.Close();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwKeyFloat
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint key;
|
||||
|
||||
/* this+0x4 */
|
||||
public uint slerp_type;
|
||||
|
||||
/* this+0x8 */
|
||||
public float data;
|
||||
};
|
||||
|
||||
public interface lwIAnimKeySetFloat
|
||||
{
|
||||
uint SetKeySequence(lwKeyFloat[] seq, uint num);
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwAnimKeySetFloat : lwIAnimKeySetFloat
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x4 */
|
||||
public lwKeyFloat[] _data_seq;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint _data_num;
|
||||
|
||||
/* this+0xc */
|
||||
public uint _data_capacity;
|
||||
|
||||
public uint SetKeySequence(lwKeyFloat[] seq, uint num)
|
||||
{
|
||||
_data_seq = seq;
|
||||
_data_num = num;
|
||||
_data_capacity = num;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwAnimDataMtlOpacity
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPStruct)]
|
||||
/* this+0x4 */
|
||||
public lwIAnimKeySetFloat _aks_ctrl;
|
||||
|
||||
public int Load(BinaryReader fp, uint version)
|
||||
{
|
||||
int ret = -1;
|
||||
uint num = fp.ReadUInt32();
|
||||
lwKeyFloat[] seq = StructReader.ReadStructArray<lwKeyFloat>(fp, num);
|
||||
this._aks_ctrl = new lwAnimKeySetFloat();
|
||||
if (this._aks_ctrl.SetKeySequence(seq, num) >= 0)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwAnimDataTexUV
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x4 */
|
||||
public Matrix4x4[] _mat_seq;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint _frame_num;
|
||||
|
||||
public int Load(BinaryReader fp, uint version)
|
||||
{
|
||||
this._frame_num = fp.ReadUInt32();
|
||||
this._mat_seq = StructReader.ReadStructArray<Matrix4x4>(fp, this._frame_num);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwAnimDataTexUVSet
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
public lwAnimDataTexUV[] mtl;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwAnimDataTexImg
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x4 */
|
||||
public lwTexInfo[] _data_seq;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint _data_num;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)]
|
||||
/* this+0xc */
|
||||
public char[] _tex_path;
|
||||
|
||||
public int Load(BinaryReader fp, uint version)
|
||||
{
|
||||
int ret = 0;
|
||||
if (version == 0)
|
||||
{
|
||||
Debug.LogError("old version file, need re-export it");
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._data_num = fp.ReadUInt32();
|
||||
this._data_seq = StructReader.ReadStructArray<lwTexInfo>(fp, this._data_num);
|
||||
}
|
||||
|
||||
;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwAnimDataMtlOpacitySet
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public lwAnimDataMtlOpacity[] mtl;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwAnimDataTexImgSet
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
public lwAnimDataTexImg[] mtl;
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/Model/lwAnimDataInfo.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/Model/lwAnimDataInfo.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25c5131c55384e3ab69ff06cde9318ba
|
||||
timeCreated: 1728045346
|
129
Assets/MindPowerSdk/Model/lwHelperInfo.cs
Normal file
129
Assets/MindPowerSdk/Model/lwHelperInfo.cs
Normal file
@ -0,0 +1,129 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public class lwHelperInfo
|
||||
{
|
||||
/* this+0x4 */
|
||||
public uint type; // MindPower::lwHelperInfoType
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x8 */
|
||||
public lwHelperDummyInfo[] dummy_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0xc */
|
||||
public lwHelperBoxInfo[] box_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x10 */
|
||||
public lwHelperMeshInfo[] mesh_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x14 */
|
||||
public lwBoundingBoxInfo[] bbox_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x18 */
|
||||
public lwBoundingSphereInfo[] bsphere_seq;
|
||||
|
||||
/* this+0x1c */
|
||||
public uint dummy_num;
|
||||
|
||||
/* this+0x20 */
|
||||
public uint box_num;
|
||||
|
||||
/* this+0x24 */
|
||||
public uint mesh_num;
|
||||
|
||||
/* this+0x28 */
|
||||
public uint bbox_num;
|
||||
|
||||
/* this+0x2c */
|
||||
public uint bsphere_num;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct lwHelperDummyInfo
|
||||
{
|
||||
public uint Id;
|
||||
public Matrix4x4 Mat;
|
||||
public Matrix4x4 MatLocal;
|
||||
public uint ParentType; // 0: default, 1: bone parent, 2: bone dummy parent
|
||||
public uint ParentId;
|
||||
}
|
||||
|
||||
public struct lwHelperBoxInfo
|
||||
{
|
||||
public uint Id;
|
||||
public uint Type;
|
||||
public uint State;
|
||||
public Bounds Box;
|
||||
public Matrix4x4 Mat;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string Name; // 32
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwHelperMeshInfo
|
||||
{
|
||||
public uint Id;
|
||||
public uint Type;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string Name;
|
||||
|
||||
public uint State;
|
||||
public uint SubType;
|
||||
public Matrix4x4 Mat;
|
||||
public Bounds Box;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)] public Vector3[] VertexSeq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)] public lwHelperMeshFaceInfo[] face_seq;
|
||||
public uint vertex_num;
|
||||
public uint face_num;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwHelperMeshFaceInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public uint[] vertex;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public uint[] adj_face;
|
||||
|
||||
public Plane plane;
|
||||
|
||||
public Vector3 center;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwBoundingBoxInfo
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint id;
|
||||
|
||||
/* this+0x4 */
|
||||
public Bounds box;
|
||||
|
||||
/* this+0x1c */
|
||||
public Matrix4x4 mat;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwBoundingSphereInfo
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint id;
|
||||
|
||||
/* this+0x4 */
|
||||
public BoundingSphere sphere;
|
||||
|
||||
/* this+0x14 */
|
||||
public Matrix4x4 mat;
|
||||
};
|
||||
}
|
3
Assets/MindPowerSdk/Model/lwHelperInfo.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/Model/lwHelperInfo.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a597eb040b04616ab57eb9f3ab8ce8f
|
||||
timeCreated: 1728006798
|
545
Assets/MindPowerSdk/Model/lwModelObjInfo.cs
Normal file
545
Assets/MindPowerSdk/Model/lwModelObjInfo.cs
Normal file
@ -0,0 +1,545 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public enum ModelObjType : uint
|
||||
{
|
||||
Geometry = 1,
|
||||
Helper = 2
|
||||
}
|
||||
|
||||
public class lwModelObjInfo
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
struct lwModelObjInfoHeader
|
||||
{
|
||||
public ModelObjType Type;
|
||||
public uint Addr;
|
||||
public uint Size;
|
||||
}
|
||||
|
||||
public int GeomObjNum;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public lwGeomObjInfo[] GeomObjSeq; // 最多32个
|
||||
|
||||
public int Load(string file)
|
||||
{
|
||||
string filePath = Path.Combine(GlobalDefine.ClientDir, file);
|
||||
using FileStream fs = File.OpenRead(filePath);
|
||||
using BinaryReader fp = new BinaryReader(fs);
|
||||
|
||||
uint version = fp.ReadUInt32();
|
||||
int objNum = fp.ReadInt32();
|
||||
|
||||
lwModelObjInfoHeader[] header = new lwModelObjInfoHeader[objNum];
|
||||
for (int i = 0; i < objNum; i++)
|
||||
{
|
||||
var h = StructReader.ReadStruct<lwModelObjInfoHeader>(fp);
|
||||
header[i] = h;
|
||||
}
|
||||
|
||||
GeomObjNum = 0;
|
||||
GeomObjSeq = new lwGeomObjInfo[32];
|
||||
for (int i = 0; i < objNum; i++)
|
||||
{
|
||||
var headerInfo = header[i];
|
||||
fs.Seek(headerInfo.Addr, SeekOrigin.Begin);
|
||||
|
||||
switch (headerInfo.Type)
|
||||
{
|
||||
case ModelObjType.Geometry:
|
||||
{
|
||||
this.GeomObjSeq[GeomObjNum] = new lwGeomObjInfo();
|
||||
if (version == 0) // EXP_OBJ_VERSION_0_0_0_0
|
||||
{
|
||||
int old_version = fp.ReadInt32();
|
||||
}
|
||||
|
||||
this.GeomObjSeq[GeomObjNum].Load(fp, version);
|
||||
GeomObjNum += 1;
|
||||
break;
|
||||
}
|
||||
case ModelObjType.Helper:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public enum lwModelObjectLoadType
|
||||
{
|
||||
MODELOBJECT_LOAD_RESET = 0,
|
||||
MODELOBJECT_LOAD_MERGE = 1,
|
||||
MODELOBJECT_LOAD_MERGE2 = 2
|
||||
};
|
||||
|
||||
public struct lwRenderCtrlCreateInfo
|
||||
{
|
||||
public uint ctrl_id;
|
||||
public uint decl_id;
|
||||
public uint vs_id;
|
||||
public uint ps_id;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwStateCtrl
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
/* this+0x0 */
|
||||
public byte[] _state_seq; // MindPower::lwObjectStateEnum ???
|
||||
|
||||
public void SetState(uint state, byte value)
|
||||
{
|
||||
this._state_seq[state] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public class lwGeomObjInfo
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
/* this+0x4 */
|
||||
public struct lwGeomObjInfoHeader
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint id;
|
||||
|
||||
/* this+0x4 */
|
||||
public uint parent_id;
|
||||
|
||||
/* this+0x8 */
|
||||
public lwModelObjectLoadType type;
|
||||
|
||||
/* this+0xc */
|
||||
public Matrix4x4 mat_local;
|
||||
|
||||
/* this+0x4c */
|
||||
public lwRenderCtrlCreateInfo rcci;
|
||||
|
||||
/* this+0x5c */
|
||||
public lwStateCtrl state_ctrl;
|
||||
|
||||
/* this+0x64 */
|
||||
public uint mtl_size;
|
||||
|
||||
/* this+0x68 */
|
||||
public uint mesh_size;
|
||||
|
||||
/* this+0x6c */
|
||||
public uint helper_size;
|
||||
|
||||
/* this+0x70 */
|
||||
public uint anim_size;
|
||||
};
|
||||
|
||||
/* this+0x4 */
|
||||
public lwGeomObjInfoHeader header;
|
||||
|
||||
/* this+0x78 */
|
||||
public uint mtl_num;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x7c */
|
||||
public lwMtlTexInfo[] mtl_seq;
|
||||
|
||||
/* this+0x80 */
|
||||
public lwMeshInfo mesh;
|
||||
|
||||
/* this+0x130 */
|
||||
public lwHelperInfo helper_data;
|
||||
|
||||
/* this+0x160 */
|
||||
public lwAnimDataInfo anim_data;
|
||||
|
||||
public int Load(BinaryReader fp, uint version)
|
||||
{
|
||||
this.header = StructReader.ReadStruct<lwGeomObjInfoHeader>(fp);
|
||||
this.header.state_ctrl.SetState(5, 0);
|
||||
this.header.state_ctrl.SetState(3, 1);
|
||||
if (this.header.mtl_size > 100000)
|
||||
{
|
||||
// System.Windows.Forms.MessageBox.Show("iii", "error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this.header.mtl_size > 0)
|
||||
{
|
||||
// lwLoadMtlTexInfo(ref this.mtl_seq, ref this.mtl_num, fp, version);
|
||||
}
|
||||
|
||||
if (this.header.mesh_size > 0)
|
||||
{
|
||||
// lwMeshInfo_Load(ref this.mesh, fp, version);
|
||||
}
|
||||
|
||||
if (this.header.helper_size > 0)
|
||||
{
|
||||
// this.helper_data.Load(fp, version);
|
||||
}
|
||||
|
||||
if (this.header.anim_size > 0)
|
||||
{
|
||||
this.anim_data = new lwAnimDataInfo();
|
||||
// this.anim_data.Load(fp, version);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Load(string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return -1;
|
||||
FileStream fs = File.Open(file, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader fp = new BinaryReader(fs);
|
||||
|
||||
uint version = fp.ReadUInt32();
|
||||
int ret = this.Load(fp, version);
|
||||
fp.Close();
|
||||
fs.Close();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwMtlTexInfo
|
||||
{
|
||||
/* this+0x0 */
|
||||
public float opacity;
|
||||
|
||||
/* this+0x4 */
|
||||
[MarshalAs(UnmanagedType.U4)] public lwMtlTexInfoTransparencyTypeEnum transp_type; // MindPower::lwMtlTexInfoTransparencyTypeEnum
|
||||
|
||||
/* this+0x8 */
|
||||
public lwMaterial mtl;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
/* this+0x4c */
|
||||
public lwRenderStateAtom[] rs_set;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
/* this+0xac */
|
||||
public lwTexInfo[] tex_seq;
|
||||
}
|
||||
|
||||
public enum lwMtlTexInfoTransparencyTypeEnum
|
||||
{
|
||||
MTLTEX_TRANSP_FILTER = 0,
|
||||
MTLTEX_TRANSP_ADDITIVE = 1,
|
||||
MTLTEX_TRANSP_ADDITIVE1 = 2,
|
||||
MTLTEX_TRANSP_ADDITIVE2 = 3,
|
||||
MTLTEX_TRANSP_ADDITIVE3 = 4,
|
||||
MTLTEX_TRANSP_SUBTRACTIVE = 5,
|
||||
MTLTEX_TRANSP_SUBTRACTIVE1 = 6,
|
||||
MTLTEX_TRANSP_SUBTRACTIVE2 = 7,
|
||||
MTLTEX_TRANSP_SUBTRACTIVE3 = 8
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwMaterial
|
||||
{
|
||||
/* this+0x0 */
|
||||
public Color dif;
|
||||
|
||||
/* this+0x10 */
|
||||
public Color amb;
|
||||
|
||||
/* this+0x20 */
|
||||
public Color spe;
|
||||
|
||||
/* this+0x30 */
|
||||
public Color emi;
|
||||
|
||||
/* this+0x40 */
|
||||
public float power;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwRenderStateAtom
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint state; // MindPower::lwRenderStateAtomType
|
||||
|
||||
/* this+0x4 */
|
||||
public uint value0;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint value1;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class lwTexInfo
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint stage;
|
||||
|
||||
/* this+0x4 */
|
||||
public uint level;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint usage;
|
||||
|
||||
/* this+0xc */
|
||||
[MarshalAs(UnmanagedType.U4)] public _D3DFORMAT format;
|
||||
|
||||
/* this+0x10 */
|
||||
[MarshalAs(UnmanagedType.U4)] public _D3DPOOL pool;
|
||||
|
||||
/* this+0x14 */
|
||||
public uint byte_alignment_flag;
|
||||
|
||||
/* this+0x18 */
|
||||
[MarshalAs(UnmanagedType.U4)] public lwTexInfoTypeEnum type;
|
||||
|
||||
/* this+0x1c */
|
||||
public uint width;
|
||||
|
||||
/* this+0x20 */
|
||||
public uint height;
|
||||
|
||||
/* this+0x24 */
|
||||
[MarshalAs(UnmanagedType.U4)] public lwColorKeyTypeEnum colorkey_type;
|
||||
|
||||
/* this+0x28 */
|
||||
public Color32 colorkey;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
/* this+0x2c */
|
||||
public char[] file_name;
|
||||
|
||||
/* this+0x6c */
|
||||
public uint data_pointer;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
/* this+0x70 */
|
||||
public lwRenderStateAtom[] tss_set;
|
||||
};
|
||||
|
||||
public enum _D3DFORMAT
|
||||
{
|
||||
D3DFMT_UNKNOWN = 0x0,
|
||||
D3DFMT_R8G8B8 = 0x14,
|
||||
D3DFMT_A8R8G8B8 = 0x15,
|
||||
D3DFMT_X8R8G8B8 = 0x16,
|
||||
D3DFMT_R5G6B5 = 0x17,
|
||||
D3DFMT_X1R5G5B5 = 0x18,
|
||||
D3DFMT_A1R5G5B5 = 0x19,
|
||||
D3DFMT_A4R4G4B4 = 0x1a,
|
||||
D3DFMT_R3G3B2 = 0x1b,
|
||||
D3DFMT_A8 = 0x1c,
|
||||
D3DFMT_A8R3G3B2 = 0x1d,
|
||||
D3DFMT_X4R4G4B4 = 0x1e,
|
||||
D3DFMT_A2B10G10R10 = 0x1f,
|
||||
D3DFMT_G16R16 = 0x22,
|
||||
D3DFMT_A8P8 = 0x28,
|
||||
D3DFMT_P8 = 0x29,
|
||||
D3DFMT_L8 = 0x32,
|
||||
D3DFMT_A8L8 = 0x33,
|
||||
D3DFMT_A4L4 = 0x34,
|
||||
D3DFMT_V8U8 = 0x3c,
|
||||
D3DFMT_L6V5U5 = 0x3d,
|
||||
D3DFMT_X8L8V8U8 = 0x3e,
|
||||
D3DFMT_Q8W8V8U8 = 0x3f,
|
||||
D3DFMT_V16U16 = 0x40,
|
||||
D3DFMT_W11V11U10 = 0x41,
|
||||
D3DFMT_A2W10V10U10 = 0x43,
|
||||
D3DFMT_UYVY = 0x59565955,
|
||||
D3DFMT_YUY2 = 0x32595559,
|
||||
D3DFMT_DXT1 = 0x31545844,
|
||||
D3DFMT_DXT2 = 0x32545844,
|
||||
D3DFMT_DXT3 = 0x33545844,
|
||||
D3DFMT_DXT4 = 0x34545844,
|
||||
D3DFMT_DXT5 = 0x35545844,
|
||||
D3DFMT_D16_LOCKABLE = 0x46,
|
||||
D3DFMT_D32 = 0x47,
|
||||
D3DFMT_D15S1 = 0x49,
|
||||
D3DFMT_D24S8 = 0x4b,
|
||||
D3DFMT_D16 = 0x50,
|
||||
D3DFMT_D24X8 = 0x4d,
|
||||
D3DFMT_D24X4S4 = 0x4f,
|
||||
D3DFMT_VERTEXDATA = 0x64,
|
||||
D3DFMT_INDEX16 = 0x65,
|
||||
D3DFMT_INDEX32 = 0x66,
|
||||
D3DFMT_FORCE_DWORD = 0x7fffffff,
|
||||
}
|
||||
|
||||
public enum _D3DPOOL
|
||||
{
|
||||
D3DPOOL_DEFAULT = 0x0,
|
||||
D3DPOOL_MANAGED = 0x1,
|
||||
D3DPOOL_SYSTEMMEM = 0x2,
|
||||
D3DPOOL_SCRATCH = 0x3,
|
||||
D3DPOOL_FORCE_DWORD = 0x7fffffff,
|
||||
}
|
||||
|
||||
public enum lwTexInfoTypeEnum
|
||||
{
|
||||
TEX_TYPE_FILE = 0,
|
||||
TEX_TYPE_SIZE = 1,
|
||||
TEX_TYPE_DATA = 2,
|
||||
TEX_TYPE_INVALID = -1
|
||||
}
|
||||
|
||||
public enum lwColorKeyTypeEnum
|
||||
{
|
||||
COLORKEY_TYPE_NONE = 0,
|
||||
COLORKEY_TYPE_COLOR = 1,
|
||||
COLORKEY_TYPE_PIXEL = 2
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwMeshInfo
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwMeshInfoHeader
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint fvf;
|
||||
|
||||
/* this+0x4 */
|
||||
[MarshalAs(UnmanagedType.U4)] public _D3DPRIMITIVETYPE pt_type;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint vertex_num;
|
||||
|
||||
/* this+0xc */
|
||||
public uint index_num;
|
||||
|
||||
/* this+0x10 */
|
||||
public uint subset_num;
|
||||
|
||||
/* this+0x14 */
|
||||
public uint bone_index_num;
|
||||
|
||||
/* this+0x18 */
|
||||
public uint bone_infl_factor;
|
||||
|
||||
/* this+0x1c */
|
||||
public uint vertex_element_num;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
/* this+0x20 */
|
||||
public lwRenderStateAtom[] rs_set;
|
||||
};
|
||||
|
||||
/* this+0x0 */
|
||||
public lwMeshInfoHeader header;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x80 */
|
||||
public Vector3[] vertex_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x84 */
|
||||
public Vector3[] normal_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x88 */
|
||||
public Vector2[] texcoord0_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x8c */
|
||||
public Vector2[] texcoord1_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x90 */
|
||||
public Vector2[] texcoord2_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x94 */
|
||||
public Vector2[] texcoord3_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x98 */
|
||||
public uint[] vercol_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0x9c */
|
||||
public uint[] index_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0xa0 */
|
||||
public uint[] bone_index_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0xa4 */
|
||||
public lwBlendInfo[] blend_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0xa8 */
|
||||
public lwSubsetInfo[] subset_seq;
|
||||
|
||||
[MarshalAs(UnmanagedType.LPArray)]
|
||||
/* this+0xac */
|
||||
public _D3DVERTEXELEMENT9[] vertex_element_seq;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct _D3DVERTEXELEMENT9
|
||||
{
|
||||
/* this+0x0 */
|
||||
public ushort Stream;
|
||||
|
||||
/* this+0x2 */
|
||||
public ushort Offset;
|
||||
|
||||
/* this+0x4 */
|
||||
public byte Type;
|
||||
|
||||
/* this+0x5 */
|
||||
public byte Method;
|
||||
|
||||
/* this+0x6 */
|
||||
public byte Usage;
|
||||
|
||||
/* this+0x7 */
|
||||
public byte UsageIndex;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwSubsetInfo
|
||||
{
|
||||
/* this+0x0 */
|
||||
public uint primitive_num;
|
||||
|
||||
/* this+0x4 */
|
||||
public uint start_index;
|
||||
|
||||
/* this+0x8 */
|
||||
public uint vertex_num;
|
||||
|
||||
/* this+0xc */
|
||||
public uint min_index;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct lwBlendInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
/* this+0x0 */
|
||||
public byte[] index;
|
||||
|
||||
/* this+0x0 */
|
||||
//uint indexd;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
/* this+0x4 */
|
||||
public float[] weight;
|
||||
}
|
||||
|
||||
public enum _D3DPRIMITIVETYPE
|
||||
{
|
||||
D3DPT_POINTLIST = 0x1,
|
||||
D3DPT_LINELIST = 0x2,
|
||||
D3DPT_LINESTRIP = 0x3,
|
||||
D3DPT_TRIANGLELIST = 0x4,
|
||||
D3DPT_TRIANGLESTRIP = 0x5,
|
||||
D3DPT_TRIANGLEFAN = 0x6,
|
||||
D3DPT_FORCE_DWORD = 0x7fffffff,
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/Model/lwModelObjInfo.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/Model/lwModelObjInfo.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7614eb326704773a4cb56c1f021865e
|
||||
timeCreated: 1728005423
|
8
Assets/MindPowerSdk/Shaders.meta
generated
Normal file
8
Assets/MindPowerSdk/Shaders.meta
generated
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a9008836e9bf4a479d7599a8505c2d8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
58
Assets/MindPowerSdk/Shaders/TerrainFun.asset
generated
Normal file
58
Assets/MindPowerSdk/Shaders/TerrainFun.asset
generated
Normal file
@ -0,0 +1,58 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 78b2425a2284af743826c689403a4924, type: 3}
|
||||
m_Name: TerrainFun
|
||||
m_EditorClassIdentifier:
|
||||
m_functionInfo: "// Made with Amplify Shader Editor v1.9.8.1\n// Available at the
|
||||
Unity Asset Store - http://u3d.as/y3X \n/*ASEBEGIN\nVersion=19801\nNode;AmplifyShaderEditor.CommentaryNode;304;-1599.907,-2287.038;Inherit;False;1188;611;UV1;14;320;317;314;313;312;311;310;308;307;306;415;421;428;309;;1,1,1,1;0;0\nNode;AmplifyShaderEditor.CommentaryNode;315;-1808,-1632;Inherit;False;1372.458;352;UV2;13;424;418;337;422;423;342;349;431;429;434;432;430;330;;1,1,1,1;0;0\nNode;AmplifyShaderEditor.CommentaryNode;316;-1679.907,-1279.038;Inherit;False;916;352;UV3;7;338;331;327;324;323;322;425;;1,1,1,1;0;0\nNode;AmplifyShaderEditor.CommentaryNode;318;-3160.916,-735.0381;Inherit;False;1359.009;539.2149;Masks;20;414;413;412;411;391;386;381;373;372;369;365;354;352;344;341;335;334;329;326;420;;1,1,1,1;0;0\nNode;AmplifyShaderEditor.CommentaryNode;319;-3039.907,-1295.038;Inherit;False;1108;355;ColorLayers;11;390;385;370;366;353;348;339;332;328;325;419;;1,1,1,1;0;0\nNode;AmplifyShaderEditor.CommentaryNode;336;-703.907,-1263.038;Inherit;False;853.0714;283;MainColor;5;355;351;347;346;345;;1,1,1,1;0;0\nNode;AmplifyShaderEditor.FractNode;331;-1199.907,-1183.038;Inherit;True;1;0;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.CustomExpressionNode;332;-2367.907,-1247.038;Inherit;False;float
|
||||
idx = f * 64.0@$return round(idx)@;0;Create;1;True;f;FLOAT;0;In;;Inherit;False;GetTexNo;True;False;0;;False;1;0;FLOAT;0;False;1;INT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;334;-2639.907,-607.0381;Inherit;False;Mask2;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RangedFloatNode;335;-2607.907,-511.0381;Inherit;False;Constant;_Float11;Float
|
||||
1;7;0;Create;True;0;0;0;False;0;False;16;0;0;0;0;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;338;-1007.907,-1167.038;Inherit;False;UV3;-1;True;1;0;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;339;-2175.907,-1247.038;Inherit;False;layer1;-1;True;1;0;INT;0;False;1;INT;0\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;341;-2319.907,-607.0381;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RoundOpNode;344;-2175.907,-607.0381;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.GetLocalVarNode;345;-639.907,-1167.038;Inherit;False;338;UV3;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.GetLocalVarNode;346;-639.907,-1087.038;Inherit;False;339;layer1;1;0;OBJECT;;False;1;INT;0\nNode;AmplifyShaderEditor.GetLocalVarNode;347;-639.907,-1231.038;Inherit;False;340;TextureAtlas;1;0;OBJECT;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.CustomExpressionNode;348;-2367.907,-1183.038;Inherit;False;float
|
||||
idx = f * 64.0@$return round(idx)@;0;Create;1;True;f;FLOAT;0;In;;Inherit;False;GetTexNo;True;False;0;;False;1;0;FLOAT;0;False;1;INT;0\nNode;AmplifyShaderEditor.SamplerNode;351;-431.907,-1215.038;Inherit;True;Property;_mainText;mainText;0;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;LockedToTexture2DArray;False;Object;-1;Auto;Texture2DArray;8;0;SAMPLER2DARRAY;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.RegisterLocalVarNode;352;-2031.907,-607.0381;Inherit;False;Mask2Index;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;353;-2175.907,-1183.038;Inherit;False;layer2;-1;True;1;0;INT;0;False;1;INT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;354;-2623.907,-399.0381;Inherit;False;Mask3;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;355;-95.90698,-1183.038;Inherit;False;MainColor;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.GetLocalVarNode;356;-1231.907,-447.0381;Inherit;False;350;Mask
|
||||
Atlas;1;0;OBJECT;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.GetLocalVarNode;357;-1263.907,-687.0381;Inherit;False;340;TextureAtlas;1;0;OBJECT;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.GetLocalVarNode;358;-1263.907,-623.0381;Inherit;False;338;UV3;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.GetLocalVarNode;359;-1231.907,-367.0381;Inherit;False;349;UV2;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.GetLocalVarNode;360;-1240.909,-306.6033;Inherit;False;352;Mask2Index;1;0;OBJECT;;False;1;FLOAT;0\nNode;AmplifyShaderEditor.GetLocalVarNode;361;-1263.907,-543.0381;Inherit;False;353;layer2;1;0;OBJECT;;False;1;INT;0\nNode;AmplifyShaderEditor.SamplerNode;362;-1039.907,-415.0381;Inherit;True;Property;_Mask;Mask;1;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;LockedToTexture2DArray;False;Object;-1;Auto;Texture2DArray;8;0;SAMPLER2DARRAY;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.GetLocalVarNode;363;-943.907,-799.0381;Inherit;False;355;MainColor;1;0;OBJECT;;False;1;COLOR;0\nNode;AmplifyShaderEditor.SamplerNode;364;-1055.907,-671.0381;Inherit;True;Property;_mainText1;mainText;0;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;LockedToTexture2DArray;False;Object;-1;Auto;Texture2DArray;8;0;SAMPLER2DARRAY;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;365;-2319.907,-447.0381;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.CustomExpressionNode;366;-2367.907,-1119.038;Inherit;False;float
|
||||
idx = f * 64.0@$return round(idx)@;0;Create;1;True;f;FLOAT;0;In;;Inherit;False;GetTexNo;True;False;0;;False;1;0;FLOAT;0;False;1;INT;0\nNode;AmplifyShaderEditor.LerpOp;367;-607.907,-607.0381;Inherit;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.GetLocalVarNode;368;-728.9089,-914.6033;Inherit;False;353;layer2;1;0;OBJECT;;False;1;INT;0\nNode;AmplifyShaderEditor.RoundOpNode;369;-2159.907,-447.0381;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;370;-2175.907,-1119.038;Inherit;False;layer3;-1;True;1;0;INT;0;False;1;INT;0\nNode;AmplifyShaderEditor.ConditionalIfNode;371;-472.9089,-850.6033;Inherit;False;False;5;0;INT;0;False;1;FLOAT;0;False;2;COLOR;0,0,0,0;False;3;COLOR;0,0,0,0;False;4;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;372;-2015.907,-447.0381;Inherit;False;Mask3Index;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;373;-2623.907,-319.0381;Inherit;False;Mask4;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;374;-280.9089,-850.6033;Inherit;False;color2;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.GetLocalVarNode;375;-1240.909,-146.6033;Inherit;False;340;TextureAtlas;1;0;OBJECT;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.GetLocalVarNode;376;-1240.909,77.39673;Inherit;False;350;Mask
|
||||
Atlas;1;0;OBJECT;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.GetLocalVarNode;377;-1240.909,141.3967;Inherit;False;349;UV2;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.GetLocalVarNode;378;-1240.909,-82.60327;Inherit;False;338;UV3;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.GetLocalVarNode;379;-1240.909,221.3967;Inherit;False;372;Mask3Index;1;0;OBJECT;;False;1;FLOAT;0\nNode;AmplifyShaderEditor.GetLocalVarNode;380;-1240.909,-2.603271;Inherit;False;370;layer3;1;0;OBJECT;;False;1;INT;0\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;381;-2319.907,-351.0381;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.SamplerNode;382;-1032.909,-130.6033;Inherit;True;Property;_mainText2;mainText;0;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;LockedToTexture2DArray;False;Object;-1;Auto;Texture2DArray;8;0;SAMPLER2DARRAY;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.GetLocalVarNode;383;-728.9089,-162.6033;Inherit;False;374;color2;1;0;OBJECT;;False;1;COLOR;0\nNode;AmplifyShaderEditor.SamplerNode;384;-1032.909,93.39673;Inherit;True;Property;_mainText3;mainText;0;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;LockedToTexture2DArray;False;Object;-1;Auto;Texture2DArray;8;0;SAMPLER2DARRAY;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.CustomExpressionNode;385;-2367.907,-1055.038;Inherit;False;float
|
||||
idx = f * 64.0@$return round(idx)@;0;Create;1;True;f;FLOAT;0;In;;Inherit;False;GetTexNo;True;False;0;;False;1;0;FLOAT;0;False;1;INT;0\nNode;AmplifyShaderEditor.RoundOpNode;386;-2175.907,-351.0381;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.LerpOp;387;-520.9089,-66.60327;Inherit;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.GetLocalVarNode;388;-488.9089,-146.6033;Inherit;False;370;layer3;1;0;OBJECT;;False;1;INT;0\nNode;AmplifyShaderEditor.GetLocalVarNode;389;-488.9089,77.39673;Inherit;False;374;color2;1;0;OBJECT;;False;1;COLOR;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;390;-2175.907,-1055.038;Inherit;False;layer4;-1;True;1;0;INT;0;False;1;INT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;391;-2015.907,-351.0381;Inherit;False;Mask4Index;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.ConditionalIfNode;392;-264.9089,-98.60327;Inherit;False;False;5;0;INT;0;False;1;FLOAT;0;False;2;COLOR;0,0,0,0;False;3;COLOR;0,0,0,0;False;4;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;393;-168.9089,-242.6033;Inherit;False;color3;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.GetLocalVarNode;394;-831.907,368.9617;Inherit;False;340;TextureAtlas;1;0;OBJECT;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.GetLocalVarNode;395;-840.9089,429.3967;Inherit;False;338;UV3;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.GetLocalVarNode;396;-847.907,736.9617;Inherit;False;391;Mask4Index;1;0;OBJECT;;False;1;FLOAT;0\nNode;AmplifyShaderEditor.GetLocalVarNode;397;-831.907,656.9617;Inherit;False;349;UV2;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.GetLocalVarNode;398;-815.907,592.9617;Inherit;False;350;Mask
|
||||
Atlas;1;0;OBJECT;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.GetLocalVarNode;399;-863.907,512.9617;Inherit;False;390;layer4;1;0;OBJECT;;False;1;INT;0\nNode;AmplifyShaderEditor.SamplerNode;400;-639.907,400.9617;Inherit;True;Property;_Mask4;Mask;1;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;LockedToTexture2DArray;False;Object;-1;Auto;Texture2DArray;8;0;SAMPLER2DARRAY;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.SamplerNode;401;-623.907,624.9617;Inherit;True;Property;_Mask5;Mask;1;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;LockedToTexture2DArray;False;Object;-1;Auto;Texture2DArray;8;0;SAMPLER2DARRAY;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.GetLocalVarNode;402;-184.9089,125.3967;Inherit;False;393;color3;1;0;OBJECT;;False;1;COLOR;0\nNode;AmplifyShaderEditor.GetLocalVarNode;403;23.09106,301.3967;Inherit;False;393;color3;1;0;OBJECT;;False;1;COLOR;0\nNode;AmplifyShaderEditor.LerpOp;404;39.09106,125.3967;Inherit;False;3;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;2;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.GetLocalVarNode;405;71.09106,-2.603271;Inherit;False;390;layer4;1;0;OBJECT;;False;1;INT;0\nNode;AmplifyShaderEditor.ConditionalIfNode;406;263.0911,29.39673;Inherit;False;False;5;0;INT;0;False;1;FLOAT;0;False;2;COLOR;0,0,0,0;False;3;COLOR;0,0,0,0;False;4;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;407;423.0911,349.3967;Inherit;False;color3;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.BreakToComponentsNode;408;631.0911,349.3967;Inherit;False;COLOR;1;0;COLOR;0,0,0,0;False;16;FLOAT;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT;5;FLOAT;6;FLOAT;7;FLOAT;8;FLOAT;9;FLOAT;10;FLOAT;11;FLOAT;12;FLOAT;13;FLOAT;14;FLOAT;15\nNode;AmplifyShaderEditor.DynamicAppendNode;409;759.0911,349.3967;Inherit;False;FLOAT4;4;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;1;FLOAT4;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;410;983.0911,349.3967;Inherit;False;origion;-1;True;1;0;FLOAT4;0,0,0,0;False;1;FLOAT4;0\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;411;-2319.907,-703.0381;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RoundOpNode;412;-2175.907,-703.0381;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;413;-2031.907,-687.0381;Inherit;False;Mask1Index;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;414;-2639.907,-687.0381;Inherit;False;Mask1;-1;True;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.SamplerNode;329;-2960,-592;Inherit;True;Property;_MaskNo;MaskNo;28;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.GetLocalVarNode;325;-2992,-1152;Inherit;False;320;UV;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SamplerNode;328;-2783.907,-1231.038;Inherit;True;Property;_TexNo;TexNo;27;0;Create;True;0;0;0;False;0;False;-1;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;6;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT3;5\nNode;AmplifyShaderEditor.FunctionInput;419;-2992,-1248;Inherit;False;TexNo;9;3;False;1;0;SAMPLER2D;0;False;1;SAMPLER2D;0\nNode;AmplifyShaderEditor.GetLocalVarNode;326;-3135.907,-543.0381;Inherit;False;320;UV;1;0;OBJECT;;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.FunctionInput;420;-3136,-608;Inherit;False;MaskNo;9;4;False;1;0;SAMPLER2D;0;False;1;SAMPLER2D;0\nNode;AmplifyShaderEditor.FractNode;342;-1248,-1552;Inherit;True;1;0;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleDivideOpNode;327;-1311.907,-1087.038;Inherit;False;2;0;FLOAT2;0,0;False;1;FLOAT;0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.RangedFloatNode;324;-1471.907,-1023.038;Inherit;False;Constant;_Float10;Float
|
||||
0;7;0;Create;True;0;0;0;False;0;False;4;0;0;0;0;1;FLOAT;0\nNode;AmplifyShaderEditor.RangedFloatNode;423;-1520,-1424;Inherit;False;Constant;_Float12;Float
|
||||
0;7;0;Create;True;0;0;0;False;0;False;4;0;0;0;0;1;FLOAT;0\nNode;AmplifyShaderEditor.SimpleDivideOpNode;422;-1376,-1472;Inherit;False;2;0;FLOAT2;0,0;False;1;FLOAT;0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleAddOpNode;307;-1264,-2096;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.SimpleAddOpNode;308;-1264,-1984;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.SimpleDivideOpNode;310;-1072,-2192;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.SimpleDivideOpNode;311;-1072,-2000;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.TexelSizeNode;312;-1088,-1888;Inherit;False;4;Create;1;0;SAMPLER2D;;False;5;FLOAT4;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4\nNode;AmplifyShaderEditor.DynamicAppendNode;313;-912,-2064;Inherit;False;FLOAT2;4;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.DynamicAppendNode;314;-896,-1952;Inherit;False;FLOAT2;4;0;FLOAT;1;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleAddOpNode;317;-752,-2048;Inherit;False;2;2;0;FLOAT2;0,0;False;1;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;320;-608,-2080;Inherit;False;UV;-1;True;1;0;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.BreakToComponentsNode;421;-1408,-2112;Inherit;False;FLOAT2;1;0;FLOAT2;0,0;False;16;FLOAT;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT;5;FLOAT;6;FLOAT;7;FLOAT;8;FLOAT;9;FLOAT;10;FLOAT;11;FLOAT;12;FLOAT;13;FLOAT;14;FLOAT;15\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;337;-1520,-1568;Inherit;False;2;2;0;FLOAT2;0,0;False;1;FLOAT;0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;323;-1344,-1168;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.TextureCoordinatesNode;322;-1632,-1136;Inherit;False;0;-1;2;3;2;SAMPLER2D;;False;0;FLOAT2;1,1;False;1;FLOAT2;0,0;False;5;FLOAT2;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4\nNode;AmplifyShaderEditor.SimpleAddOpNode;425;-1504,-1248;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;1;False;1;FLOAT;0\nNode;AmplifyShaderEditor.FunctionInput;418;-1792,-1376;Inherit;False;Repeat;1;5;False;1;0;FLOAT;8;False;1;FLOAT;0\nNode;AmplifyShaderEditor.Vector2Node;306;-1520,-1904;Inherit;False;Constant;_Vector6;Vector
|
||||
0;6;0;Create;True;0;0;0;False;0;False;1,1;0,0;0;3;FLOAT2;0;FLOAT;1;FLOAT;2\nNode;AmplifyShaderEditor.SimpleSubtractOpNode;428;-1568,-2032;Inherit;False;2;0;FLOAT2;1,0;False;1;FLOAT2;1,1;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleAddOpNode;424;-1648,-1456;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;1;False;1;FLOAT;0\nNode;AmplifyShaderEditor.PosVertexDataNode;309;-1296,-2256;Inherit;False;1;0;5;FLOAT4;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4\nNode;AmplifyShaderEditor.FunctionInput;415;-1600,-2224;Inherit;False;TerrainSize;2;6;False;1;0;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;350;-16,-1440;Inherit;False;Mask
|
||||
Atlas;-1;True;1;0;SAMPLER2DARRAY;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.FunctionInput;416;-224,-1424;Inherit;False;Mask
|
||||
Atlas;12;2;False;1;0;SAMPLER2DARRAY;0;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;340;-32,-1600;Inherit;False;TextureAtlas;-1;True;1;0;SAMPLER2DARRAY;;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.FunctionInput;417;-256,-1568;Inherit;False;Texture
|
||||
Atlas;12;1;False;1;0;SAMPLER2DARRAY;0;False;1;SAMPLER2DARRAY;0\nNode;AmplifyShaderEditor.RegisterLocalVarNode;349;-560,-1568;Inherit;False;UV2;-1;True;1;0;FLOAT2;0,0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;430;-752,-1520;Inherit;False;2;2;0;FLOAT2;0,0;False;1;FLOAT;0;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleAddOpNode;431;-640,-1456;Inherit;False;2;2;0;FLOAT2;0,0;False;1;FLOAT;1;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.SimpleSubtractOpNode;429;-992,-1600;Inherit;False;2;0;FLOAT2;0,0;False;1;FLOAT;1;False;1;FLOAT2;0\nNode;AmplifyShaderEditor.RangedFloatNode;432;-1056,-1408;Inherit;False;Constant;_Float3;Float
|
||||
3;11;0;Create;True;0;0;0;False;0;False;0.5;0;0;0;0;1;FLOAT;0\nNode;AmplifyShaderEditor.FunctionInput;434;-848,-1360;Inherit;False;UVZoom;1;0;False;1;0;FLOAT;1;False;1;FLOAT;0\nNode;AmplifyShaderEditor.TextureCoordinatesNode;330;-1808,-1600;Inherit;False;0;-1;2;3;2;SAMPLER2D;;False;0;FLOAT2;1,1;False;1;FLOAT2;0,0;False;5;FLOAT2;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4\nNode;AmplifyShaderEditor.FunctionOutput;0;1440,320;Inherit;False;True;-1;OrigionColor;0;True;1;0;FLOAT4;0,0,0,0;False;1;FLOAT4;0\nWireConnection;331;0;327;0\nWireConnection;332;0;328;1\nWireConnection;334;0;329;2\nWireConnection;338;0;331;0\nWireConnection;339;0;332;0\nWireConnection;341;0;334;0\nWireConnection;341;1;335;0\nWireConnection;344;0;341;0\nWireConnection;348;0;328;2\nWireConnection;351;0;347;0\nWireConnection;351;1;345;0\nWireConnection;351;6;346;0\nWireConnection;352;0;344;0\nWireConnection;353;0;348;0\nWireConnection;354;0;329;3\nWireConnection;355;0;351;0\nWireConnection;362;0;356;0\nWireConnection;362;1;359;0\nWireConnection;362;6;360;0\nWireConnection;364;0;357;0\nWireConnection;364;1;358;0\nWireConnection;364;6;361;0\nWireConnection;365;0;335;0\nWireConnection;365;1;354;0\nWireConnection;366;0;328;3\nWireConnection;367;0;363;0\nWireConnection;367;1;364;5\nWireConnection;367;2;362;0\nWireConnection;369;0;365;0\nWireConnection;370;0;366;0\nWireConnection;371;0;368;0\nWireConnection;371;2;367;0\nWireConnection;371;3;363;0\nWireConnection;371;4;363;0\nWireConnection;372;0;369;0\nWireConnection;373;0;329;4\nWireConnection;374;0;371;0\nWireConnection;381;0;335;0\nWireConnection;381;1;373;0\nWireConnection;382;0;375;0\nWireConnection;382;1;378;0\nWireConnection;382;6;380;0\nWireConnection;384;0;376;0\nWireConnection;384;1;377;0\nWireConnection;384;6;379;0\nWireConnection;385;0;328;4\nWireConnection;386;0;381;0\nWireConnection;387;0;383;0\nWireConnection;387;1;382;0\nWireConnection;387;2;384;0\nWireConnection;390;0;385;0\nWireConnection;391;0;386;0\nWireConnection;392;0;388;0\nWireConnection;392;2;387;0\nWireConnection;392;3;389;0\nWireConnection;392;4;389;0\nWireConnection;393;0;392;0\nWireConnection;400;0;394;0\nWireConnection;400;1;395;0\nWireConnection;400;6;399;0\nWireConnection;401;0;398;0\nWireConnection;401;1;397;0\nWireConnection;401;6;396;0\nWireConnection;404;0;402;0\nWireConnection;404;1;400;0\nWireConnection;404;2;401;0\nWireConnection;406;0;405;0\nWireConnection;406;2;404;0\nWireConnection;406;3;403;0\nWireConnection;406;4;403;0\nWireConnection;407;0;406;0\nWireConnection;408;0;407;0\nWireConnection;409;0;408;0\nWireConnection;409;1;408;1\nWireConnection;409;2;408;2\nWireConnection;410;0;409;0\nWireConnection;411;0;414;0\nWireConnection;411;1;335;0\nWireConnection;412;0;411;0\nWireConnection;413;0;412;0\nWireConnection;414;0;329;1\nWireConnection;329;0;420;0\nWireConnection;329;1;326;0\nWireConnection;328;0;419;0\nWireConnection;328;1;325;0\nWireConnection;342;0;337;0\nWireConnection;327;0;323;0\nWireConnection;327;1;324;0\nWireConnection;422;0;337;0\nWireConnection;422;1;423;0\nWireConnection;307;0;421;0\nWireConnection;307;1;306;1\nWireConnection;308;0;421;1\nWireConnection;308;1;306;2\nWireConnection;310;0;309;1\nWireConnection;310;1;307;0\nWireConnection;311;0;309;3\nWireConnection;311;1;308;0\nWireConnection;313;0;310;0\nWireConnection;313;1;311;0\nWireConnection;314;1;312;4\nWireConnection;317;0;313;0\nWireConnection;317;1;314;0\nWireConnection;320;0;317;0\nWireConnection;421;0;428;0\nWireConnection;337;0;330;0\nWireConnection;337;1;424;0\nWireConnection;323;0;425;0\nWireConnection;323;1;322;0\nWireConnection;425;0;418;0\nWireConnection;428;0;415;0\nWireConnection;424;0;418;0\nWireConnection;350;0;416;0\nWireConnection;340;0;417;0\nWireConnection;349;0;431;0\nWireConnection;430;0;429;0\nWireConnection;430;1;434;0\nWireConnection;431;0;430;0\nWireConnection;431;1;432;0\nWireConnection;429;0;342;0\nWireConnection;429;1;432;0\nWireConnection;0;0;410;0\nASEEND*/\n//CHKSM=781FBD8CBE033EA181D08FF20BC953B50BC38506"
|
||||
m_functionName:
|
||||
m_description:
|
||||
m_additionalIncludes:
|
||||
m_additionalIncludes: []
|
||||
m_outsideIncludes: []
|
||||
m_additionalPragmas:
|
||||
m_additionalPragmas: []
|
||||
m_outsidePragmas: []
|
||||
m_additionalDirectives:
|
||||
m_validData: 0
|
||||
m_isDirty: 1
|
||||
m_moduleName: ' Additional Directives'
|
||||
m_independentModule: 1
|
||||
m_customEdited: 0
|
||||
m_additionalDirectives: []
|
||||
m_shaderFunctionDirectives: []
|
||||
m_nativeDirectives: []
|
||||
m_nativeDirectivesIndex: -1
|
||||
m_nativeDirectivesFoldout: 0
|
||||
m_directivesSaveItems: []
|
||||
m_nodeCategory: 0
|
||||
m_headerStyle: 1
|
||||
m_headerColor: {r: 1, g: 0.4, b: 0, a: 1}
|
||||
m_customNodeCategory:
|
||||
m_previewPosition: 0
|
||||
m_hidden: 0
|
||||
m_url:
|
8
Assets/MindPowerSdk/Shaders/TerrainFun.asset.meta
generated
Normal file
8
Assets/MindPowerSdk/Shaders/TerrainFun.asset.meta
generated
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edbc8b3738bf4f3408088b56c3cfd812
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
196
Assets/MindPowerSdk/Shaders/TerrainFunctions.hlsl
Normal file
196
Assets/MindPowerSdk/Shaders/TerrainFunctions.hlsl
Normal file
@ -0,0 +1,196 @@
|
||||
#ifndef TERRAIN_FUNCTIONS_INCLUDED
|
||||
#define TERRAIN_FUNCTIONS_INCLUDED
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
// 如果需要使用 Texture2DArray 类型,请确保 Shader 目标版本支持(例如 5.0 以上)
|
||||
// #pragma target 5.0
|
||||
|
||||
// 全局变量声明(在 Amplify Shader Editor 中可作为属性绑定使用)
|
||||
// 主贴图图集(2DArray)
|
||||
UNITY_DECLARE_TEX2DARRAY(_MainTex);
|
||||
// 贴图编号贴图(2D)
|
||||
sampler2D _TexNo;
|
||||
// 遮罩编号贴图(2D)
|
||||
sampler2D _MaskNo;
|
||||
// 遮罩图集(2DArray)
|
||||
UNITY_DECLARE_TEX2DARRAY(_MaskTex);
|
||||
|
||||
// 地形参数:x 表示宽度,z 表示高度(y/w 可忽略)
|
||||
float4 _TerrainSize;
|
||||
// 纹理重复系数
|
||||
float _Repeat;
|
||||
// UV 偏移(防止采样边界问题)
|
||||
float _UVOffsetX;
|
||||
float _UVOffsetY;
|
||||
// 采样时的 texel 尺寸(由 Unity 自动传入)
|
||||
float4 _TexNo_TexelSize;
|
||||
float4 _MaskNo_TexelSize;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 计算全局 UV(根据世界坐标和地形尺寸)
|
||||
// worldPos.x 对应宽度方向,worldPos.z 对应高度方向
|
||||
float2 ComputeGlobalUV(float3 worldPos)
|
||||
{
|
||||
return float2(worldPos.x / (_TerrainSize.x + 1.0), worldPos.z / (_TerrainSize.z + 1.0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 将从 _TexNo 中采样到的数值转换为图集层号(0~64 内的整数)
|
||||
int GetTexNo(float f)
|
||||
{
|
||||
return (int)round(f * 64.0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 混合函数:从主图集中采样指定图层,并根据遮罩图集的采样结果进行混合
|
||||
// (使用全局变量版本)
|
||||
// @param color 当前颜色
|
||||
// @param maskTexuv 用于遮罩图集采样的 UV
|
||||
// @param mainTexuv 用于主图集采样的局部 UV
|
||||
// @param mask 遮罩值(对应 _MaskNo 中的通道)
|
||||
// @param layer 主图集的图层号
|
||||
float4 Blend(float4 color, float2 maskTexuv, float2 mainTexuv, float mask, int layer)
|
||||
{
|
||||
float4 col2 = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(mainTexuv, layer));
|
||||
int idx = (int)round(mask * 16.0);
|
||||
maskTexuv += float2(_UVOffsetX, _UVOffsetY);
|
||||
float4 maskTexCol = UNITY_SAMPLE_TEX2DARRAY(_MaskTex, float3(maskTexuv, idx));
|
||||
return lerp(color, col2, maskTexCol);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 调试用混合测试函数(返回遮罩图集采样结果)
|
||||
// @param color 当前颜色(仅用于占位)
|
||||
// @param uv 用于遮罩采样的 UV
|
||||
// @param mask 遮罩值
|
||||
// @param layer 贴图层号
|
||||
float4 BlendTest(float4 color, float2 uv, float mask, int layer)
|
||||
{
|
||||
int idx = (int)round(mask * 16.0);
|
||||
uv += float2(_UVOffsetX, _UVOffsetY);
|
||||
return UNITY_SAMPLE_TEX2DARRAY(_MaskTex, float3(uv, idx));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 主混合函数(使用全局变量):根据 _TexNo 与 _MaskNo 中采样的编号和遮罩值混合出最终颜色
|
||||
// @param globalUV 全局 UV(例如由 ComputeGlobalUV 得来,用于 _TexNo 与 _MaskNo 采样)
|
||||
// @param localUV 局部 UV(例如每个 tile 内的局部坐标,用于主图集采样)
|
||||
// @return 混合后的最终颜色
|
||||
float4 TerrainBlend(float2 globalUV, float2 localUV)
|
||||
{
|
||||
// 调整 UV(增加偏移以保证采样精度)
|
||||
float2 uvAdjusted = globalUV + float2(0, _TexNo_TexelSize.y);
|
||||
float4 texNo = tex2D(_TexNo, uvAdjusted);
|
||||
|
||||
int layer1 = GetTexNo(texNo.r);
|
||||
int layer2 = GetTexNo(texNo.g);
|
||||
int layer3 = GetTexNo(texNo.b);
|
||||
int layer4 = GetTexNo(texNo.a);
|
||||
|
||||
float4 maskNo = tex2D(_MaskNo, uvAdjusted);
|
||||
|
||||
// 局部 UV:uv2 用于遮罩采样,mainTextureUV2 用于主图集采样
|
||||
float2 uv2 = frac(localUV * _Repeat);
|
||||
float2 mainTextureUV2 = frac(localUV * (_Repeat / 4.0));
|
||||
|
||||
// 先采样第一层
|
||||
float4 col = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(mainTextureUV2, layer1));
|
||||
|
||||
if (layer2 > 0)
|
||||
{
|
||||
col = Blend(col, uv2, mainTextureUV2, maskNo.g, layer2);
|
||||
}
|
||||
if (layer3 > 0)
|
||||
{
|
||||
col = Blend(col, uv2, mainTextureUV2, maskNo.b, layer3);
|
||||
}
|
||||
if (layer4 > 0)
|
||||
{
|
||||
col = Blend(col, uv2, mainTextureUV2, maskNo.a, layer4);
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 新的函数入口:提供所有参数(不依赖全局变量)
|
||||
// 2DArray 类型参数采用 HLSL 原生类型 Texture2DArray + SamplerState(需要 Shader Model 5.0 支持)
|
||||
// @param globalUV 全局 UV 坐标(例如由世界坐标计算得到)
|
||||
// @param localUV 局部 UV 坐标(例如 tile 内坐标)
|
||||
// @param _MainTexParam 主贴图图集(2DArray 贴图对象)
|
||||
// @param _MainTexSamplerParam 主贴图采样状态
|
||||
// @param _TexNoParam 贴图编号贴图(2D 采样器)
|
||||
// @param _MaskNoParam 遮罩编号贴图(2D 采样器)
|
||||
// @param _MaskTexParam 遮罩图集(2DArray 贴图对象)
|
||||
// @param _MaskTexSamplerParam 遮罩图集采样状态
|
||||
// @param TerrainSizeParam 地形尺寸(float4,x为宽度,z为高度)
|
||||
// @param RepeatParam 纹理重复系数
|
||||
// @param UVOffsetXParam UV X轴偏移
|
||||
// @param UVOffsetYParam UV Y轴偏移
|
||||
// @param TexNo_TexelSizeParam _TexNo 贴图的 texel 尺寸(float4)
|
||||
// @param MaskNo_TexelSizeParam _MaskNo 贴图的 texel 尺寸(float4)
|
||||
// @return 最终混合后的颜色
|
||||
float4 TerrainBlendFull(
|
||||
float2 globalUV,
|
||||
float2 localUV,
|
||||
uniform Texture2DArray _MainTexParam,
|
||||
uniform SamplerState _MainTexSamplerParam,
|
||||
sampler2D _TexNoParam,
|
||||
sampler2D _MaskNoParam,
|
||||
uniform Texture2DArray _MaskTexParam,
|
||||
uniform SamplerState _MaskTexSamplerParam,
|
||||
float4 TerrainSizeParam,
|
||||
float RepeatParam,
|
||||
float UVOffsetXParam,
|
||||
float UVOffsetYParam,
|
||||
float4 TexNo_TexelSizeParam,
|
||||
float4 MaskNo_TexelSizeParam
|
||||
)
|
||||
{
|
||||
// 调整 UV 用于 _TexNo 与 _MaskNo 的采样
|
||||
float2 uvAdjusted = globalUV + float2(0, TexNo_TexelSizeParam.y);
|
||||
float4 texNo = tex2D(_TexNoParam, uvAdjusted);
|
||||
|
||||
int layer1 = (int)round(texNo.r * 64.0);
|
||||
int layer2 = (int)round(texNo.g * 64.0);
|
||||
int layer3 = (int)round(texNo.b * 64.0);
|
||||
int layer4 = (int)round(texNo.a * 64.0);
|
||||
|
||||
float4 maskNo = tex2D(_MaskNoParam, uvAdjusted);
|
||||
|
||||
// 计算局部 UV(用于主贴图与遮罩采样)
|
||||
float2 uv2 = frac(localUV * RepeatParam);
|
||||
float2 mainTextureUV2 = frac(localUV * (RepeatParam / 4.0));
|
||||
|
||||
// 从主贴图图集中采样第一层
|
||||
float4 col = _MainTexParam.Sample(_MainTexSamplerParam, float3(mainTextureUV2, layer1));
|
||||
|
||||
// 内联 Blend 逻辑(采用 .Sample() 方法)
|
||||
if (layer2 > 0)
|
||||
{
|
||||
int idx = (int)round(maskNo.g * 16.0);
|
||||
float2 maskUV = uv2 + float2(UVOffsetXParam, UVOffsetYParam);
|
||||
float4 col2 = _MainTexParam.Sample(_MainTexSamplerParam, float3(mainTextureUV2, layer2));
|
||||
float4 maskTexCol = _MaskTexParam.Sample(_MaskTexSamplerParam, float3(maskUV, idx));
|
||||
col = lerp(col, col2, maskTexCol);
|
||||
}
|
||||
if (layer3 > 0)
|
||||
{
|
||||
int idx = (int)round(maskNo.b * 16.0);
|
||||
float2 maskUV = uv2 + float2(UVOffsetXParam, UVOffsetYParam);
|
||||
float4 col2 = _MainTexParam.Sample(_MainTexSamplerParam, float3(mainTextureUV2, layer3));
|
||||
float4 maskTexCol = _MaskTexParam.Sample(_MaskTexSamplerParam, float3(maskUV, idx));
|
||||
col = lerp(col, col2, maskTexCol);
|
||||
}
|
||||
if (layer4 > 0)
|
||||
{
|
||||
int idx = (int)round(maskNo.a * 16.0);
|
||||
float2 maskUV = uv2 + float2(UVOffsetXParam, UVOffsetYParam);
|
||||
float4 col2 = _MainTexParam.Sample(_MainTexSamplerParam, float3(mainTextureUV2, layer4));
|
||||
float4 maskTexCol = _MaskTexParam.Sample(_MaskTexSamplerParam, float3(maskUV, idx));
|
||||
col = lerp(col, col2, maskTexCol);
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
#endif // TERRAIN_FUNCTIONS_INCLUDED
|
9
Assets/MindPowerSdk/Shaders/TerrainFunctions.hlsl.meta
generated
Normal file
9
Assets/MindPowerSdk/Shaders/TerrainFunctions.hlsl.meta
generated
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed643d6a6e16c9144bda5f1bf73be0a5
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/MindPowerSdk/Table.meta
generated
Normal file
8
Assets/MindPowerSdk/Table.meta
generated
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54e2e9de63e54934f96d36655faa2667
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
66
Assets/MindPowerSdk/Table/CRawDataSet.cs
Normal file
66
Assets/MindPowerSdk/Table/CRawDataSet.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using MindPowerSdk;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public abstract class CRawDataInfo
|
||||
{
|
||||
public int bExist;
|
||||
public int nIndex;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 72)]
|
||||
public string szDataName;
|
||||
|
||||
public uint dwLastUseTick;
|
||||
public int bEnable;
|
||||
public uint pData;
|
||||
public uint dwPackOffset;
|
||||
public uint dwDataSize;
|
||||
public int nID;
|
||||
public uint dwLoadCnt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有的配置数据,读取方式都是一样的(只要布局好结构)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class CRawDataSet<T> where T : CRawDataInfo
|
||||
{
|
||||
public T[] Data { get; private set; }
|
||||
|
||||
private Dictionary<int, int> _idMap;
|
||||
|
||||
public void LoadBin(string file)
|
||||
{
|
||||
using var fs = File.OpenRead(file);
|
||||
using BinaryReader reader = new BinaryReader(fs);
|
||||
|
||||
long fileSize = fs.Length;
|
||||
uint infoSize = reader.ReadUInt32();
|
||||
|
||||
int resNum = (int)(fileSize / infoSize);
|
||||
Debug.Log($"{file} - {infoSize}({resNum})");
|
||||
|
||||
Data = new T[resNum];
|
||||
_idMap = new Dictionary<int, int>(resNum);
|
||||
for (int i = 0; i < resNum; i++)
|
||||
{
|
||||
byte[] data = reader.ReadBytes((int)infoSize);
|
||||
T info = StructReader.ReadStructFromArray<T>(data);
|
||||
Data[i] = info;
|
||||
_idMap.Add(info.nID, i);
|
||||
//Debug.Log(JsonConvert.SerializeObject(info));
|
||||
}
|
||||
}
|
||||
|
||||
public T Get(int id)
|
||||
{
|
||||
return Data[_idMap[id]];
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Table/CRawDataSet.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Table/CRawDataSet.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cabe265ec2e2ae143b9a60dbcffc1a4e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
92
Assets/MindPowerSdk/Table/CSceneObjInfo.cs
Normal file
92
Assets/MindPowerSdk/Table/CSceneObjInfo.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct CRawColor
|
||||
{
|
||||
public byte R, G, B;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
|
||||
public sealed class CSceneObjInfo : CRawDataInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
|
||||
public string Name; // char[16]
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// </summary>
|
||||
public int Type;
|
||||
|
||||
/// <summary>
|
||||
/// 点光源颜色
|
||||
/// </summary>
|
||||
public CRawColor PointColor; // byte[3]
|
||||
|
||||
/// <summary>
|
||||
/// 环境光颜色
|
||||
/// </summary>
|
||||
public CRawColor EnvColor; // byte[3]
|
||||
|
||||
/// <summary>
|
||||
/// 雾颜色
|
||||
/// </summary>
|
||||
public CRawColor FogColor; // byte[3]
|
||||
|
||||
public int Range;
|
||||
public float Attenuation1;
|
||||
|
||||
/// <summary>
|
||||
/// 点光源动画类型id
|
||||
/// </summary>
|
||||
public int AnimCtrlID;
|
||||
|
||||
/// <summary>
|
||||
/// 风格
|
||||
/// </summary>
|
||||
public int Style;
|
||||
|
||||
public int AttachEffectID;
|
||||
|
||||
/// <summary>
|
||||
/// 是否收点光源影响
|
||||
/// </summary>
|
||||
public bool EnablePointLight;
|
||||
|
||||
/// <summary>
|
||||
/// 是否收环境光影响
|
||||
/// </summary>
|
||||
public bool EnableEnvLight;
|
||||
|
||||
/// <summary>
|
||||
/// 其它标记
|
||||
/// </summary>
|
||||
public int Flag;
|
||||
|
||||
/// <summary>
|
||||
/// 尺寸标记, 如果物件是超大尺寸, 则可见性判断特殊
|
||||
/// </summary>
|
||||
public int SizeFlag;
|
||||
|
||||
/// <summary>
|
||||
/// char[11]
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
|
||||
public string EnvSound;
|
||||
|
||||
public int EnvSoundDis; // 单位:厘米
|
||||
public int PhotoTexID; // 图标贴图ID
|
||||
public bool ShadeFlag;
|
||||
public bool IsReallyBig; // 是否特大物件,Added by clp
|
||||
|
||||
public int FadeObjNum;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public int[] FadeObjSeq;
|
||||
|
||||
public float FadeCoefficent;
|
||||
}
|
||||
}
|
11
Assets/MindPowerSdk/Table/CSceneObjInfo.cs.meta
generated
Normal file
11
Assets/MindPowerSdk/Table/CSceneObjInfo.cs.meta
generated
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 633eae2d15904444b9ffc44ada376087
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
12
Assets/MindPowerSdk/Table/CSceneObjSet.cs
Normal file
12
Assets/MindPowerSdk/Table/CSceneObjSet.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public sealed class CSceneObjSet : CRawDataSet<CSceneObjInfo>
|
||||
{
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/Table/CSceneObjSet.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/Table/CSceneObjSet.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ea575bf5c5649319567acf6e5589fa5
|
||||
timeCreated: 1727947862
|
7
Assets/MindPowerSdk/TerrainGeneratorDynamic.cs
Normal file
7
Assets/MindPowerSdk/TerrainGeneratorDynamic.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace MindPowerSdk
|
||||
{
|
||||
public class TerrainGeneratorDynamic
|
||||
{
|
||||
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/TerrainGeneratorDynamic.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/TerrainGeneratorDynamic.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfc23c162f5d445da6992e5a350ca005
|
||||
timeCreated: 1742990892
|
170
Assets/MindPowerSdk/TerrainGeneratorWithAtlas.cs
Normal file
170
Assets/MindPowerSdk/TerrainGeneratorWithAtlas.cs
Normal file
@ -0,0 +1,170 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using MindPowerSdk;
|
||||
|
||||
public static class TerrainGeneratorWithAtlas
|
||||
{
|
||||
/// <summary>
|
||||
/// 利用 MPMap 数据生成 Terrain,采用原生 Terrain 的 splat map 混合方式。
|
||||
/// 参数 terrainLayers 必须包含 4 个层,每个层用打包好的图集贴图
|
||||
/// </summary>
|
||||
public static void GenTerrain(MPMap map, int chunkSize, Transform parent)
|
||||
{
|
||||
// 计算全局高度范围(归一化用)
|
||||
(float globalMin, float globalMax) = ComputeGlobalHeightRange(map);
|
||||
|
||||
int xCnt = Mathf.CeilToInt((float)map.Width / chunkSize);
|
||||
int yCnt = Mathf.CeilToInt((float)map.Height / chunkSize);
|
||||
|
||||
for (int i = 0; i < yCnt; i++)
|
||||
{
|
||||
for (int j = 0; j < xCnt; j++)
|
||||
{
|
||||
int startX = j * chunkSize;
|
||||
int startY = i * chunkSize;
|
||||
// 为保证边界内不越界,右侧和上侧减1
|
||||
int endX = Mathf.Min(startX + chunkSize, map.Width - 1);
|
||||
int endY = Mathf.Min(startY + chunkSize, map.Height - 1);
|
||||
int resX = (endX - startX) + 1; // 横向瓦片数
|
||||
int resY = (endY - startY) + 1; // 纵向瓦片数
|
||||
|
||||
// 为了保证生成的 Terrain 与原始地图高度一致,并且位置正确,需要使用固定分辨率
|
||||
int newRes = 33;
|
||||
|
||||
// 创建 TerrainData,设置高度图和混合图分辨率以及尺寸
|
||||
TerrainData terrainData = new TerrainData();
|
||||
terrainData.heightmapResolution = newRes;
|
||||
terrainData.alphamapResolution = newRes;
|
||||
terrainData.size = new Vector3((resX - 1), globalMax - globalMin, (resY - 1));
|
||||
|
||||
// 生成高度图(归一化到 [0,1])
|
||||
float[,] heights = GenerateHeightMap(map, startX, startY, resX, resY, newRes, globalMin, globalMax);
|
||||
terrainData.SetHeights(0, 0, heights);
|
||||
|
||||
|
||||
// 生成 Terrain 游戏对象并设置位置
|
||||
GameObject terrainGO = Terrain.CreateTerrainGameObject(terrainData);
|
||||
terrainGO.name = $"terrain_{i}_{j}";
|
||||
terrainGO.transform.parent = parent;
|
||||
// 将 Terrain 的 Y 坐标设置为 globalMin,使高度值正确偏移
|
||||
terrainGO.transform.position = new Vector3(startX, globalMin, startY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static float[,] GenerateHeightMap(MPMap map, int startX, int startY, int resX, int resY, int newRes,
|
||||
float globalMin, float globalMax)
|
||||
{
|
||||
// 采集原始高度数据,并归一化到 [0,1]
|
||||
float[,] fullHeights = new float[resY, resX];
|
||||
for (int z = 0; z < resY; z++)
|
||||
{
|
||||
for (int x = 0; x < resX; x++)
|
||||
{
|
||||
int worldX = startX + x;
|
||||
int worldY = startY + z;
|
||||
MPTile tile = map.GetTile(worldX, worldY);
|
||||
float norm = (globalMax - globalMin) > 0 ? (tile.Height - globalMin) / (globalMax - globalMin) : 0f;
|
||||
fullHeights[z, x] = norm;
|
||||
}
|
||||
}
|
||||
|
||||
// 利用双三次插值生成新分辨率高度图
|
||||
float[,] resampled = new float[newRes, newRes];
|
||||
float scaleX = (float)(resX - 1) / (newRes - 1);
|
||||
float scaleY = (float)(resY - 1) / (newRes - 1);
|
||||
for (int z = 0; z < newRes; z++)
|
||||
{
|
||||
float origZ = z * scaleY;
|
||||
for (int x = 0; x < newRes; x++)
|
||||
{
|
||||
float origX = x * scaleX;
|
||||
resampled[z, x] = BicubicInterpolate(fullHeights, origX, origZ, resX, resY);
|
||||
}
|
||||
}
|
||||
return resampled;
|
||||
float[,] smoothed = ApplyGaussianBlur(resampled, newRes, newRes);
|
||||
return smoothed;
|
||||
}
|
||||
|
||||
private static float BicubicInterpolate(float[,] data, float x, float z, int resX, int resY)
|
||||
{
|
||||
int xInt = Mathf.FloorToInt(x);
|
||||
int zInt = Mathf.FloorToInt(z);
|
||||
float s = x - xInt;
|
||||
float t = z - zInt;
|
||||
float[] arr = new float[4];
|
||||
for (int m = -1; m <= 2; m++)
|
||||
{
|
||||
int sampleZ = Mathf.Clamp(zInt + m, 0, resY - 1);
|
||||
float p0 = data[sampleZ, Mathf.Clamp(xInt - 1, 0, resX - 1)];
|
||||
float p1 = data[sampleZ, Mathf.Clamp(xInt, 0, resX - 1)];
|
||||
float p2 = data[sampleZ, Mathf.Clamp(xInt + 1, 0, resX - 1)];
|
||||
float p3 = data[sampleZ, Mathf.Clamp(xInt + 2, 0, resX - 1)];
|
||||
arr[m + 1] = CubicInterpolate(p0, p1, p2, p3, s);
|
||||
}
|
||||
|
||||
return CubicInterpolate(arr[0], arr[1], arr[2], arr[3], t);
|
||||
}
|
||||
|
||||
private static float CubicInterpolate(float p0, float p1, float p2, float p3, float t)
|
||||
{
|
||||
float a0 = p3 - p2 - p0 + p1;
|
||||
float a1 = p0 - p1 - a0;
|
||||
float a2 = p2 - p0;
|
||||
float a3 = p1;
|
||||
return ((a0 * t + a1) * t + a2) * t + a3;
|
||||
}
|
||||
|
||||
private static float[,] ApplyGaussianBlur(float[,] data, int width, int height)
|
||||
{
|
||||
float[,] result = new float[height, width];
|
||||
int kernelSize = 3;
|
||||
int kernelRadius = kernelSize / 2;
|
||||
float[,] kernel = new float[,]
|
||||
{
|
||||
{ 1f, 2f, 1f },
|
||||
{ 2f, 4f, 2f },
|
||||
{ 1f, 2f, 1f }
|
||||
};
|
||||
float kernelSum = 16f;
|
||||
for (int z = 0; z < height; z++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
float sum = 0f;
|
||||
for (int kz = -kernelRadius; kz <= kernelRadius; kz++)
|
||||
{
|
||||
int sampleZ = Mathf.Clamp(z + kz, 0, height - 1);
|
||||
for (int kx = -kernelRadius; kx <= kernelRadius; kx++)
|
||||
{
|
||||
int sampleX = Mathf.Clamp(x + kx, 0, width - 1);
|
||||
float weight = kernel[kz + kernelRadius, kx + kernelRadius];
|
||||
sum += data[sampleZ, sampleX] * weight;
|
||||
}
|
||||
}
|
||||
|
||||
result[z, x] = sum / kernelSum;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static (float, float) ComputeGlobalHeightRange(MPMap map)
|
||||
{
|
||||
float min = float.MaxValue;
|
||||
float max = float.MinValue;
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
float h = map.GetTile(x, y).Height;
|
||||
if (h < min) min = h;
|
||||
if (h > max) max = h;
|
||||
}
|
||||
}
|
||||
|
||||
return (min, max);
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/TerrainGeneratorWithAtlas.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/TerrainGeneratorWithAtlas.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1dcc7510be4497185a95f550ad91239
|
||||
timeCreated: 1742905680
|
64
Assets/MindPowerSdk/TerrainLayerUtility.cs
Normal file
64
Assets/MindPowerSdk/TerrainLayerUtility.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using MindPowerSdk;
|
||||
using UnityEngine;
|
||||
|
||||
public static class AtlasBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 将 textures 中的贴图每 countPerAtlas 张打包成一个图集,默认图集尺寸为 2048。
|
||||
/// </summary>
|
||||
/// <param name="textures">所有原始贴图,数量应为 countPerAtlas 的倍数</param>
|
||||
/// <param name="countPerAtlas">每个图集中包含的贴图数量(例如 16)</param>
|
||||
/// <param name="atlasSize">图集尺寸</param>
|
||||
/// <returns>打包好的图集数组</returns>
|
||||
public static Texture2D[] BuildAtlases(Texture2D[] textures, int countPerAtlas, int atlasSize = 2048)
|
||||
{
|
||||
int atlasCount = textures.Length / countPerAtlas;
|
||||
Texture2D[] atlases = new Texture2D[atlasCount];
|
||||
for (int i = 0; i < atlasCount; i++)
|
||||
{
|
||||
Texture2D atlas = new Texture2D(atlasSize, atlasSize, TextureFormat.RGBA32, false);
|
||||
Texture2D[] group = new Texture2D[countPerAtlas];
|
||||
for (int j = 0; j < countPerAtlas; j++)
|
||||
{
|
||||
group[j] = textures[i * countPerAtlas + j];
|
||||
}
|
||||
|
||||
// 自动打包,第二个参数表示边距(像素),atlasSize 限制最大尺寸
|
||||
atlas.PackTextures(group, 2, atlasSize);
|
||||
atlases[i] = atlas;
|
||||
}
|
||||
|
||||
return atlases;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TerrainLayerBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 从 4 个图集创建 TerrainLayer,每个图集对应一个层
|
||||
/// </summary>
|
||||
/// <param name="atlases">必须包含 4 个图集</param>
|
||||
/// <returns>TerrainLayer 数组</returns>
|
||||
public static TerrainLayer[] BuildTerrainLayers(Texture2D[] atlases)
|
||||
{
|
||||
if (atlases.Length != 4)
|
||||
{
|
||||
Debug.LogError("期望传入 4 个图集贴图");
|
||||
return null;
|
||||
}
|
||||
|
||||
TerrainLayer[] layers = new TerrainLayer[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
TerrainLayer tl = new TerrainLayer();
|
||||
tl.diffuseTexture = atlases[i];
|
||||
// 假设图集内为 4×4 布局,每个子贴图尺寸为 atlas 尺寸的 1/4
|
||||
tl.tileSize = new Vector2(tl.diffuseTexture.width / 4f, tl.diffuseTexture.height / 4f);
|
||||
layers[i] = tl;
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
}
|
3
Assets/MindPowerSdk/TerrainLayerUtility.cs.meta
generated
Normal file
3
Assets/MindPowerSdk/TerrainLayerUtility.cs.meta
generated
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbd5813c39bc470784f6d1ec6b802817
|
||||
timeCreated: 1742979746
|
Reference in New Issue
Block a user