Signed-off-by: TRAfoer <lhf190@outlook.com>
This commit is contained in:
@@ -2,6 +2,7 @@ using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System;
|
||||
|
||||
namespace Dreamteck
|
||||
{
|
||||
@@ -23,77 +24,153 @@ namespace Dreamteck
|
||||
int nbFaces = x * (z - 1);
|
||||
if (reallocateArray && triangles.Length != nbFaces * 6)
|
||||
{
|
||||
if(startTriangleIndex > 0)
|
||||
if (startTriangleIndex > 0)
|
||||
{
|
||||
int[] newTris = new int[startTriangleIndex + nbFaces * 6];
|
||||
for(int i = 0; i < startTriangleIndex; i++) newTris[i] = triangles[i];
|
||||
for (int i = 0; i < startTriangleIndex; i++) newTris[i] = triangles[i];
|
||||
triangles = newTris;
|
||||
} else triangles = new int[nbFaces * 6];
|
||||
}
|
||||
else triangles = new int[nbFaces * 6];
|
||||
}
|
||||
int g = x + 1;
|
||||
int t = startTriangleIndex;
|
||||
for (int face = 0; face < nbFaces + z - 2; face++)
|
||||
|
||||
// for (int face = 0; face < nbFaces + z - 2; face++)
|
||||
// {
|
||||
// if ((float)(face + 1) % (float)g == 0f && face != 0) face++;
|
||||
// if (flip)
|
||||
// {
|
||||
// triangles[t++] = face + x + 1 + startVertex;
|
||||
// triangles[t++] = face + 1 + startVertex;
|
||||
// triangles[t++] = face + startVertex;
|
||||
|
||||
// triangles[t++] = face + x + 1 + startVertex;
|
||||
// triangles[t++] = face + x + 2 + startVertex;
|
||||
// triangles[t++] = face + 1 + startVertex;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// triangles[t++] = face + startVertex;
|
||||
// triangles[t++] = face + 1 + startVertex;
|
||||
// triangles[t++] = face + x + 1 + startVertex;
|
||||
|
||||
// triangles[t++] = face + 1 + startVertex;
|
||||
// triangles[t++] = face + x + 2 + startVertex;
|
||||
// triangles[t++] = face + x + 1 + startVertex;
|
||||
// }
|
||||
// }
|
||||
|
||||
int index = 0;
|
||||
for (int row = 0; row < z - 1; row++)
|
||||
{
|
||||
if ((float)(face + 1) % (float)g == 0f && face != 0) face++;
|
||||
if (flip)
|
||||
for (int col = 0; col < x; col++)
|
||||
{
|
||||
triangles[t++] = face + x + 1 + startVertex;
|
||||
triangles[t++] = face + 1 + startVertex;
|
||||
triangles[t++] = face + startVertex;
|
||||
int i = row * (x + 1) + col;
|
||||
|
||||
triangles[t++] = face + x + 1 + startVertex;
|
||||
triangles[t++] = face + x + 2 + startVertex;
|
||||
triangles[t++] = face + 1 + startVertex;
|
||||
}
|
||||
else
|
||||
{
|
||||
triangles[t++] = face + startVertex;
|
||||
triangles[t++] = face + 1 + startVertex;
|
||||
triangles[t++] = face + x + 1 + startVertex;
|
||||
if (flip)
|
||||
{
|
||||
triangles[index++] = i + x + 1;
|
||||
triangles[index++] = i + 1;
|
||||
triangles[index++] = i;
|
||||
|
||||
triangles[t++] = face + 1 + startVertex;
|
||||
triangles[t++] = face + x + 2 + startVertex;
|
||||
triangles[t++] = face + x + 1 + startVertex;
|
||||
triangles[index++] = i + x + 1;
|
||||
triangles[index++] = i + x + 2;
|
||||
triangles[index++] = i + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
triangles[index++] = i + startVertex;
|
||||
triangles[index++] = i + 1 + startVertex;
|
||||
triangles[index++] = i + x + 1 + startVertex;
|
||||
|
||||
triangles[index++] = i + 1 + startVertex;
|
||||
triangles[index++] = i + x + 2 + startVertex;
|
||||
triangles[index++] = i + x + 1 + startVertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return triangles;
|
||||
}
|
||||
|
||||
public static void CalculateTangents(TS_Mesh mesh)
|
||||
{
|
||||
int vertexCount = mesh.vertexCount;
|
||||
int triangleCount = mesh.triangles.Length / 3;
|
||||
if (mesh.tangents.Length != mesh.vertexCount) mesh.tangents = new Vector4[mesh.vertexCount];
|
||||
if (tan1.Length != mesh.vertexCount)
|
||||
|
||||
// 优化1:数组重用与按需分配
|
||||
if (tan1.Length < vertexCount)
|
||||
{
|
||||
tan1 = new Vector3[mesh.vertexCount];
|
||||
tan2 = new Vector3[mesh.vertexCount];
|
||||
tan1 = new Vector3[vertexCount];
|
||||
tan2 = new Vector3[vertexCount];
|
||||
}
|
||||
else
|
||||
{
|
||||
// 重用数组但需要清零
|
||||
Array.Clear(tan1, 0, vertexCount);
|
||||
Array.Clear(tan2, 0, vertexCount);
|
||||
}
|
||||
|
||||
int tri = 0;
|
||||
// 优化2:避免重复访问属性
|
||||
Vector3[] vertices = mesh.vertices;
|
||||
Vector2[] uvs = mesh.uv;
|
||||
Vector3[] normals = mesh.normals;
|
||||
int[] triangles = mesh.triangles;
|
||||
|
||||
// 优化3:预先检查数组长度
|
||||
if (uvs.Length < vertexCount || normals.Length < vertexCount)
|
||||
{
|
||||
Debug.LogError("UV or Normal array size mismatch");
|
||||
return;
|
||||
}
|
||||
|
||||
// 优化4:缓存变量减少重复计算
|
||||
Vector3 edge1 = Vector3.zero;
|
||||
Vector3 edge2 = Vector3.zero;
|
||||
Vector2 uvEdge1 = Vector2.zero;
|
||||
Vector2 uvEdge2 = Vector2.zero;
|
||||
|
||||
// 优化5:循环展开减少分支预测失败
|
||||
for (int i = 0; i < triangleCount; i++)
|
||||
{
|
||||
int i1 = mesh.triangles[tri];
|
||||
int i2 = mesh.triangles[tri + 1];
|
||||
int i3 = mesh.triangles[tri + 2];
|
||||
int triIndex = i * 3;
|
||||
int i1 = triangles[triIndex];
|
||||
int i2 = triangles[triIndex + 1];
|
||||
int i3 = triangles[triIndex + 2];
|
||||
|
||||
float x1 = mesh.vertices[i2].x - mesh.vertices[i1].x;
|
||||
float x2 = mesh.vertices[i3].x - mesh.vertices[i1].x;
|
||||
float y1 = mesh.vertices[i2].y - mesh.vertices[i1].y;
|
||||
float y2 = mesh.vertices[i3].y - mesh.vertices[i1].y;
|
||||
float z1 = mesh.vertices[i2].z - mesh.vertices[i1].z;
|
||||
float z2 = mesh.vertices[i3].z - mesh.vertices[i1].z;
|
||||
// 计算边向量
|
||||
edge1.x = vertices[i2].x - vertices[i1].x;
|
||||
edge1.y = vertices[i2].y - vertices[i1].y;
|
||||
edge1.z = vertices[i2].z - vertices[i1].z;
|
||||
|
||||
float s1 = mesh.uv[i2].x - mesh.uv[i1].x;
|
||||
float s2 = mesh.uv[i3].x - mesh.uv[i1].x;
|
||||
float t1 = mesh.uv[i2].y - mesh.uv[i1].y;
|
||||
float t2 = mesh.uv[i3].y - mesh.uv[i1].y;
|
||||
edge2.x = vertices[i3].x - vertices[i1].x;
|
||||
edge2.y = vertices[i3].y - vertices[i1].y;
|
||||
edge2.z = vertices[i3].z - vertices[i1].z;
|
||||
|
||||
float div = s1 * t2 - s2 * t1;
|
||||
float r = div == 0f ? 0f : 1f / div;
|
||||
// 计算UV差
|
||||
uvEdge1.x = uvs[i2].x - uvs[i1].x;
|
||||
uvEdge1.y = uvs[i2].y - uvs[i1].y;
|
||||
|
||||
Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
|
||||
Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
|
||||
uvEdge2.x = uvs[i3].x - uvs[i1].x;
|
||||
uvEdge2.y = uvs[i3].y - uvs[i1].y;
|
||||
|
||||
// 优化6:避免除零检查的分支预测
|
||||
float div = uvEdge1.x * uvEdge2.y - uvEdge2.x * uvEdge1.y;
|
||||
float r = Mathf.Abs(div) < Mathf.Epsilon ? 0f : 1f / div;
|
||||
|
||||
// 计算切线向量
|
||||
Vector3 sdir = new Vector3(
|
||||
(uvEdge2.y * edge1.x - uvEdge1.y * edge2.x) * r,
|
||||
(uvEdge2.y * edge1.y - uvEdge1.y * edge2.y) * r,
|
||||
(uvEdge2.y * edge1.z - uvEdge1.y * edge2.z) * r
|
||||
);
|
||||
|
||||
Vector3 tdir = new Vector3(
|
||||
(uvEdge1.x * edge2.x - uvEdge2.x * edge1.x) * r,
|
||||
(uvEdge1.x * edge2.y - uvEdge2.x * edge1.y) * r,
|
||||
(uvEdge1.x * edge2.z - uvEdge2.x * edge1.z) * r
|
||||
);
|
||||
|
||||
// 累加到顶点
|
||||
tan1[i1] += sdir;
|
||||
tan1[i2] += sdir;
|
||||
tan1[i3] += sdir;
|
||||
@@ -101,22 +178,30 @@ namespace Dreamteck
|
||||
tan2[i1] += tdir;
|
||||
tan2[i2] += tdir;
|
||||
tan2[i3] += tdir;
|
||||
|
||||
tri += 3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mesh.vertexCount; i++)
|
||||
// 优化7:确保切线数组已分配
|
||||
if (mesh.tangents == null || mesh.tangents.Length != vertexCount)
|
||||
{
|
||||
Vector3 n = mesh.normals[i];
|
||||
mesh.tangents = new Vector4[vertexCount];
|
||||
}
|
||||
|
||||
// 优化8:手动Gram-Schmidt正交化
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
Vector3 n = normals[i];
|
||||
Vector3 t = tan1[i];
|
||||
Vector3.OrthoNormalize(ref n, ref t);
|
||||
mesh.tangents[i].x = t.x;
|
||||
mesh.tangents[i].y = t.y;
|
||||
mesh.tangents[i].z = t.z;
|
||||
mesh.tangents[i].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[i]) < 0.0f) ? -1.0f : 1.0f;
|
||||
|
||||
// 手动正交化 (比Vector3.OrthoNormalize更高效)
|
||||
t = (t - n * Vector3.Dot(n, t)).normalized;
|
||||
|
||||
// 计算副法线方向
|
||||
Vector3 b = Vector3.Cross(n, t);
|
||||
float w = (Vector3.Dot(b, tan2[i]) < 0.0f) ? -1.0f : 1.0f;
|
||||
|
||||
mesh.tangents[i] = new Vector4(t.x, t.y, t.z, w);
|
||||
}
|
||||
}
|
||||
|
||||
public static void MakeDoublesided(Mesh input)
|
||||
{
|
||||
Vector3[] vertices = input.vertices;
|
||||
@@ -206,7 +291,7 @@ namespace Dreamteck
|
||||
Color[] newColors = new Color[colors.Length * 2];
|
||||
int[] newTris = new int[triangles.Length * 2];
|
||||
List<int[]> newSubmeshes = new List<int[]>();
|
||||
for(int i = 0; i < submeshes.Count; i++)
|
||||
for (int i = 0; i < submeshes.Count; i++)
|
||||
{
|
||||
newSubmeshes.Add(new int[submeshes[i].Length * 2]);
|
||||
submeshes[i].CopyTo(newSubmeshes[i], 0);
|
||||
@@ -217,7 +302,7 @@ namespace Dreamteck
|
||||
newVertices[i] = vertices[i];
|
||||
newNormals[i] = normals[i];
|
||||
newUvs[i] = uvs[i];
|
||||
if(colors.Length > i) newColors[i] = colors[i];
|
||||
if (colors.Length > i) newColors[i] = colors[i];
|
||||
|
||||
newVertices[i + vertices.Length] = vertices[i];
|
||||
newNormals[i + vertices.Length] = -normals[i];
|
||||
@@ -239,9 +324,9 @@ namespace Dreamteck
|
||||
newTris[i + triangles.Length + 2] = index1 + vertices.Length;
|
||||
}
|
||||
|
||||
for(int i = 0; i < submeshes.Count; i++)
|
||||
for (int i = 0; i < submeshes.Count; i++)
|
||||
{
|
||||
for(int n = 0; n < submeshes[i].Length; n+= 3)
|
||||
for (int n = 0; n < submeshes[i].Length; n += 3)
|
||||
{
|
||||
int index1 = submeshes[i][n];
|
||||
int index2 = submeshes[i][n + 1];
|
||||
@@ -349,7 +434,7 @@ namespace Dreamteck
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("g " + mesh.name +"\n");
|
||||
sb.Append("g " + mesh.name + "\n");
|
||||
foreach (Vector3 v in mesh.vertices)
|
||||
{
|
||||
numVertices++;
|
||||
|
||||
Reference in New Issue
Block a user