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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
using UnityEngine;
using UnityEditor;
public class TerrainToMeshWindow : EditorWindow
{
[MenuItem("Window/TerrainToMeshWindow")]
static void Init()
{
TerrainToMeshWindow window = (TerrainToMeshWindow)EditorWindow.GetWindow(typeof(TerrainToMeshWindow));
window.Show();
}
int row = 5;
int column = 5;
Terrain terrain = null;
void OnGUI()
{
EditorGUILayout.BeginVertical();
terrain = EditorGUILayout.ObjectField("terrain", terrain, typeof(Terrain), true) as Terrain;
row = EditorGUILayout.IntField("row", row);
column = EditorGUILayout.IntField("column", column);
if (GUILayout.Button("convert"))
{
if( row * column * 6 > 65535)
{
Debug.LogError("row or column is too big! index buffer can't use 16 bit");
return;
}
TerrainData terrainData = terrain.terrainData;
int vertexCount = (row + 1) * (column + 1);
// vertex && uv
Vector3[] vertices = new Vector3[vertexCount];
Vector2[] uvs = new Vector2[vertexCount];
for (int i = 0; i <= row; i++)
{
for (int j = 0; j <= column; j++)
{
float width = terrainData.size.x;
float length = terrainData.size.z;
float x = (float)i / row * width;
float z = (float)j / column * length;
float y = terrain.SampleHeight(new Vector3(x, 0, z));
vertices[i * (column + 1) + j] = new Vector3(x, y, z);
uvs[i * (column + 1) + j] = new Vector2((float)i / row, (float)j / column);
}
}
// index
int indexCount = row * column * 6;
int[] indices = new int[indexCount];
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
indices[(i * column + j) * 6] = i * (column + 1) + j;
indices[(i * column + j) * 6 + 1] = i * (column + 1) + j + 1;
indices[(i * column + j) * 6 + 2] = (i + 1) * (column + 1) + j;
indices[(i * column + j) * 6 + 3] = i * (column + 1) + j + 1;
indices[(i * column + j) * 6 + 4] = (i + 1) * (column + 1) + j + 1;
indices[(i * column + j) * 6 + 5] = (i + 1) * (column + 1) + j;
}
}
// normal
Vector3[] normals = new Vector3[vertexCount];
int[] normalcounts = new int[vertexCount];
for (int i = 0; i < vertexCount; i++)
{
normals[i] = Vector3.zero;
normalcounts[i] = 0;
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
int vid0 = i * (column + 1) + j;
int vid1 = i * (column + 1) + j + 1;
int vid2 = (i + 1) * (column + 1) + j;
int vid3 = (i + 1) * (column + 1) + j + 1;
Vector3 normal0 =Vector3.Cross(vertices[vid2]-vertices[vid0], vertices[vid2]-vertices[vid0]).normalized;
Vector3 normal1 =Vector3.Cross(vertices[vid3]-vertices[vid1], vertices[vid2]-vertices[vid1]).normalized;
normals[vid0] += normal0;
normals[vid1] += normal0;
normals[vid2] += normal0;
normalcounts[vid0]++;
normalcounts[vid1]++;
normalcounts[vid2]++;
normals[vid1] += normal1;
normals[vid2] += normal1;
normals[vid3] += normal1;
normalcounts[vid1]++;
normalcounts[vid2]++;
normalcounts[vid3]++;
}
}
for (int i = 0; i < vertexCount; i++)
{
normals[i] /= normalcounts[i];
normals[i].Normalize();
}
Mesh mesh = new Mesh();
mesh.name = terrain.name;
mesh.vertices = vertices;
mesh.uv = uvs;
mesh.triangles = indices;
mesh.normals = normals;
AssetDatabase.CreateAsset(mesh, "Assets/test.asset");
AssetDatabase.Refresh();
}
EditorGUILayout.EndVertical();
}
}
|