mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-13 17:48:21 +00:00
临时提交
This commit is contained in:
307
JNFrame2/Assets/HotScripts/JNGame/Editor/EditorCreateLUT.cs
Normal file
307
JNFrame2/Assets/HotScripts/JNGame/Editor/EditorCreateLUT.cs
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* @FileName: EditorCreateLUT.cs
|
||||
* @Date: 2024-04-20 20:06:14
|
||||
* @LastEditTime: 2024-04-22 22:15:46
|
||||
* @Description: 生成三角函数速查表代码
|
||||
*/
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace JNGame.Math
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑模式下生成三角函数速查表代码
|
||||
/// </summary>
|
||||
public static class EditorCreateLUT
|
||||
{
|
||||
#region Unit Test
|
||||
|
||||
//[MenuItem("LockstepEngine/Math/TestAllLut")]
|
||||
private static void TestAllLut()
|
||||
{
|
||||
TestSqrt(10000);
|
||||
TestSqrt(65535);
|
||||
TestSqrt(65536);
|
||||
TestSqrt(0xffffffff);
|
||||
TestSqrt(1000002L * 1000001L);
|
||||
TestLutATan();
|
||||
TestATan2();
|
||||
TestLutASin();
|
||||
TestLutACos();
|
||||
TestLutSin();
|
||||
TestLutCos();
|
||||
}
|
||||
|
||||
private static void TestSqrt(ulong t)
|
||||
{
|
||||
var val = LMath.Sqrt(t);
|
||||
UnityEngine.Debug.Log($"sqrt({t}) = {val}");
|
||||
return;
|
||||
}
|
||||
|
||||
//[MenuItem("LockstepEngine/Math/TestLutATan")]
|
||||
private static void TestLutATan()
|
||||
{
|
||||
TestLut((i) => i, (i) => Mathf.Atan(i), (i) => LMath.Atan(i.ToLFloat()));
|
||||
}
|
||||
|
||||
private static void TestLutASin()
|
||||
{
|
||||
TestLut((i) => i * 0.001f, (p) => Mathf.Asin(p), (p) => LMath.Asin(p.ToLFloat()));
|
||||
}
|
||||
|
||||
private static void TestLutACos()
|
||||
{
|
||||
TestLut((i) => i * 0.001f, (p) => Mathf.Acos(p), (p) => LMath.Acos(p.ToLFloat()));
|
||||
}
|
||||
|
||||
private static void TestLutSin()
|
||||
{
|
||||
TestLut((i) => i * 0.001f * Mathf.PI * 2 - Mathf.PI, (p) => Mathf.Sin(p), (p) => LMath.Sin(p.ToLFloat()));
|
||||
}
|
||||
|
||||
private static void TestLutCos()
|
||||
{
|
||||
TestLut((i) => i * 0.001f * Mathf.PI * 2 - Mathf.PI, (p) => Mathf.Cos(p), (p) => LMath.Cos(p.ToLFloat()));
|
||||
}
|
||||
|
||||
private static void TestLut(Func<int, float> funcPar, Func<float, float> rawFunc, Func<float, LFloat> lFunc)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int testSize1 = 1000;
|
||||
for (int i = 1; i < testSize1; i++)
|
||||
{
|
||||
var par = funcPar(i);
|
||||
var rawVal = rawFunc(par);
|
||||
var myVal = lFunc(par).ToFloat();
|
||||
var diff = rawVal - myVal;
|
||||
if (diff > 0.01f)
|
||||
{
|
||||
sb.AppendLine($"i:{i} diff:{diff}");
|
||||
}
|
||||
}
|
||||
|
||||
UnityEngine.Debug.Log(sb.ToString());
|
||||
}
|
||||
|
||||
//[MenuItem("LockstepEngine/Math/TestATan2")]
|
||||
private static void TestATan2()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
var v1 = Mathf.Atan2(1, 1);
|
||||
var v2 = Mathf.Atan2(1, -1);
|
||||
var v3 = Mathf.Atan2(-1, -1);
|
||||
var v4 = Mathf.Atan2(-1, 1);
|
||||
|
||||
int testSize = 100;
|
||||
for (int y = -testSize; y < testSize; y++)
|
||||
{
|
||||
for (int x = -testSize; x < testSize; x++)
|
||||
{
|
||||
var rawVal = Mathf.Atan2(y, x);
|
||||
var myVal = LMath.Atan2(y, x); // new LFloat(true, LMath._Atan2(y, x)).ToFloat();
|
||||
var diff = rawVal - myVal;
|
||||
if (diff > 0.01f)
|
||||
{
|
||||
sb.AppendLine($"y:{y} x:{x} diff:{diff}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UnityEngine.Debug.Log(sb.ToString());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Code Generator
|
||||
/// <summary>
|
||||
/// 代码生成路径
|
||||
/// </summary>
|
||||
private static readonly string s_LUTDir = Application.dataPath + "/HotScripts/JNGame/Root/Math/LUT/";
|
||||
|
||||
/// <summary>
|
||||
/// 生成三角函数速查表代码文件
|
||||
/// </summary>
|
||||
[MenuItem("LockstepEngine/Math/CreateAllLUT")]
|
||||
static void CreateAllLUT()
|
||||
{
|
||||
CreateLutAtan2();
|
||||
CreateLUTASinCos();
|
||||
}
|
||||
|
||||
private static readonly string s_FilePrefixStr = @"
|
||||
//#define DONT_USE_GENERATE_CODE
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by JNGame.CodeGenerator
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
";
|
||||
private static void CreateLutAtan2()
|
||||
{
|
||||
var fileName = s_LUTDir + "LUTAtan2.cs";
|
||||
string content = @"
|
||||
using System;
|
||||
using JNGame.Math;
|
||||
namespace JNGame.Math
|
||||
{
|
||||
public static class LUTAtan2
|
||||
{
|
||||
public const int MaxQueryIdx = $MAX_QUERY_IDX;//Abs(y/x)from 1 to MaxQueryIdx
|
||||
|
||||
public static int[] _startIdx;
|
||||
public static int[] _arySize;
|
||||
public static int[] _tblTbl;
|
||||
|
||||
static LUTAtan2()
|
||||
{
|
||||
_startIdx = new int[MaxQueryIdx +1]{
|
||||
$START_IDX
|
||||
};
|
||||
_arySize = new int[MaxQueryIdx +1]{
|
||||
$ARY_SIZE
|
||||
};
|
||||
_tblTbl = new int[]{
|
||||
$ALL_VALUES
|
||||
};
|
||||
}
|
||||
}
|
||||
}";
|
||||
const int MaxQueryIdx = 1000;
|
||||
const int interval = 1000;
|
||||
// UnityEngine.Debug.LogError("tan Pi/4 = " + Mathf.Tan(Mathf.PI / 4));
|
||||
// UnityEngine.Debug.LogError("atan 1 = " + Mathf.Atan(1) * Mathf.Rad2Deg);
|
||||
StringBuilder ssb = new StringBuilder();
|
||||
StringBuilder aryLne = new StringBuilder();
|
||||
int sum = 0;
|
||||
StringBuilder tblSb = new StringBuilder();
|
||||
StringBuilder startSb = new StringBuilder();
|
||||
StringBuilder arySizeSb = new StringBuilder();
|
||||
string sprefix = "\t\t\t\t";
|
||||
tblSb.Append(sprefix);
|
||||
startSb.Append(sprefix);
|
||||
arySizeSb.Append(sprefix);
|
||||
for (int i = 0; i < MaxQueryIdx; i++)
|
||||
{
|
||||
var val = Mathf.Atan(i + 1) * Mathf.Rad2Deg;
|
||||
var val2 = Mathf.Atan(i + 2) * Mathf.Rad2Deg;
|
||||
var arryLen = (int)((val2 - val) * interval);
|
||||
if (arryLen == 0)
|
||||
{
|
||||
arryLen = 1;
|
||||
}
|
||||
|
||||
startSb.Append(sum + ", ");
|
||||
arySizeSb.Append(arryLen + ", ");
|
||||
for (int j = 0; j < arryLen; j++)
|
||||
{
|
||||
var rad = Mathf.Atan(i + 1 + (j * 1.0f / arryLen));
|
||||
tblSb.Append((int)(rad * LFloat.Precision) + ", ");
|
||||
sum++;
|
||||
if (sum % 100 == 0)
|
||||
{
|
||||
tblSb.AppendLine();
|
||||
tblSb.Append(sprefix);
|
||||
}
|
||||
}
|
||||
|
||||
if (i % 100 == 99)
|
||||
{
|
||||
startSb.AppendLine();
|
||||
arySizeSb.AppendLine();
|
||||
startSb.Append(sprefix);
|
||||
arySizeSb.Append(sprefix);
|
||||
}
|
||||
}
|
||||
|
||||
startSb.Append("" + (sum + 1));
|
||||
arySizeSb.Append("" + 1);
|
||||
tblSb.Append("" + (int)(Mathf.PI / 4 * LFloat.Precision));
|
||||
content = content
|
||||
.Replace("$MAX_QUERY_IDX", MaxQueryIdx.ToString())
|
||||
.Replace("$START_IDX", startSb.ToString())
|
||||
.Replace("$ARY_SIZE", arySizeSb.ToString())
|
||||
.Replace("$ALL_VALUES", tblSb.ToString());
|
||||
|
||||
//save to files
|
||||
File.WriteAllText(fileName, s_FilePrefixStr + content);
|
||||
AssetDatabase.Refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
private static void CreateLUTASinCos()
|
||||
{
|
||||
int ACount = 4000;
|
||||
CreateLUTA("LUTAsin", ACount, (i) =>
|
||||
Mathf.Asin(Mathf.Clamp(-1.0f + i * 2.0f / ACount, -1f, 1f))
|
||||
);
|
||||
CreateLUTA("LUTAcos", ACount, (i) =>
|
||||
Mathf.Acos(Mathf.Clamp(-1.0f + i * 2.0f / ACount, -1f, 1f))
|
||||
);
|
||||
int CCount = 7200;
|
||||
CreateLUTA("LUTCos", CCount, (i) =>
|
||||
Mathf.Cos(i * Mathf.PI * 2 / CCount)
|
||||
);
|
||||
CreateLUTA("LUTSin", CCount, (i) =>
|
||||
Mathf.Sin(i * Mathf.PI * 2 / CCount)
|
||||
);
|
||||
}
|
||||
|
||||
private static void CreateLUTA(string clsName, int nLutAryCount, Func<int, float> itemCallBack)
|
||||
{
|
||||
var fileName = s_LUTDir + clsName + ".cs";
|
||||
string content = @"using System;
|
||||
using JNGame.Math;
|
||||
namespace JNGame.Math
|
||||
{
|
||||
public static class $CLS_NAME
|
||||
{
|
||||
public static readonly int COUNT;
|
||||
public static readonly int HALF_COUNT;
|
||||
public static readonly int[] table;
|
||||
static $CLS_NAME()
|
||||
{
|
||||
COUNT = $COUNT_VAL;
|
||||
HALF_COUNT = COUNT >> 1;
|
||||
table = new int[]
|
||||
{
|
||||
$ALL_VALUES
|
||||
};
|
||||
}
|
||||
}
|
||||
}";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string prefix = "\t\t\t\t";
|
||||
sb.Append(prefix);
|
||||
for (int i = 0; i <= nLutAryCount; i++)
|
||||
{
|
||||
int val = (int)(itemCallBack(i) * LFloat.Precision);
|
||||
sb.Append(val.ToString() + ",");
|
||||
if (i % 100 == 99)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.Append(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
content = content
|
||||
.Replace("$CLS_NAME", clsName.ToString())
|
||||
.Replace("$COUNT_VAL", nLutAryCount.ToString())
|
||||
.Replace("$ALL_VALUES", sb.ToString());
|
||||
//save to files
|
||||
File.WriteAllText(fileName, s_FilePrefixStr + content);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5eb54a96f1904df2a6494a7d56f65aa5
|
||||
timeCreated: 1732460759
|
||||
Reference in New Issue
Block a user