1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
public class MeshNormalSmoothWindow : EditorWindow
{
[MenuItem("Window/MeshNormalSmoothWindow")]
static void Init()
{
MeshNormalSmoothWindow window = (MeshNormalSmoothWindow)EditorWindow.GetWindow(typeof(MeshNormalSmoothWindow));
window.Show();
}
Mesh mesh;
void OnGUI()
{
EditorGUILayout.BeginVertical();
mesh = EditorGUILayout.ObjectField("mesh", mesh, typeof(Mesh), true) as Mesh;
if (GUILayout.Button("convert"))
{
Vector3[] vertices = mesh.vertices;
int[] triangles = mesh.triangles;
int polygonNum = mesh.triangles.Length / 3;
Vector3[] polyNormals = new Vector3[polygonNum];
for (int i = 0; i < polygonNum; i++)
{
int vid0 = triangles[i * 3];
int vid1 = triangles[i * 3 + 1];
int vid2 = triangles[i * 3 + 2];
// 乘以1000避免数值过小时计算结果为0
polyNormals[i] = Vector3.Cross((vertices[vid1] - vertices[vid0])*1000, (vertices[vid2] - vertices[vid0])*1000).normalized;
}
int vertexNum = mesh.vertices.Length;
Vector3[] normals = new Vector3[vertexNum];
for (int i = 0; i < vertexNum; i++)
{
normals[i] = Vector3.zero;
}
for (int i = 0; i < polygonNum; i++)
{
int vid0 = triangles[i * 3];
int vid1 = triangles[i * 3 + 1];
int vid2 = triangles[i * 3 + 2];
// 这里可以使用Dictionary来进行优化,那么不用进行整个顶点的遍历;
// 因此需要将Vector3作为Dictionary的Key来使用;
// Dictionary中添加自定义Key的方法为:
// https://stackoverflow.com/questions/6999191/use-custom-object-as-dictionary-key
// https://www.codeproject.com/Articles/23610/Dictionary-with-a-Custom-Key
// 因为Vector3的Equals方法是精确匹配,只有“==”的实现是非精确匹配;因此不适合使用Vector3来作为Key使用;
// 参考https://docs.unity3d.com/ScriptReference/Vector3.Equals.html
for (int j = 0; j < vertexNum; j++)
{
if(vertices[j] == vertices[vid0])
{
normals[j] += polyNormals[i];
}
if(vertices[j] == vertices[vid1])
{
normals[j] += polyNormals[i];
}
if(vertices[j] == vertices[vid2])
{
normals[j] += polyNormals[i];
}
}
}
for (int i = 0; i < vertexNum; i++)
{
normals[i].Normalize();
}
Mesh newmesh = new Mesh();
newmesh.vertices = mesh.vertices;
newmesh.triangles = mesh.triangles;
newmesh.normals = normals;
newmesh.uv = mesh.uv;
newmesh.uv2 = mesh.uv2;
newmesh.boneWeights = mesh.boneWeights;
newmesh.bindposes = mesh.bindposes;
AssetDatabase.CreateAsset(newmesh, "Assets/test.asset");
AssetDatabase.Refresh();
}
EditorGUILayout.EndVertical();
}
}
|