1 [
EntityEditorProps(
category:
"GameScripted/Shapes", description:
"Procedural box", color:
"255 0 0 255", style:
"box", dynamicBox:
true)]
12 protected int m_iResolution;
15 protected float m_fHeightCoef;
18 protected ref array<float> m_aHeights;
20 [
Attribute(
category:
"Terrain Mesh",
desc:
"Material mapped on the mesh.", uiwidget: UIWidgets.ResourcePickerThumbnail,
params:
"emat")]
21 private ResourceName m_Material;
23 void Generate(array<float> heights, ResourceName material)
25 int heightsCount = heights.Count();
26 if (heightsCount != m_iResolution * m_iResolution)
28 Print(
string.Format(
"Resolution of height values (%1) doesn't match the resolution attribute (%2)", Math.Sqrt(heightsCount), m_iResolution), LogLevel.WARNING);
31 int resolution1 = m_iResolution - 1;
36 int vI, iI, uI, row, column;
39 for (
int y = 0; y < m_iResolution; y++)
41 for (
int x = 0; x < m_iResolution; x++)
44 x / resolution1 - 0.5,
45 heights[vI] * m_fHeightCoef,
50 uvs[uI] = x / resolution1; uI++;
51 uvs[uI] = 1 - y / resolution1; uI++;
66 for (
int s = 0; s < vI - m_iResolution; s++)
68 column = s % m_iResolution;
69 if (column == resolution1)
75 int pointBottomLeft = s;
76 int pointBottomRight = s + 1;
77 int pointTopLeft = pointBottomLeft + m_iResolution;
78 int pointTopRight = pointBottomRight + m_iResolution;
80 indices[iI] = pointBottomLeft; iI++;
81 indices[iI] = pointTopLeft; iI++;
82 indices[iI] = pointTopRight; iI++;
84 indices[iI] = pointTopRight; iI++;
85 indices[iI] = pointBottomRight; iI++;
86 indices[iI] = pointBottomLeft; iI++;
89 int numVertices[] = {vI};
90 int numIndices[] = {iI};
91 string materials[] = {material};
93 Resource res = MeshObject.Create(1, numVertices, numIndices, materials, 0);
94 MeshObject meshObject = res.GetResource().ToMeshObject();
95 meshObject.UpdateVerts(0, verts, uvs);
96 meshObject.UpdateIndices(0, indices);
97 SetObject(meshObject,
"");
98 Physics.CreateStatic(
this, 0xffffffff);
107 override array<ref WB_UIMenuItem> _WB_GetContextMenuItems()
109 return {
new WB_UIMenuItem(
"Generate from the current terrain", 0) };
111 override void _WB_OnContextMenu(
int id)
113 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
114 if (!worldEditor)
return;
116 WorldEditorAPI api = _WB_GetEditorAPI();
119 BaseWorld world = api.GetWorld();
122 vector min, max, size;
124 worldEditor.GetTerrainBounds(min, max);
126 float stepX = size[0] / m_iResolution;
127 float stepY = size[2] / m_iResolution;
128 float heightMax = max[1] - Math.Max(min[1], 0);
130 int resolution1 = m_iResolution - 1;
131 bool addComma =
false;
133 float posX, posY, posZ;
134 for (
int y = 0; y < m_iResolution; y++)
136 for (
int x = 0; x < m_iResolution; x++)
138 if (addComma) value +=
",";
139 posX = min[0] + size[0] * x / resolution1;
140 posY = min[2] + size[2] * y / resolution1;
141 posZ = Math.Max(world.GetSurfaceY(posX, posY), 0) / heightMax;
142 value += posZ.ToString();
148 api.BeginEntityAction();
149 api.SetVariableValue(api.EntityToSource(
this),
null,
"m_aHeights", value);
150 api.EndEntityAction();