载入中...
搜索中...
未找到
TerrainStampScript.cpp
浏览该文件的文档.
2#include "common/Capability.h"
4#include "procgen/PointSet.h"
25
36
37#include <functional>
38
39namespace eve::procgen {
40namespace {
41Result<int> missingRaster() {
43 Diagnostic::error(DiagnosticCode::InvalidArgument, "terrain operation requires non-null rasters and settings"));
44}
45} // namespace
46
47void exposeHeightmap(ssq::Table& table) {
48 auto spawnProgress = table.addClass("PcgSpawnProgress", ssq::Class::Ctor<PcgSpawnProgress()>());
49 spawnProgress.addFunc("updateRule", [vm = table.getHandle()](PcgSpawnProgress* progress,
50 const std::string& name, int total, int done, int localTotal, int localDone) {
51 return eve::script::projectResult(vm, progress->updateRule(name, total, done, localTotal, localDone),
52 [](PcgSpawnProgressStatus value) { return eve::Value(static_cast<int>(value)); });
53 });
54 spawnProgress.addFunc("updateRuleFraction", [vm = table.getHandle()](PcgSpawnProgress* progress, float value) {
55 return eve::script::projectResult(vm, progress->updateRuleFraction(value),
56 [](PcgSpawnProgressStatus status) { return eve::Value(static_cast<int>(status)); });
57 });
58 spawnProgress.addFunc("requestCancel", [vm = table.getHandle()](PcgSpawnProgress* progress) {
59 return eve::script::projectResult(vm, progress->requestCancel(),
60 [](PcgSpawnProgressStatus status) { return eve::Value(static_cast<int>(status)); });
61 });
62 spawnProgress.addFunc("clear", [](PcgSpawnProgress* progress) { return static_cast<int>(progress->clear()); });
63 spawnProgress.addFunc("getProgress", [](const PcgSpawnProgress* progress) { return float(progress->progress()); });
64 spawnProgress.addFunc("getTitle", [](const PcgSpawnProgress* progress) { return progress->title(); });
65 spawnProgress.addFunc("getSubtitle", [](const PcgSpawnProgress* progress) { return progress->subtitle(); });
66 spawnProgress.addFunc("getStatus", [](const PcgSpawnProgress* progress) { return static_cast<int>(progress->status()); });
67
68 auto runtimeStamper = table.addClass("PcgRuntimeStamper", ssq::Class::Ctor<PcgRuntimeStamper()>());
69 runtimeStamper.addFunc("configure", [vm = table.getHandle()](PcgRuntimeStamper* stamper,
70 const std::string& address, bool showGui,
71 bool showDebug) {
72 return eve::script::projectResult(vm, stamper->configure(address, showGui, showDebug));
73 });
74 runtimeStamper.addFunc("loadStamp", [vm = table.getHandle()](PcgRuntimeStamper* stamper,
75 const Heightmap* stamp,
76 const std::string& resourceName) {
77 auto result = stamp ? stamper->loadStamp(*stamp, resourceName)
79 "stamp resource is required", {}, {}, "procgen.pcgRuntimeStamper"));
80 return eve::script::projectResult(vm, std::move(result));
81 });
82 runtimeStamper.addFunc("reportMissingStamp", [vm = table.getHandle()](PcgRuntimeStamper* stamper) {
83 return eve::script::projectResult(vm, stamper->reportMissingStamp());
84 });
85 runtimeStamper.addFunc("execute", [vm = table.getHandle()](PcgRuntimeStamper* stamper, Heightmap* target,
86 float originX, float originZ, float spacingX,
87 float spacingZ) {
88 auto result = target ? stamper->execute(*target, originX, originZ, spacingX, spacingZ) : missingRaster();
89 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
90 });
91 runtimeStamper.addFunc("updateLayout", [vm = table.getHandle()](PcgRuntimeStamper* stamper,
92 float width, float height) {
93 return eve::script::projectResult(vm, stamper->updateLayout(width, height));
94 });
95 runtimeStamper.addFunc("getStatus", [](const PcgRuntimeStamper* stamper) {
96 return static_cast<int>(stamper->status());
97 });
98 runtimeStamper.addFunc("getStampAddress", [](const PcgRuntimeStamper* stamper) {
99 return stamper->stampAddress();
100 });
101 runtimeStamper.addFunc("getProgressText", [](const PcgRuntimeStamper* stamper) {
102 return stamper->progressText();
103 });
104 runtimeStamper.addFunc("getUpdateTimeAllowed", [](const PcgRuntimeStamper* stamper) {
105 return static_cast<float>(stamper->updateTimeAllowed());
106 });
107 runtimeStamper.addFunc("getLabelCenterX", [](const PcgRuntimeStamper* stamper) {
108 return static_cast<float>(stamper->labelCenterX());
109 });
110 runtimeStamper.addFunc("getLabelCenterY", [](const PcgRuntimeStamper* stamper) {
111 return static_cast<float>(stamper->labelCenterY());
112 });
113
114 auto biomeController = table.addClass("PcgBiomeController", ssq::Class::Ctor<PcgBiomeController()>());
115 biomeController.addFunc("configure", [vm=table.getHandle()](PcgBiomeController* controller,
116 float x,float y,float z,float range,float impostorRange,int mode) {
117 return eve::script::projectResult(vm,controller->configure(x,y,z,range,impostorRange,
118 static_cast<PcgBiomeLoadMode>(mode)));
119 });
120 biomeController.addFunc("fitToTerrain", [vm=table.getHandle()](PcgBiomeController* controller,
121 float x,float y,float z,float sx,float sy,float sz) {
122 return eve::script::projectResult(vm,controller->fitToTerrain(x,y,z,sx,sy,sz));
123 });
124 biomeController.addFunc("fitToAllTerrains", [vm=table.getHandle()](PcgBiomeController* controller,
125 float x,float y,float z,float sx,float sy,float sz) {
126 return eve::script::projectResult(vm,controller->fitToAllTerrains(x,y,z,sx,sy,sz));
127 });
128 biomeController.addFunc("tierAt", [](const PcgBiomeController* controller,float x,float y,float z) {
129 return static_cast<int>(controller->tierAt(x,y,z));
130 });
131 biomeController.addFunc("getRange", [](const PcgBiomeController* controller) {
132 return static_cast<float>(controller->range());
133 });
134 biomeController.addFunc("getLoadMode", [](const PcgBiomeController* controller) {
135 return static_cast<int>(controller->loadMode());
136 });
137 biomeController.addFunc("getRegularCenterX", [](const PcgBiomeController* controller) {
138 return static_cast<float>(controller->regularBounds().centerX);
139 });
140 biomeController.addFunc("getRegularCenterY", [](const PcgBiomeController* controller) {
141 return static_cast<float>(controller->regularBounds().centerY);
142 });
143 biomeController.addFunc("getRegularCenterZ", [](const PcgBiomeController* controller) {
144 return static_cast<float>(controller->regularBounds().centerZ);
145 });
146 biomeController.addFunc("getRegularSize", [](const PcgBiomeController* controller) {
147 return static_cast<float>(controller->regularBounds().sizeX);
148 });
149 biomeController.addFunc("getImpostorSize", [](const PcgBiomeController* controller) {
150 return static_cast<float>(controller->impostorBounds().sizeX);
151 });
152 auto treeManager = table.addClass("PcgTreeManager", ssq::Class::Ctor<PcgTreeManager()>());
153 treeManager.addFunc("reset", [vm=table.getHandle()](PcgTreeManager* manager,
154 float x,float z,float width,float depth) {
155 return eve::script::projectResult(vm,manager->reset(x,z,width,depth));
156 });
157 treeManager.addFunc("addTree", [vm=table.getHandle()](PcgTreeManager* manager,
158 float x,float z,int prototype) {
159 return eve::script::projectResult(vm,manager->addTree(x,z,prototype),
160 [](int value){return eve::Value(value);});
161 });
162 treeManager.addFunc("addTrees", [vm=table.getHandle()](PcgTreeManager* manager,
163 const PointSet* points,int prototype) {
164 auto result=points?manager->addTrees(*points,prototype):
166 "PointSet is required","procgen.pcgTreeManager"));
167 return eve::script::projectResult(vm,std::move(result),
168 [](int value){return eve::Value(value);});
169 });
170 treeManager.addFunc("countInRange", [vm=table.getHandle()](const PcgTreeManager* manager,
171 float x,float z,float range) {
172 return eve::script::projectResult(vm,manager->countInRange(x,z,range),
173 [](int value){return eve::Value(value);});
174 });
175 treeManager.addFunc("getCount", [](const PcgTreeManager* manager){return manager->getCount();});
176 auto terrainWatcher = table.addClass("PcgTerrainWatcher", ssq::Class::Ctor<PcgTerrainWatcher()>());
177 terrainWatcher.addFunc("beginScan", &PcgTerrainWatcher::beginScan);
178 terrainWatcher.addFunc("addTerrain", [vm=table.getHandle()](PcgTerrainWatcher* watcher,
179 const std::string& id) {
180 return eve::script::projectResult(vm, watcher->addTerrain(id),
181 [](int value) { return eve::Value(value); });
182 });
183 terrainWatcher.addFunc("commitScan", [vm=table.getHandle()](PcgTerrainWatcher* watcher) {
184 return eve::script::projectResult(vm, watcher->commitScan(),
185 [](int value) { return eve::Value(value); });
186 });
187 terrainWatcher.addFunc("cancelScan", &PcgTerrainWatcher::cancelScan);
188 terrainWatcher.addFunc("getTerrainCount", [](const PcgTerrainWatcher* watcher) {
189 return watcher->getTerrainCount();
190 });
191 terrainWatcher.addFunc("getChangeCount", [](const PcgTerrainWatcher* watcher) {
192 return watcher->getChangeCount();
193 });
194 terrainWatcher.addFunc("getChangeTerrainId", [vm=table.getHandle()](const PcgTerrainWatcher* watcher,
195 int index) {
196 return eve::script::projectResult(vm, watcher->getChangeTerrainId(index),
197 [](const std::string& value) { return eve::Value(value); });
198 });
199 terrainWatcher.addFunc("getChangeType", [vm=table.getHandle()](const PcgTerrainWatcher* watcher,
200 int index) {
201 return eve::script::projectResult(vm, watcher->getChangeType(index),
202 [](int value) { return eve::Value(value); });
203 });
204 auto splatmap = table.addClass("TerrainSplatmap", ssq::Class::Ctor<TerrainSplatmap()>());
205 splatmap.addFunc("initialize", [vm = table.getHandle()](TerrainSplatmap* target, int width, int height,
206 int layers, int defaultLayer) {
207 return eve::script::projectResult(vm, target->initialize(width, height, layers, defaultLayer),
208 [](int n) { return eve::Value(n); });
209 });
210 splatmap.addFunc("sample", [vm = table.getHandle()](const TerrainSplatmap* target, int layer, int x, int y) {
211 return eve::script::projectResult(vm, target->sample(layer, x, y),
212 [](float value) { return eve::Value(value); });
213 });
214 splatmap.addFunc("copyLayer", [vm = table.getHandle()](const TerrainSplatmap* target, int layer,
215 Heightmap* output) {
216 auto result = output ? target->copyLayer(layer, *output) : missingRaster();
217 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
218 });
219 splatmap.addFunc("paint", [vm = table.getHandle()](TerrainSplatmap* target, const Heightmap* paint, int layer) {
220 auto result = paint ? paintTerrainSplatLayer(*target, *paint, layer) : missingRaster();
221 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
222 });
223 splatmap.addFunc("getWidth", [](const TerrainSplatmap* target) { return target->getWidth(); });
224 splatmap.addFunc("getHeight", [](const TerrainSplatmap* target) { return target->getHeight(); });
225 splatmap.addFunc("getLayerCount", [](const TerrainSplatmap* target) { return target->getLayerCount(); });
226 splatmap.addFunc("getLastChangedSamples",
227 [](const TerrainSplatmap* target) { return target->getLastChangedSamples(); });
228 auto textureAlign =
229 table.addClass("TerrainTextureAlignSettings", ssq::Class::Ctor<TerrainTextureAlignSettings()>());
230 textureAlign.addVar("terrainAOriginX", &TerrainTextureAlignSettings::terrainAOriginX);
231 textureAlign.addVar("terrainAOriginZ", &TerrainTextureAlignSettings::terrainAOriginZ);
232 textureAlign.addVar("terrainAWidth", &TerrainTextureAlignSettings::terrainAWidth);
233 textureAlign.addVar("terrainADepth", &TerrainTextureAlignSettings::terrainADepth);
234 textureAlign.addVar("terrainBOriginX", &TerrainTextureAlignSettings::terrainBOriginX);
235 textureAlign.addVar("terrainBOriginZ", &TerrainTextureAlignSettings::terrainBOriginZ);
236 textureAlign.addVar("terrainBWidth", &TerrainTextureAlignSettings::terrainBWidth);
237 textureAlign.addVar("terrainBDepth", &TerrainTextureAlignSettings::terrainBDepth);
238 textureAlign.addVar("blendStrength", &TerrainTextureAlignSettings::blendStrength);
239 textureAlign.addVar("blendWidth", &TerrainTextureAlignSettings::blendWidth);
240 textureAlign.addVar("adjacencyTolerance", &TerrainTextureAlignSettings::adjacencyTolerance);
241 table.addFunc("alignTerrainSplatTextures",
242 [vm = table.getHandle()](TerrainSplatmap* terrainA, TerrainSplatmap* terrainB,
243 const TerrainTextureAlignSettings* settings) {
244 auto result = terrainA && terrainB && settings
245 ? alignTerrainSplatTextures(*terrainA, *terrainB, *settings)
246 : missingRaster();
247 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
248 });
249 auto heightBlend = table.addClass("GtsHeightBlendSet", ssq::Class::Ctor<GtsHeightBlendSet()>());
250 heightBlend.addFunc("addLayer", [vm = table.getHandle()](GtsHeightBlendSet* target,
251 const Heightmap* height, float contrast,
252 float brightness, float increase) {
253 auto result = height ? target->addLayer(*height, contrast, brightness, increase) : missingRaster();
254 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
255 });
256 heightBlend.addFunc("getLayerCount", [](const GtsHeightBlendSet* target) { return target->getLayerCount(); });
257 table.addFunc("applyGtsHeightBlend",
258 [vm = table.getHandle()](TerrainSplatmap* output, const TerrainSplatmap* input,
259 const GtsHeightBlendSet* heights, float blendFactor) {
260 auto result = output && input && heights ? applyGtsHeightBlend(*output, *input, *heights, blendFactor)
261 : missingRaster();
262 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
263 });
264
265 auto multiSplat = table.addClass("TerrainMultiSplatWorkspace", ssq::Class::Ctor<TerrainMultiSplatWorkspace()>());
266 multiSplat.addFunc("addTile", [vm = table.getHandle()](TerrainMultiSplatWorkspace* workspace,
267 const std::string& name,
268 const TerrainSplatmap* splat, float originX,
269 float originZ, float width, float depth, bool worldMap) {
270 auto result = splat ? workspace->addTile(name, *splat, originX, originZ, width, depth, worldMap)
271 : missingRaster();
272 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
273 });
274 multiSplat.addFunc("paint", [vm = table.getHandle()](TerrainMultiSplatWorkspace* workspace,
275 const Heightmap* paint, int targetLayer,
276 const TerrainStampSettings* operation, bool worldMap) {
277 auto result = paint && operation ? workspace->paint(*paint, targetLayer, *operation, worldMap)
278 : missingRaster();
279 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
280 });
281 multiSplat.addFunc("copyTile", [vm = table.getHandle()](const TerrainMultiSplatWorkspace* workspace,
282 const std::string& name, TerrainSplatmap* output) {
283 auto result = output ? workspace->copyTile(name, *output) : missingRaster();
284 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
285 });
286 multiSplat.addFunc("undo", [vm = table.getHandle()](TerrainMultiSplatWorkspace* workspace) {
287 return eve::script::projectResult(vm, workspace->undo(), [](int n) { return eve::Value(n); });
288 });
289 multiSplat.addFunc("redo", [vm = table.getHandle()](TerrainMultiSplatWorkspace* workspace) {
290 return eve::script::projectResult(vm, workspace->redo(), [](int n) { return eve::Value(n); });
291 });
292 multiSplat.addFunc("getTileCount", [](const TerrainMultiSplatWorkspace* workspace) {
293 return workspace->getTileCount();
294 });
295 multiSplat.addFunc("getLastChangedSamples", [](const TerrainMultiSplatWorkspace* workspace) {
296 return workspace->getLastChangedSamples();
297 });
298 multiSplat.addFunc("getLastAffectedTiles", [](const TerrainMultiSplatWorkspace* workspace) {
299 return workspace->getLastAffectedTiles();
300 });
301 multiSplat.addFunc("getOperationCount", [](const TerrainMultiSplatWorkspace* workspace) {
302 return workspace->getOperationCount();
303 });
304 multiSplat.addFunc("getAppliedCount", [](const TerrainMultiSplatWorkspace* workspace) {
305 return workspace->getAppliedCount();
306 });
307
308 auto objectInstance =
309 table.addClass("TerrainObjectInstanceSettings", ssq::Class::Ctor<TerrainObjectInstanceSettings()>());
310 objectInstance.addVar("asset", &TerrainObjectInstanceSettings::asset);
311 objectInstance.addVar("minimumInstances", &TerrainObjectInstanceSettings::minimumInstances);
312 objectInstance.addVar("maximumInstances", &TerrainObjectInstanceSettings::maximumInstances);
313 objectInstance.addVar("failureRate", &TerrainObjectInstanceSettings::failureRate);
314 objectInstance.addVar("minimumOffsetX", &TerrainObjectInstanceSettings::minimumOffsetX);
315 objectInstance.addVar("maximumOffsetX", &TerrainObjectInstanceSettings::maximumOffsetX);
316 objectInstance.addVar("minimumOffsetY", &TerrainObjectInstanceSettings::minimumOffsetY);
317 objectInstance.addVar("maximumOffsetY", &TerrainObjectInstanceSettings::maximumOffsetY);
318 objectInstance.addVar("minimumOffsetZ", &TerrainObjectInstanceSettings::minimumOffsetZ);
319 objectInstance.addVar("maximumOffsetZ", &TerrainObjectInstanceSettings::maximumOffsetZ);
320 objectInstance.addVar("customOffset", &TerrainObjectInstanceSettings::customOffset);
321 objectInstance.addVar("commonScale", &TerrainObjectInstanceSettings::commonScale);
322 objectInstance.addVar("minimumScale", &TerrainObjectInstanceSettings::minimumScale);
323 objectInstance.addVar("maximumScale", &TerrainObjectInstanceSettings::maximumScale);
324 objectInstance.addVar("minimumScaleX", &TerrainObjectInstanceSettings::minimumScaleX);
325 objectInstance.addVar("maximumScaleX", &TerrainObjectInstanceSettings::maximumScaleX);
326 objectInstance.addVar("minimumScaleY", &TerrainObjectInstanceSettings::minimumScaleY);
327 objectInstance.addVar("maximumScaleY", &TerrainObjectInstanceSettings::maximumScaleY);
328 objectInstance.addVar("minimumScaleZ", &TerrainObjectInstanceSettings::minimumScaleZ);
329 objectInstance.addVar("maximumScaleZ", &TerrainObjectInstanceSettings::maximumScaleZ);
330 objectInstance.addVar("scaleRandomPercentage", &TerrainObjectInstanceSettings::scaleRandomPercentage);
331 objectInstance.addVar("scaleRandomPercentageX", &TerrainObjectInstanceSettings::scaleRandomPercentageX);
332 objectInstance.addVar("scaleRandomPercentageY", &TerrainObjectInstanceSettings::scaleRandomPercentageY);
333 objectInstance.addVar("scaleRandomPercentageZ", &TerrainObjectInstanceSettings::scaleRandomPercentageZ);
334 objectInstance.addVar("minimumRotationX", &TerrainObjectInstanceSettings::minimumRotationX);
335 objectInstance.addVar("maximumRotationX", &TerrainObjectInstanceSettings::maximumRotationX);
336 objectInstance.addVar("minimumRotationY", &TerrainObjectInstanceSettings::minimumRotationY);
337 objectInstance.addVar("maximumRotationY", &TerrainObjectInstanceSettings::maximumRotationY);
338 objectInstance.addVar("minimumRotationZ", &TerrainObjectInstanceSettings::minimumRotationZ);
339 objectInstance.addVar("maximumRotationZ", &TerrainObjectInstanceSettings::maximumRotationZ);
340 objectInstance.addVar("yOffsetAlongSlope", &TerrainObjectInstanceSettings::yOffsetAlongSlope);
341 objectInstance.addVar("alignForwardToSlope", &TerrainObjectInstanceSettings::alignForwardToSlope);
342 objectInstance.addVar("rotateToSlope", &TerrainObjectInstanceSettings::rotateToSlope);
343 objectInstance.addFunc("setYOffsetMode", [](TerrainObjectInstanceSettings* value, int mode) {
344 value->yOffsetMode = static_cast<TerrainObjectYOffsetMode>(mode);
345 });
346 objectInstance.addFunc("setScaleMode", [](TerrainObjectInstanceSettings* value, int mode) {
347 value->scaleMode = static_cast<TerrainObjectScaleMode>(mode);
348 });
349
350 auto object = table.addClass("TerrainObjectPlacementSettings", ssq::Class::Ctor<TerrainObjectPlacementSettings()>());
351 object.addVar("originX", &TerrainObjectPlacementSettings::originX);
352 object.addVar("originZ", &TerrainObjectPlacementSettings::originZ);
353 object.addVar("width", &TerrainObjectPlacementSettings::width);
354 object.addVar("depth", &TerrainObjectPlacementSettings::depth);
355 object.addVar("heightScale", &TerrainObjectPlacementSettings::heightScale);
356 object.addVar("spacing", &TerrainObjectPlacementSettings::spacing);
357 object.addVar("spawnDensity", &TerrainObjectPlacementSettings::spawnDensity);
358 object.addVar("jitterPercent", &TerrainObjectPlacementSettings::jitterPercent);
359 object.addVar("startOffsetX", &TerrainObjectPlacementSettings::startOffsetX);
360 object.addVar("startOffsetZ", &TerrainObjectPlacementSettings::startOffsetZ);
361 object.addVar("failureRate", &TerrainObjectPlacementSettings::failureRate);
362 object.addVar("minimumFitness", &TerrainObjectPlacementSettings::minimumFitness);
363 object.addVar("minimumInstanceFitness", &TerrainObjectPlacementSettings::minimumInstanceFitness);
364 object.addVar("minimumDirection", &TerrainObjectPlacementSettings::minimumDirection);
365 object.addVar("maximumDirection", &TerrainObjectPlacementSettings::maximumDirection);
366 object.addVar("boundsRadius", &TerrainObjectPlacementSettings::boundsRadius);
367 object.addVar("boundsCheckQuality", &TerrainObjectPlacementSettings::boundsCheckQuality);
368 object.addVar("prototypeScale", &TerrainObjectPlacementSettings::prototypeScale);
369 object.addVar("boundsCollisionCheck", &TerrainObjectPlacementSettings::boundsCollisionCheck);
370 object.addVar("seaLevel", &TerrainObjectPlacementSettings::seaLevel);
371 object.addVar("seed", &TerrainObjectPlacementSettings::seed);
372 object.addVar("namespaceId", &TerrainObjectPlacementSettings::namespaceId);
373 object.addVar("maxPoints", &TerrainObjectPlacementSettings::maxPoints);
374 object.addVar("prototype", &TerrainObjectPlacementSettings::prototype);
375 object.addFunc("addInstance", [vm = table.getHandle()](TerrainObjectPlacementSettings* settings,
376 const TerrainObjectInstanceSettings* instance) {
377 auto result = instance ? settings->addInstance(*instance) : missingRaster();
378 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
379 });
380 object.addFunc("exportPoints", [vm = table.getHandle()](const TerrainObjectPlacementSettings* settings,
381 PointSet* output, const Heightmap* fitness,
382 const Heightmap* heights) {
383 auto result = output && fitness && heights ? exportTerrainObjectPoints(*output, *fitness, *heights, *settings)
384 : missingRaster();
385 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
386 });
387 object.addFunc("removePoints", [vm = table.getHandle()](const TerrainObjectPlacementSettings* settings,
388 PointSet* output, const PointSet* input,
389 const Heightmap* fitness, float strength) {
390 auto result = output && input && fitness
392 : missingRaster();
393 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
394 });
395
396 auto multiObject =
397 table.addClass("TerrainMultiObjectWorkspace", ssq::Class::Ctor<TerrainMultiObjectWorkspace()>());
398 multiObject.addFunc("addTile", [vm = table.getHandle()](TerrainMultiObjectWorkspace* workspace,
399 const std::string& name, const PointSet* objects,
400 const Heightmap* heights, float originX, float originZ,
401 float width, float depth, int resolutionX,
402 int resolutionY, bool worldMap) {
403 auto result = objects && heights
404 ? workspace->addTile(name, *objects, *heights, originX, originZ, width, depth,
405 resolutionX, resolutionY, worldMap)
406 : missingRaster();
407 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
408 });
409 multiObject.addFunc("apply", [vm = table.getHandle()](TerrainMultiObjectWorkspace* workspace,
410 const Heightmap* fitness,
411 const TerrainObjectPlacementSettings* settings,
412 const TerrainStampSettings* operation, int mode,
413 bool worldMap) {
414 auto result = fitness && settings && operation
415 ? workspace->apply(*fitness, *settings, *operation,
416 static_cast<TerrainObjectOperationMode>(mode), worldMap)
417 : missingRaster();
418 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
419 });
420 multiObject.addFunc("copyTile", [vm = table.getHandle()](const TerrainMultiObjectWorkspace* workspace,
421 const std::string& name, PointSet* output) {
422 auto result = output ? workspace->copyTile(name, *output) : missingRaster();
423 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
424 });
425 multiObject.addFunc("undo", [vm = table.getHandle()](TerrainMultiObjectWorkspace* workspace) {
426 return eve::script::projectResult(vm, workspace->undo(), [](int n) { return eve::Value(n); });
427 });
428 multiObject.addFunc("redo", [vm = table.getHandle()](TerrainMultiObjectWorkspace* workspace) {
429 return eve::script::projectResult(vm, workspace->redo(), [](int n) { return eve::Value(n); });
430 });
431 multiObject.addFunc("getTileCount", [](const TerrainMultiObjectWorkspace* workspace) {
432 return workspace->getTileCount();
433 });
434 multiObject.addFunc("getLastChangedSamples", [](const TerrainMultiObjectWorkspace* workspace) {
435 return workspace->getLastChangedSamples();
436 });
437 multiObject.addFunc("getLastAffectedTiles", [](const TerrainMultiObjectWorkspace* workspace) {
438 return workspace->getLastAffectedTiles();
439 });
440 multiObject.addFunc("getOperationCount", [](const TerrainMultiObjectWorkspace* workspace) {
441 return workspace->getOperationCount();
442 });
443 multiObject.addFunc("getAppliedCount", [](const TerrainMultiObjectWorkspace* workspace) {
444 return workspace->getAppliedCount();
445 });
446
447 auto worldSettings =
448 table.addClass("TerrainWorldCreationSettings", ssq::Class::Ctor<TerrainWorldCreationSettings()>());
449 worldSettings.addVar("tilesX", &TerrainWorldCreationSettings::tilesX);
450 worldSettings.addVar("tilesZ", &TerrainWorldCreationSettings::tilesZ);
451 worldSettings.addVar("tileSize", &TerrainWorldCreationSettings::tileSize);
452 worldSettings.addVar("tileHeight", &TerrainWorldCreationSettings::tileHeight);
453 worldSettings.addVar("centerX", &TerrainWorldCreationSettings::centerX);
454 worldSettings.addVar("centerZ", &TerrainWorldCreationSettings::centerZ);
455 worldSettings.addVar("heightmapResolution", &TerrainWorldCreationSettings::heightmapResolution);
456 worldSettings.addVar("controlTextureResolution", &TerrainWorldCreationSettings::controlTextureResolution);
457 worldSettings.addVar("detailResolution", &TerrainWorldCreationSettings::detailResolution);
458 worldSettings.addVar("treeResolution", &TerrainWorldCreationSettings::treeResolution);
459 worldSettings.addVar("objectResolution", &TerrainWorldCreationSettings::objectResolution);
460 worldSettings.addVar("splatLayers", &TerrainWorldCreationSettings::splatLayers);
461 worldSettings.addVar("defaultSplatLayer", &TerrainWorldCreationSettings::defaultSplatLayer);
462 worldSettings.addVar("defaultDetailDensity", &TerrainWorldCreationSettings::defaultDetailDensity);
463 worldSettings.addVar("worldMap", &TerrainWorldCreationSettings::worldMap);
464 worldSettings.addVar("namePrefix", &TerrainWorldCreationSettings::namePrefix);
465 worldSettings.addVar("nameSuffix", &TerrainWorldCreationSettings::nameSuffix);
466
467 auto probeSettings = table.addClass("TerrainProbePlacementSettings",
468 ssq::Class::Ctor<TerrainProbePlacementSettings()>());
469 probeSettings.addVar("name", &TerrainProbePlacementSettings::name);
470 probeSettings.addVar("originX", &TerrainProbePlacementSettings::originX);
471 probeSettings.addVar("originZ", &TerrainProbePlacementSettings::originZ);
472 probeSettings.addVar("width", &TerrainProbePlacementSettings::width);
473 probeSettings.addVar("depth", &TerrainProbePlacementSettings::depth);
474 probeSettings.addVar("heightScale", &TerrainProbePlacementSettings::heightScale);
475 probeSettings.addVar("spacing", &TerrainProbePlacementSettings::spacing);
476 probeSettings.addVar("jitterPercent", &TerrainProbePlacementSettings::jitterPercent);
477 probeSettings.addVar("minimumFitness", &TerrainProbePlacementSettings::minimumFitness);
478 probeSettings.addVar("seaLevelActive", &TerrainProbePlacementSettings::seaLevelActive);
479 probeSettings.addVar("seaLevel", &TerrainProbePlacementSettings::seaLevel);
480 probeSettings.addVar("reflectionOffset", &TerrainProbePlacementSettings::reflectionOffset);
481 probeSettings.addVar("lightOffset", &TerrainProbePlacementSettings::lightOffset);
482 probeSettings.addVar("reflectionResolution", &TerrainProbePlacementSettings::reflectionResolution);
483 probeSettings.addVar("reflectionClipDistance", &TerrainProbePlacementSettings::reflectionClipDistance);
484 probeSettings.addVar("reflectionShadowDistance", &TerrainProbePlacementSettings::reflectionShadowDistance);
485 probeSettings.addVar("seed", &TerrainProbePlacementSettings::seed);
486 probeSettings.addVar("namespaceId", &TerrainProbePlacementSettings::namespaceId);
487 probeSettings.addVar("maxPoints", &TerrainProbePlacementSettings::maxPoints);
488 table.addFunc("generateTerrainProbes",
489 [vm = table.getHandle()](PointSet* output, const Heightmap* fitness, const Heightmap* heights,
490 const TerrainProbePlacementSettings* settings, int type) {
491 auto result = [&]() -> Result<int> {
492 if (!output || !fitness || !heights || !settings) return missingRaster();
493 auto copy = *settings;
494 copy.type = static_cast<TerrainProbeType>(type);
495 return exportTerrainProbePoints(*output, *fitness, *heights, copy);
496 }();
497 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
498 });
499 table.addFunc("publishTerrainProbes", [vm = table.getHandle()](const std::string& batchId,
500 const PointSet* points) {
501 auto result = [&]() -> Result<int> {
502 if (!points)
504 "terrain.probes.publish: point set required"));
505 auto* sink = eve::cap::query<eve::IProcgenProbeSink>();
506 if (!sink)
508 "terrain.probes.publish: graphics provider unavailable"));
509 std::vector<eve::ProcgenProbeDesc> descriptions;
510 descriptions.reserve(static_cast<std::size_t>(points->getCount()));
511 for (int i = 0; i < points->getCount(); ++i) {
512 const auto& point = points->points()[static_cast<std::size_t>(i)];
515 desc.resource = points->getStringAttribute(i, "probeResource", "");
516 desc.type = static_cast<int>(points->getIntAttribute(i, "probeType", -1));
517 desc.x = point.x; desc.y = point.y; desc.z = point.z;
518 desc.extentX = std::max(0.5F, (point.boundsMaxX - point.boundsMinX) * 0.5F);
519 desc.extentY = std::max(0.5F, (point.boundsMaxY - point.boundsMinY) * 0.5F);
520 desc.extentZ = std::max(0.5F, (point.boundsMaxZ - point.boundsMinZ) * 0.5F);
521 desc.resolution = static_cast<int>(points->getIntAttribute(i, "reflectionResolution", 128));
522 desc.clipDistance = points->getFloatAttribute(i, "reflectionClipDistance", 1000);
523 desc.shadowDistance = points->getFloatAttribute(i, "reflectionShadowDistance", 80);
524 desc.irradianceR = points->getFloatAttribute(i, "probeIrradianceR", 0.12F);
525 desc.irradianceG = points->getFloatAttribute(i, "probeIrradianceG", 0.12F);
526 desc.irradianceB = points->getFloatAttribute(i, "probeIrradianceB", 0.14F);
527 desc.hasSphericalHarmonics = points->getIntAttribute(i, "probeHasSphericalHarmonics", 0) != 0;
528 if (desc.hasSphericalHarmonics) {
529 static constexpr char channels[] = {'R', 'G', 'B'};
530 for (int coefficient = 0; coefficient < 9; ++coefficient)
531 for (int channel = 0; channel < 3; ++channel) {
532 const std::string name = "probeSh" + std::to_string(coefficient) + channels[channel];
533 desc.sphericalHarmonics[static_cast<size_t>(coefficient * 3 + channel)] =
534 points->getFloatAttribute(i, name, 0.f);
535 }
536 }
537 descriptions.push_back(std::move(desc));
538 }
539 return sink->replaceProbeBatch(batchId, descriptions);
540 }();
541 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
542 });
543 table.addFunc("removeTerrainProbeBatch", [vm = table.getHandle()](const std::string& batchId) {
544 auto* sink = eve::cap::query<eve::IProcgenProbeSink>();
545 auto result = sink ? sink->removeProbeBatch(batchId)
547 "terrain.probes.remove: graphics provider unavailable"));
548 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
549 });
550 table.addFunc("tickTerrainProbeBatches", [vm = table.getHandle()](int faces, int filters, int samples) {
551 auto* sink = eve::cap::query<eve::IProcgenProbeSink>();
552 auto result = sink ? sink->tickProbeBatches(faces, filters, samples)
554 "terrain.probes.tick: graphics provider unavailable"));
555 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
556 });
557 table.addFunc("getTerrainProbeBatchCount", [](const std::string& batchId) {
558 auto* sink = eve::cap::query<eve::IProcgenProbeSink>();
559 return sink ? sink->probeCount(batchId) : 0;
560 });
561 table.addFunc("getTerrainReflectionProbeCount", [](const std::string& batchId) {
562 auto* sink = eve::cap::query<eve::IProcgenProbeSink>();
563 return sink ? sink->reflectionProbeCount(batchId) : 0;
564 });
565 table.addFunc("getTerrainLightProbeCount", [](const std::string& batchId) {
566 auto* sink = eve::cap::query<eve::IProcgenProbeSink>();
567 return sink ? sink->lightProbeCount(batchId) : 0;
568 });
569
570 auto spawnPlan = table.addClass("TerrainSpawnPlan", ssq::Class::Ctor<TerrainSpawnPlan()>());
571 spawnPlan.addFunc("addSplat", [vm = table.getHandle()](TerrainSpawnPlan* self, const std::string& ruleId,
572 const Heightmap* paint, int targetLayer,
573 const TerrainStampSettings* operation) {
574 auto result = paint && operation ? self->addSplat(ruleId, *paint, targetLayer, *operation)
575 : missingRaster();
576 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
577 });
578 spawnPlan.addFunc("addDetail", [vm = table.getHandle()](TerrainSpawnPlan* self, const std::string& ruleId,
579 const Heightmap* fitness,
580 const TerrainDetailSettings* settings,
581 const TerrainStampSettings* operation, int mode,
582 int seed) {
583 auto result = fitness && settings && operation
584 ? self->addDetail(ruleId, *fitness, *settings, *operation,
585 static_cast<TerrainDetailMode>(mode), seed)
586 : missingRaster();
587 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
588 });
589 spawnPlan.addFunc("addTrees", [vm = table.getHandle()](TerrainSpawnPlan* self, const std::string& ruleId,
590 const Heightmap* fitness,
591 const TerrainTreePlacementSettings* settings,
592 const TerrainStampSettings* operation, int mode) {
593 auto result = fitness && settings && operation
594 ? self->addTrees(ruleId, *fitness, *settings, *operation,
595 static_cast<TerrainTreeOperationMode>(mode))
596 : missingRaster();
597 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
598 });
599 spawnPlan.addFunc("addObjects", [vm = table.getHandle()](TerrainSpawnPlan* self, const std::string& ruleId,
600 const Heightmap* fitness,
601 const TerrainObjectPlacementSettings* settings,
602 const TerrainStampSettings* operation, int mode) {
603 auto result = fitness && settings && operation
604 ? self->addObjects(ruleId, *fitness, *settings, *operation,
605 static_cast<TerrainObjectOperationMode>(mode))
606 : missingRaster();
607 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
608 });
609 spawnPlan.addFunc("addProbes", [vm = table.getHandle()](TerrainSpawnPlan* self, const std::string& ruleId,
610 const Heightmap* fitness,
611 const TerrainProbePlacementSettings* settings,
612 const TerrainStampSettings* operation, int mode,
613 int type) {
614 auto result = [&]() -> Result<int> {
615 if (!fitness || !settings || !operation) return missingRaster();
616 auto copy = *settings;
617 copy.type = static_cast<TerrainProbeType>(type);
618 return self->addProbes(ruleId, *fitness, copy, *operation,
619 static_cast<TerrainProbeOperationMode>(mode));
620 }();
621 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
622 });
623 spawnPlan.addFunc("addModifierStamp", [vm = table.getHandle()](TerrainSpawnPlan* self,
624 const std::string& ruleId,
625 const Heightmap* stamp,
626 const TerrainStampSettings* operation,
627 int operationType,
628 const Heightmap* localMask,
629 const Heightmap* globalMask) {
630 auto result = [&]() -> Result<int> {
631 if (!stamp || !operation || !localMask || !globalMask) return missingRaster();
632 auto copy = *operation;
633 copy.operation = static_cast<TerrainStampOperation>(operationType);
634 return self->addModifierStamp(ruleId, *stamp, copy, *localMask, *globalMask);
635 }();
636 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
637 });
638 spawnPlan.addFunc("setEnabled", [vm = table.getHandle()](TerrainSpawnPlan* self,
639 const std::string& ruleId, bool enabled) {
640 return eve::script::projectResult(vm, self->setEnabled(ruleId, enabled));
641 });
642 spawnPlan.addFunc("getRuleCount", [](const TerrainSpawnPlan* self) { return self->getRuleCount(); });
643 spawnPlan.addFunc("snapshotJson", [vm = table.getHandle()](const TerrainSpawnPlan* self) {
644 return eve::script::projectResult(vm, self->snapshotJson(),
645 [](const std::string& value) { return eve::Value(value); });
646 });
647 spawnPlan.addFunc("restoreJson", [vm = table.getHandle()](TerrainSpawnPlan* self,
648 const std::string& json) {
649 return eve::script::projectResult(vm, self->restoreJson(json));
650 });
651
652 auto biomePreset = table.addClass("TerrainBiomePreset", ssq::Class::Ctor<TerrainBiomePreset()>());
653 biomePreset.addFunc("addSpawner", [vm = table.getHandle()](TerrainBiomePreset* self,
654 const std::string& entryId,
655 const TerrainSpawnPlan* plan,
656 bool activeInBiome, bool activeInStamper,
657 bool autoAssignResources) {
658 auto result = plan ? self->addSpawner(entryId, *plan, activeInBiome, activeInStamper,
659 autoAssignResources)
660 : missingRaster();
661 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
662 });
663 biomePreset.addFunc("setActiveInBiome", [vm = table.getHandle()](TerrainBiomePreset* self,
664 const std::string& entryId, bool active) {
665 return eve::script::projectResult(vm, self->setActiveInBiome(entryId, active));
666 });
667 biomePreset.addFunc("setActiveInStamper", [vm = table.getHandle()](TerrainBiomePreset* self,
668 const std::string& entryId, bool active) {
669 return eve::script::projectResult(vm, self->setActiveInStamper(entryId, active));
670 });
671 biomePreset.addFunc("getSpawnerCount", [](const TerrainBiomePreset* self) { return self->getSpawnerCount(); });
672 biomePreset.addFunc("getAutoAssignResources", [vm = table.getHandle()](const TerrainBiomePreset* self,
673 const std::string& entryId) {
674 return eve::script::projectResult(vm, self->getAutoAssignResources(entryId),
675 [](bool value) { return eve::Value(value); });
676 });
677 biomePreset.addFunc("snapshotJson", [vm = table.getHandle()](const TerrainBiomePreset* self) {
678 return eve::script::projectResult(vm, self->snapshotJson(),
679 [](const std::string& value) { return eve::Value(value); });
680 });
681 biomePreset.addFunc("restoreJson", [vm = table.getHandle()](TerrainBiomePreset* self,
682 const std::string& json) {
683 return eve::script::projectResult(vm, self->restoreJson(json));
684 });
685
686 auto world = table.addClass("TerrainWorldWorkspace", ssq::Class::Ctor<TerrainWorldWorkspace()>());
687 world.addFunc("create", [vm = table.getHandle()](TerrainWorldWorkspace* self,
688 const TerrainWorldCreationSettings* settings) {
689 auto result = settings ? self->create(*settings) : missingRaster();
690 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
691 });
692 world.addFunc("stamp", [vm = table.getHandle()](TerrainWorldWorkspace* self, const Heightmap* stamp,
693 const TerrainStampSettings* settings, const Heightmap* local,
694 const Heightmap* global) {
695 auto result = stamp && settings && local && global ? self->stamp(*stamp, *settings, *local, *global)
696 : missingRaster();
697 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
698 });
699 world.addFunc("paintSplat", [vm = table.getHandle()](TerrainWorldWorkspace* self, const Heightmap* paint,
700 int layer, const TerrainStampSettings* operation) {
701 auto result = paint && operation ? self->paintSplat(*paint, layer, *operation) : missingRaster();
702 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
703 });
704 world.addFunc("spawn", [vm = table.getHandle()](TerrainWorldWorkspace* self,
705 const TerrainSpawnPlan* plan) {
706 auto result = plan ? self->spawn(*plan) : missingRaster();
707 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
708 });
709 world.addFunc("spawnBiome", [vm = table.getHandle()](TerrainWorldWorkspace* self,
710 const TerrainBiomePreset* preset) {
711 auto result = preset ? self->spawnBiome(*preset) : missingRaster();
712 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
713 });
714 world.addFunc("spawnStamper", [vm = table.getHandle()](TerrainWorldWorkspace* self,
715 const TerrainBiomePreset* preset) {
716 auto result = preset ? self->spawnStamper(*preset) : missingRaster();
717 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
718 });
719 world.addFunc("beginSpawn", [vm = table.getHandle()](TerrainWorldWorkspace* self,
720 const TerrainSpawnPlan* plan) {
721 auto result = plan ? self->beginSpawn(*plan)
723 DiagnosticCode::InvalidArgument, "terrain.world.beginSpawn: plan required"));
724 return eve::script::projectResult(vm, std::move(result),
725 [](TerrainWorldRunStatus status) { return eve::Value(int(status)); });
726 });
727 world.addFunc("beginSpawnBiome", [vm = table.getHandle()](TerrainWorldWorkspace* self,
728 const TerrainBiomePreset* preset) {
729 auto result = preset ? self->beginSpawnBiome(*preset)
732 "terrain.world.beginSpawnBiome: preset required"));
733 return eve::script::projectResult(vm, std::move(result),
734 [](TerrainWorldRunStatus status) { return eve::Value(int(status)); });
735 });
736 world.addFunc("beginSpawnStamper", [vm = table.getHandle()](TerrainWorldWorkspace* self,
737 const TerrainBiomePreset* preset) {
738 auto result = preset ? self->beginSpawnStamper(*preset)
741 "terrain.world.beginSpawnStamper: preset required"));
742 return eve::script::projectResult(vm, std::move(result),
743 [](TerrainWorldRunStatus status) { return eve::Value(int(status)); });
744 });
745 world.addFunc("stepSpawn", [vm = table.getHandle()](TerrainWorldWorkspace* self, int maxRules) {
746 return eve::script::projectResult(vm, self->stepSpawn(maxRules),
747 [](TerrainWorldRunStatus status) { return eve::Value(int(status)); });
748 });
749 world.addFunc("cancelSpawn", [vm = table.getHandle()](TerrainWorldWorkspace* self) {
750 return eve::script::projectResult(vm, self->cancelSpawn(),
751 [](TerrainWorldRunStatus status) { return eve::Value(int(status)); });
752 });
753 world.addFunc("getSpawnStatus", [](const TerrainWorldWorkspace* self) { return int(self->getSpawnStatus()); });
754 world.addFunc("getSpawnCompletedRules",
755 [](const TerrainWorldWorkspace* self) { return self->getSpawnCompletedRules(); });
756 world.addFunc("applyDetail", [vm = table.getHandle()](TerrainWorldWorkspace* self, const Heightmap* fitness,
757 const TerrainDetailSettings* settings,
758 const TerrainStampSettings* operation, int mode,
759 int seed) {
760 auto result = fitness && settings && operation
761 ? self->applyDetail(*fitness, *settings, *operation,
762 static_cast<TerrainDetailMode>(mode), seed)
763 : missingRaster();
764 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
765 });
766 world.addFunc("applyTrees", [vm = table.getHandle()](TerrainWorldWorkspace* self, const Heightmap* fitness,
767 const TerrainTreePlacementSettings* settings,
768 const TerrainStampSettings* operation, int mode) {
769 auto result = fitness && settings && operation
770 ? self->applyTrees(*fitness, *settings, *operation,
771 static_cast<TerrainTreeOperationMode>(mode))
772 : missingRaster();
773 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
774 });
775 world.addFunc("applyObjects", [vm = table.getHandle()](TerrainWorldWorkspace* self,
776 const Heightmap* fitness,
777 const TerrainObjectPlacementSettings* settings,
778 const TerrainStampSettings* operation, int mode) {
779 auto result = fitness && settings && operation
780 ? self->applyObjects(*fitness, *settings, *operation,
781 static_cast<TerrainObjectOperationMode>(mode))
782 : missingRaster();
783 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
784 });
785 world.addFunc("applyProbes", [vm = table.getHandle()](TerrainWorldWorkspace* self,
786 const Heightmap* fitness,
787 const TerrainProbePlacementSettings* settings,
788 const TerrainStampSettings* operation, int mode,
789 int type) {
790 auto result = [&]() -> Result<int> {
791 if (!fitness || !settings || !operation) return missingRaster();
792 auto copy = *settings;
793 copy.type = static_cast<TerrainProbeType>(type);
794 return self->applyProbes(*fitness, copy, *operation,
795 static_cast<TerrainProbeOperationMode>(mode));
796 }();
797 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
798 });
799 auto worldClear = table.addClass("TerrainWorldClearSettings", ssq::Class::Ctor<TerrainWorldClearSettings()>());
800 worldClear.addVar("details", &TerrainWorldClearSettings::details);
801 worldClear.addVar("trees", &TerrainWorldClearSettings::trees);
802 worldClear.addVar("objects", &TerrainWorldClearSettings::objects);
803 worldClear.addVar("probes", &TerrainWorldClearSettings::probes);
804 worldClear.addVar("sourceNamespace", &TerrainWorldClearSettings::sourceNamespace);
805 world.addFunc("flatten", [vm = table.getHandle()](TerrainWorldWorkspace* self) {
806 return eve::script::projectResult(vm, self->flatten(), [](int n) { return eve::Value(n); });
807 });
808 world.addFunc("setHeightWorldUnits",
809 [vm = table.getHandle()](TerrainWorldWorkspace* self, float heightWorldUnits,
810 float worldHeightSpan) {
811 return eve::script::projectResult(vm, self->setHeightWorldUnits(heightWorldUnits, worldHeightSpan),
812 [](int n) { return eve::Value(n); });
813 });
814 world.addFunc("clearSpawns", [vm = table.getHandle()](TerrainWorldWorkspace* self,
815 const TerrainWorldClearSettings* settings) {
816 auto result = settings ? self->clearSpawns(*settings) : missingRaster();
817 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
818 });
819 world.addFunc("copyHeightmap", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index,
820 Heightmap* output) {
821 auto result = output ? self->copyHeightmap(index, *output) : missingRaster();
822 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
823 });
824 world.addFunc("copySplatmap", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index,
825 TerrainSplatmap* output) {
826 auto result = output ? self->copySplatmap(index, *output) : missingRaster();
827 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
828 });
829 world.addFunc("copyDetail", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index,
830 TerrainDetailLayer* output) {
831 auto result = output ? self->copyDetail(index, *output) : missingRaster();
832 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
833 });
834 world.addFunc("copyTrees", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index,
835 PointSet* output) {
836 auto result = output ? self->copyTrees(index, *output) : missingRaster();
837 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
838 });
839 world.addFunc("copyObjects", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index,
840 PointSet* output) {
841 auto result = output ? self->copyObjects(index, *output) : missingRaster();
842 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
843 });
844 world.addFunc("copyProbes", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index,
845 PointSet* output) {
846 auto result = output ? self->copyProbes(index, *output) : missingRaster();
847 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
848 });
849 world.addFunc("getTileName", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index) {
850 return eve::script::projectResult(vm, self->getTileName(index),
851 [](const std::string& value) { return eve::Value(value); });
852 });
853 world.addFunc("getTileOriginX", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index) {
854 return eve::script::projectResult(vm, self->getTileOriginX(index),
855 [](double value) { return eve::Value(value); });
856 });
857 world.addFunc("getTileOriginZ", [vm = table.getHandle()](const TerrainWorldWorkspace* self, int index) {
858 return eve::script::projectResult(vm, self->getTileOriginZ(index),
859 [](double value) { return eve::Value(value); });
860 });
861 world.addFunc("undo", [vm = table.getHandle()](TerrainWorldWorkspace* self) {
862 return eve::script::projectResult(vm, self->undo(), [](int n) { return eve::Value(n); });
863 });
864 world.addFunc("redo", [vm = table.getHandle()](TerrainWorldWorkspace* self) {
865 return eve::script::projectResult(vm, self->redo(), [](int n) { return eve::Value(n); });
866 });
867 world.addFunc("getTileCount", [](const TerrainWorldWorkspace* self) { return self->getTileCount(); });
868 world.addFunc("getLastChangedSamples",
869 [](const TerrainWorldWorkspace* self) { return self->getLastChangedSamples(); });
870 world.addFunc("getLastAffectedTiles",
871 [](const TerrainWorldWorkspace* self) { return self->getLastAffectedTiles(); });
872 world.addFunc("getOperationCount", [](const TerrainWorldWorkspace* self) { return self->getOperationCount(); });
873 world.addFunc("getAppliedCount", [](const TerrainWorldWorkspace* self) { return self->getAppliedCount(); });
874
875 auto tree = table.addClass("TerrainTreePlacementSettings", ssq::Class::Ctor<TerrainTreePlacementSettings()>());
876 tree.addVar("originX", &TerrainTreePlacementSettings::originX);
877 tree.addVar("originZ", &TerrainTreePlacementSettings::originZ);
878 tree.addVar("width", &TerrainTreePlacementSettings::width);
879 tree.addVar("depth", &TerrainTreePlacementSettings::depth);
880 tree.addVar("heightScale", &TerrainTreePlacementSettings::heightScale);
881 tree.addVar("spacing", &TerrainTreePlacementSettings::spacing);
882 tree.addVar("spawnDensity", &TerrainTreePlacementSettings::spawnDensity);
883 tree.addVar("jitterPercent", &TerrainTreePlacementSettings::jitterPercent);
884 tree.addVar("failureRate", &TerrainTreePlacementSettings::failureRate);
885 tree.addVar("minimumFitness", &TerrainTreePlacementSettings::minimumFitness);
886 tree.addVar("snapToTerrain", &TerrainTreePlacementSettings::snapToTerrain);
887 tree.addVar("seaLevel", &TerrainTreePlacementSettings::seaLevel);
888 tree.addVar("customOffset", &TerrainTreePlacementSettings::customOffset);
889 tree.addVar("minimumYOffset", &TerrainTreePlacementSettings::minimumYOffset);
890 tree.addVar("maximumYOffset", &TerrainTreePlacementSettings::maximumYOffset);
891 tree.addVar("minimumWidth", &TerrainTreePlacementSettings::minimumWidth);
892 tree.addVar("maximumWidth", &TerrainTreePlacementSettings::maximumWidth);
893 tree.addVar("minimumHeight", &TerrainTreePlacementSettings::minimumHeight);
894 tree.addVar("maximumHeight", &TerrainTreePlacementSettings::maximumHeight);
895 tree.addVar("widthRandomPercentage", &TerrainTreePlacementSettings::widthRandomPercentage);
896 tree.addVar("heightRandomPercentage", &TerrainTreePlacementSettings::heightRandomPercentage);
897 tree.addVar("healthyR", &TerrainTreePlacementSettings::healthyR);
898 tree.addVar("healthyG", &TerrainTreePlacementSettings::healthyG);
899 tree.addVar("healthyB", &TerrainTreePlacementSettings::healthyB);
900 tree.addVar("healthyA", &TerrainTreePlacementSettings::healthyA);
901 tree.addVar("dryR", &TerrainTreePlacementSettings::dryR);
902 tree.addVar("dryG", &TerrainTreePlacementSettings::dryG);
903 tree.addVar("dryB", &TerrainTreePlacementSettings::dryB);
904 tree.addVar("dryA", &TerrainTreePlacementSettings::dryA);
905 tree.addVar("bendFactor", &TerrainTreePlacementSettings::bendFactor);
906 tree.addVar("boundsRadius", &TerrainTreePlacementSettings::boundsRadius);
907 tree.addVar("seed", &TerrainTreePlacementSettings::seed);
908 tree.addVar("namespaceId", &TerrainTreePlacementSettings::namespaceId);
909 tree.addVar("maxPoints", &TerrainTreePlacementSettings::maxPoints);
910 tree.addVar("asset", &TerrainTreePlacementSettings::asset);
911 tree.addFunc("setScaleMode", [](TerrainTreePlacementSettings* s, int mode) {
912 s->scaleMode = static_cast<TerrainTreeScaleMode>(mode);
913 });
914 tree.addFunc("getScaleMode", [](const TerrainTreePlacementSettings* s) { return int(s->scaleMode); });
915 tree.addFunc("setYOffsetMode", [](TerrainTreePlacementSettings* s, int mode) {
916 s->yOffsetMode = static_cast<TerrainTreeYOffsetMode>(mode);
917 });
918 tree.addFunc("getYOffsetMode", [](const TerrainTreePlacementSettings* s) { return int(s->yOffsetMode); });
919 table.addFunc("exportTerrainTreePoints",
920 [vm = table.getHandle()](PointSet* output, const Heightmap* fitness, const Heightmap* heights,
921 const TerrainTreePlacementSettings* settings) {
922 auto result = output && fitness && heights && settings
923 ? exportTerrainTreePoints(*output, *fitness, *heights, *settings)
924 : missingRaster();
925 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
926 });
927 table.addFunc("removeTerrainTreePoints",
928 [vm = table.getHandle()](PointSet* output, const PointSet* input, const Heightmap* fitness,
929 const TerrainTreePlacementSettings* settings) {
930 auto result = output && input && fitness && settings
932 : missingRaster();
933 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
934 });
935
936 auto rescale = table.addClass("TerrainTreeRescaleSettings", ssq::Class::Ctor<TerrainTreeRescaleSettings()>());
937 rescale.addVar("previousMinimumWidth", &TerrainTreeRescaleSettings::previousMinimumWidth);
938 rescale.addVar("previousMaximumWidth", &TerrainTreeRescaleSettings::previousMaximumWidth);
939 rescale.addVar("previousMinimumHeight", &TerrainTreeRescaleSettings::previousMinimumHeight);
940 rescale.addVar("previousMaximumHeight", &TerrainTreeRescaleSettings::previousMaximumHeight);
941 rescale.addVar("minimumWidth", &TerrainTreeRescaleSettings::minimumWidth);
942 rescale.addVar("maximumWidth", &TerrainTreeRescaleSettings::maximumWidth);
943 rescale.addVar("minimumHeight", &TerrainTreeRescaleSettings::minimumHeight);
944 rescale.addVar("maximumHeight", &TerrainTreeRescaleSettings::maximumHeight);
945 rescale.addVar("bendFactor", &TerrainTreeRescaleSettings::bendFactor);
946 rescale.addVar("boundsRadius", &TerrainTreeRescaleSettings::boundsRadius);
947 rescale.addVar("asset", &TerrainTreeRescaleSettings::asset);
948 rescale.addFunc("setScaleMode", [](TerrainTreeRescaleSettings* s, int mode) {
949 s->scaleMode = static_cast<TerrainTreeScaleMode>(mode);
950 });
951 rescale.addFunc("getScaleMode", [](const TerrainTreeRescaleSettings* s) { return int(s->scaleMode); });
952 table.addFunc("rescaleTerrainTreePoints",
953 [vm = table.getHandle()](PointSet* output, const PointSet* input,
954 const TerrainTreeRescaleSettings* settings) {
956 : missingRaster();
957 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
958 });
959
960 auto placement =
961 table.addClass("TerrainDetailPlacementSettings", ssq::Class::Ctor<TerrainDetailPlacementSettings()>());
962 placement.addVar("originX", &TerrainDetailPlacementSettings::originX);
963 placement.addVar("originZ", &TerrainDetailPlacementSettings::originZ);
964 placement.addVar("width", &TerrainDetailPlacementSettings::width);
965 placement.addVar("depth", &TerrainDetailPlacementSettings::depth);
966 placement.addVar("heightScale", &TerrainDetailPlacementSettings::heightScale);
967 placement.addVar("minimumScale", &TerrainDetailPlacementSettings::minimumScale);
968 placement.addVar("maximumScale", &TerrainDetailPlacementSettings::maximumScale);
969 placement.addVar("minimumWidth", &TerrainDetailPlacementSettings::minimumWidth);
970 placement.addVar("maximumWidth", &TerrainDetailPlacementSettings::maximumWidth);
971 placement.addVar("minimumHeight", &TerrainDetailPlacementSettings::minimumHeight);
972 placement.addVar("maximumHeight", &TerrainDetailPlacementSettings::maximumHeight);
973 placement.addVar("healthyR", &TerrainDetailPlacementSettings::healthyR);
974 placement.addVar("healthyG", &TerrainDetailPlacementSettings::healthyG);
975 placement.addVar("healthyB", &TerrainDetailPlacementSettings::healthyB);
976 placement.addVar("healthyA", &TerrainDetailPlacementSettings::healthyA);
977 placement.addVar("dryR", &TerrainDetailPlacementSettings::dryR);
978 placement.addVar("dryG", &TerrainDetailPlacementSettings::dryG);
979 placement.addVar("dryB", &TerrainDetailPlacementSettings::dryB);
980 placement.addVar("dryA", &TerrainDetailPlacementSettings::dryA);
981 placement.addVar("noiseSpread", &TerrainDetailPlacementSettings::noiseSpread);
982 placement.addVar("noiseSeed", &TerrainDetailPlacementSettings::noiseSeed);
983 placement.addVar("seed", &TerrainDetailPlacementSettings::seed);
984 placement.addVar("namespaceId", &TerrainDetailPlacementSettings::namespaceId);
985 placement.addVar("densityNamespaceId", &TerrainDetailPlacementSettings::densityNamespaceId);
986 placement.addVar("maxPoints", &TerrainDetailPlacementSettings::maxPoints);
987 placement.addVar("asset", &TerrainDetailPlacementSettings::asset);
988 table.addFunc("exportTerrainDetailPoints",
989 [vm = table.getHandle()](PointSet* output, const TerrainDetailLayer* layer, const Heightmap* heights,
990 const TerrainDetailPlacementSettings* settings) {
991 auto result = output && layer && heights && settings
993 : missingRaster();
994 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
995 });
996
997 auto detailSettings = table.addClass("TerrainDetailSettings", ssq::Class::Ctor<TerrainDetailSettings()>());
998 detailSettings.addVar("minimumFitness", &TerrainDetailSettings::minimumFitness);
999 detailSettings.addVar("fadeStart", &TerrainDetailSettings::fadeStart);
1000 detailSettings.addVar("density", &TerrainDetailSettings::density);
1001 detailSettings.addVar("namespaceId", &TerrainDetailSettings::namespaceId);
1002 auto detail = table.addClass("TerrainDetailLayer", ssq::Class::Ctor<TerrainDetailLayer()>());
1003 detail.addFunc("getWidth", [](const TerrainDetailLayer* s) { return s->getWidth(); });
1004 detail.addFunc("getHeight", [](const TerrainDetailLayer* s) { return s->getHeight(); });
1005 detail.addFunc("reset", [vm = table.getHandle()](TerrainDetailLayer* s, int width, int height, int count) {
1006 return eve::script::projectResult(vm, s->reset(width, height, count), [](int n) { return eve::Value(n); });
1007 });
1008 detail.addFunc("sample", [vm = table.getHandle()](const TerrainDetailLayer* s, int x, int z) {
1009 return eve::script::projectResult(vm, s->sample(x, z), [](int n) { return eve::Value(n); });
1010 });
1011 detail.addFunc("apply", [vm = table.getHandle()](TerrainDetailLayer* s, const Heightmap* fitness,
1012 const TerrainDetailSettings* settings, int mode, int seed) {
1013 auto result = [&]() -> Result<int> {
1014 if (!fitness || !settings) return missingRaster();
1015 auto copy = *settings;
1016 copy.mode = static_cast<TerrainDetailMode>(mode);
1017 return s->apply(*fitness, copy, seed);
1018 }();
1019 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1020 });
1021
1022 auto session = table.addClass("TerrainGenerationSession", ssq::Class::Ctor<TerrainGenerationSession()>());
1023 session.addFunc("smooth", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* mask,
1024 const TerrainSmoothSettings* settings) {
1025 auto result = mask && settings ? s->smooth(*mask, *settings) : missingRaster();
1026 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1027 });
1028 session.addFunc("ridges", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* mask,
1029 const TerrainRidgeSettings* settings) {
1030 auto result = mask && settings ? s->ridges(*mask, *settings) : missingRaster();
1031 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1032 });
1033 session.addFunc("terrace", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* mask,
1034 const TerrainTerraceSettings* settings) {
1035 auto result = mask && settings ? s->terrace(*mask, *settings) : missingRaster();
1036 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1037 });
1038 session.addFunc("contrast", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* mask,
1039 float strength, float featureSize) {
1040 auto result = mask ? s->contrast(*mask, strength, featureSize) : missingRaster();
1041 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1042 });
1043 session.addFunc("power", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* mask, float power) {
1044 auto result = mask ? s->power(*mask, power) : missingRaster();
1045 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1046 });
1047 session.addFunc("heightCurve", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* mask,
1048 const Heightmap* curve, float minimum, float maximum) {
1049 auto result = mask && curve ? s->heightCurve(*mask, *curve, minimum, maximum) : missingRaster();
1050 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1051 });
1052 session.addFunc(
1053 "heightMix", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* local,
1054 const Heightmap* global, const TerrainHeightMixSettings* settings) {
1055 auto result = local && global && settings ? s->heightMix(*local, *global, *settings) : missingRaster();
1056 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1057 });
1058 session.addFunc("resetSimulation", [vm = table.getHandle()](TerrainGenerationSession* s, float depth) {
1059 return eve::script::projectResult(vm, s->resetSimulation(depth), [](int n) { return eve::Value(n); });
1060 });
1061 session.addFunc("thermal",
1062 [vm = table.getHandle()](TerrainGenerationSession* s, const TerrainThermalSettings* settings) {
1063 auto result = settings ? s->thermal(*settings) : missingRaster();
1064 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1065 });
1066 session.addFunc(
1067 "hydraulic", [vm = table.getHandle()](TerrainGenerationSession* s, const TerrainWaterSettings* water,
1068 const TerrainSedimentSettings* sediment,
1069 const TerrainThermalSettings* thermal, int iterations) {
1070 auto result =
1071 water && sediment && thermal ? s->hydraulic(*water, *sediment, *thermal, iterations) : missingRaster();
1072 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1073 });
1074 session.addFunc("copySediment", [vm = table.getHandle()](const TerrainGenerationSession* s, Heightmap* target) {
1075 auto result = target ? s->copySediment(*target) : missingRaster();
1076 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1077 });
1078 session.addFunc(
1079 "exportWater", [vm = table.getHandle()](const TerrainGenerationSession* s, Heightmap* target, int channel) {
1080 auto result = target ? s->exportWater(*target, static_cast<TerrainWaterChannel>(channel)) : missingRaster();
1081 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1082 });
1083 session.addFunc("getOperationCount", [](const TerrainGenerationSession* s) { return s->getOperationCount(); });
1084 session.addFunc("getAppliedCount", [](const TerrainGenerationSession* s) { return s->getAppliedCount(); });
1085 session.addFunc("getReplayStatus", [](const TerrainGenerationSession* s) { return int(s->getReplayStatus()); });
1086 session.addFunc("getReplayCompletedOperations",
1087 [](const TerrainGenerationSession* s) { return s->getReplayCompletedOperations(); });
1088 session.addFunc("getAccess", [](const TerrainGenerationSession* s) { return int(s->getAccess()); });
1089 session.addFunc("snapshotJson", [vm = table.getHandle()](const TerrainGenerationSession* s) {
1090 return eve::script::projectResult(vm, s->snapshotJson(),
1091 [](const std::string& value) { return eve::Value(value); });
1092 });
1093 session.addFunc("restoreJson", [vm = table.getHandle()](TerrainGenerationSession* s,
1094 const std::string& json) {
1095 return eve::script::projectResult(vm, s->restoreJson(json));
1096 });
1097 session.addFunc("setAccess", [vm = table.getHandle()](TerrainGenerationSession* s, int access) {
1098 return eve::script::projectResult(vm, s->setAccess(static_cast<TerrainSessionAccess>(access)));
1099 });
1100 session.addFunc("operationEnabled", [vm = table.getHandle()](const TerrainGenerationSession* s, int index) {
1101 return eve::script::projectResult(vm, s->operationEnabled(index), [](bool value) { return eve::Value(value); });
1102 });
1103 session.addFunc("reset", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* baseline) {
1104 auto result = baseline ? s->reset(*baseline) : missingRaster();
1105 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1106 });
1107 session.addFunc("copyTerrain", [vm = table.getHandle()](const TerrainGenerationSession* s, Heightmap* target) {
1108 auto result = target ? s->copyTerrain(*target) : missingRaster();
1109 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1110 });
1111 session.addFunc("setOperationEnabled",
1112 [vm = table.getHandle()](TerrainGenerationSession* s, int index, bool enabled) {
1113 return eve::script::projectResult(vm, s->setOperationEnabled(index, enabled),
1114 [](int n) { return eve::Value(n); });
1115 });
1116 session.addFunc("undo", [vm = table.getHandle()](TerrainGenerationSession* s) {
1117 return eve::script::projectResult(vm, s->undo(), [](int n) { return eve::Value(n); });
1118 });
1119 session.addFunc("redo", [vm = table.getHandle()](TerrainGenerationSession* s) {
1120 return eve::script::projectResult(vm, s->redo(), [](int n) { return eve::Value(n); });
1121 });
1122 session.addFunc("replay", [vm = table.getHandle()](TerrainGenerationSession* s) {
1123 return eve::script::projectResult(vm, s->replay(), [](int n) { return eve::Value(n); });
1124 });
1125 session.addFunc("beginReplay", [vm = table.getHandle()](TerrainGenerationSession* s) {
1126 return eve::script::projectResult(vm, s->beginReplay(),
1127 [](TerrainSessionRunStatus status) { return eve::Value(int(status)); });
1128 });
1129 session.addFunc("stepReplay", [vm = table.getHandle()](TerrainGenerationSession* s, int maxOperations) {
1130 return eve::script::projectResult(vm, s->stepReplay(maxOperations),
1131 [](TerrainSessionRunStatus status) { return eve::Value(int(status)); });
1132 });
1133 session.addFunc("cancelReplay", [vm = table.getHandle()](TerrainGenerationSession* s) {
1134 return eve::script::projectResult(vm, s->cancelReplay(),
1135 [](TerrainSessionRunStatus status) { return eve::Value(int(status)); });
1136 });
1137 session.addFunc("stamp", [vm = table.getHandle()](TerrainGenerationSession* s, const Heightmap* stamp,
1138 const TerrainStampSettings* settings, int operation,
1139 const Heightmap* local, const Heightmap* global) {
1140 auto result = [&]() -> Result<int> {
1141 if (!stamp || !settings || !local || !global) return missingRaster();
1142 auto copy = *settings;
1143 copy.operation = static_cast<TerrainStampOperation>(operation);
1144 return s->stamp(*stamp, copy, *local, *global);
1145 }();
1146 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1147 });
1148
1149 auto settings = table.addClass("TerrainStampSettings", ssq::Class::Ctor<TerrainStampSettings()>());
1150 // The pinned VM uses float SQFloat; bind explicit float adapters for double world coordinates.
1151 settings.addFunc("setGrid", [](TerrainStampSettings* s, float x, float z, float dx, float dz) {
1152 s->originX = x;
1153 s->originZ = z;
1154 s->spacingX = dx;
1155 s->spacingZ = dz;
1156 });
1157 settings.addFunc("setCenter", [](TerrainStampSettings* s, float x, float z) {
1158 s->centerX = x;
1159 s->centerZ = z;
1160 });
1161 settings.addFunc("setSize", [](TerrainStampSettings* s, float width, float depth) {
1162 s->width = width;
1163 s->depth = depth;
1164 });
1165 settings.addFunc("setRotation", [](TerrainStampSettings* s, float radians) { s->rotation = radians; });
1166 settings.addVar("amplitude", &TerrainStampSettings::amplitude);
1167 settings.addVar("baseHeight", &TerrainStampSettings::baseHeight);
1168 settings.addVar("blendStrength", &TerrainStampSettings::blendStrength);
1169
1170 auto stitchSettings =
1171 table.addClass("TerrainHeightStitchSettings", ssq::Class::Ctor<TerrainHeightStitchSettings()>());
1172 stitchSettings.addVar("extraSeamSize", &TerrainHeightStitchSettings::extraSeamSize);
1173 stitchSettings.addVar("maxDifference", &TerrainHeightStitchSettings::maxDifference);
1174 auto multi = table.addClass("TerrainMultiTileWorkspace", ssq::Class::Ctor<TerrainMultiTileWorkspace()>());
1175 multi.addFunc("addTile", [vm = table.getHandle()](TerrainMultiTileWorkspace* workspace,
1176 const std::string& name, const Heightmap* heightmap,
1177 float originX, float originZ, float width, float depth,
1178 bool worldMap) {
1179 auto result = heightmap ? workspace->addTile(name, *heightmap, originX, originZ, width, depth, worldMap)
1180 : missingRaster();
1181 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1182 });
1183 detail.addFunc("sampleResource", [vm = table.getHandle()](const TerrainDetailLayer* s,
1184 std::uint64_t namespaceId, int x, int z) {
1185 return eve::script::projectResult(vm, s->sampleResource(namespaceId, x, z),
1186 [](int n) { return eve::Value(n); });
1187 });
1188 detail.addFunc("clearResource", [vm = table.getHandle()](TerrainDetailLayer* s,
1189 std::uint64_t namespaceId) {
1190 return eve::script::projectResult(vm, s->clearResource(namespaceId),
1191 [](int n) { return eve::Value(n); });
1192 });
1193 multi.addFunc("stamp", [vm = table.getHandle()](TerrainMultiTileWorkspace* workspace,
1194 const Heightmap* stampRaster,
1195 const TerrainStampSettings* stampSettings, int operation,
1196 const Heightmap* localMask, const Heightmap* globalMask,
1197 bool worldMap) {
1198 auto result = [&]() -> Result<int> {
1199 if (!stampRaster || !stampSettings || !localMask || !globalMask) return missingRaster();
1200 auto copy = *stampSettings;
1201 copy.operation = static_cast<TerrainStampOperation>(operation);
1202 return workspace->stamp(*stampRaster, copy, *localMask, *globalMask, worldMap);
1203 }();
1204 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1205 });
1206 multi.addFunc("copyTile", [vm = table.getHandle()](const TerrainMultiTileWorkspace* workspace,
1207 const std::string& name, Heightmap* output) {
1208 auto result = output ? workspace->copyTile(name, *output) : missingRaster();
1209 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1210 });
1211 multi.addFunc("stitch", [vm = table.getHandle()](TerrainMultiTileWorkspace* workspace,
1212 const std::string& terrainA,
1213 const std::string& terrainB,
1214 const TerrainHeightStitchSettings* settings) {
1215 auto result = settings ? workspace->stitch(terrainA, terrainB, *settings) : missingRaster();
1216 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1217 });
1218 multi.addFunc("undo", [vm = table.getHandle()](TerrainMultiTileWorkspace* workspace) {
1219 return eve::script::projectResult(vm, workspace->undo(), [](int n) { return eve::Value(n); });
1220 });
1221 multi.addFunc("redo", [vm = table.getHandle()](TerrainMultiTileWorkspace* workspace) {
1222 return eve::script::projectResult(vm, workspace->redo(), [](int n) { return eve::Value(n); });
1223 });
1224 multi.addFunc("getTileCount", [](const TerrainMultiTileWorkspace* workspace) { return workspace->getTileCount(); });
1225 multi.addFunc("getLastAffectedTiles", [](const TerrainMultiTileWorkspace* workspace) {
1226 return workspace->getLastAffectedTiles();
1227 });
1228 multi.addFunc("getLastChangedSamples", [](const TerrainMultiTileWorkspace* workspace) {
1229 return workspace->getLastChangedSamples();
1230 });
1231 multi.addFunc("getLastMappingCount", [](const TerrainMultiTileWorkspace* workspace) {
1232 return workspace->getLastMappingCount();
1233 });
1234 multi.addFunc("getOperationCount", [](const TerrainMultiTileWorkspace* workspace) {
1235 return workspace->getOperationCount();
1236 });
1237 multi.addFunc("getAppliedCount", [](const TerrainMultiTileWorkspace* workspace) {
1238 return workspace->getAppliedCount();
1239 });
1240
1241 auto multiDetail =
1242 table.addClass("TerrainMultiDetailWorkspace", ssq::Class::Ctor<TerrainMultiDetailWorkspace()>());
1243 multiDetail.addFunc("addTile", [vm = table.getHandle()](TerrainMultiDetailWorkspace* workspace,
1244 const std::string& name,
1245 const TerrainDetailLayer* layer, float originX,
1246 float originZ, float width, float depth, bool worldMap) {
1247 auto result = layer ? workspace->addTile(name, *layer, originX, originZ, width, depth, worldMap)
1248 : missingRaster();
1249 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1250 });
1251 multiDetail.addFunc(
1252 "apply", [vm = table.getHandle()](TerrainMultiDetailWorkspace* workspace, const Heightmap* fitness,
1253 const TerrainDetailSettings* settings,
1254 const TerrainStampSettings* operationSettings, int mode, int seed,
1255 bool worldMap) {
1256 auto result = [&]() -> Result<int> {
1257 if (!fitness || !settings || !operationSettings) return missingRaster();
1258 auto copy = *settings;
1259 copy.mode = static_cast<TerrainDetailMode>(mode);
1260 return workspace->apply(*fitness, copy, *operationSettings, seed, worldMap);
1261 }();
1262 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1263 });
1264 multiDetail.addFunc("copyTile", [vm = table.getHandle()](const TerrainMultiDetailWorkspace* workspace,
1265 const std::string& name,
1266 TerrainDetailLayer* output) {
1267 auto result = output ? workspace->copyTile(name, *output) : missingRaster();
1268 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1269 });
1270 multiDetail.addFunc("undo", [vm = table.getHandle()](TerrainMultiDetailWorkspace* workspace) {
1271 return eve::script::projectResult(vm, workspace->undo(), [](int n) { return eve::Value(n); });
1272 });
1273 multiDetail.addFunc("redo", [vm = table.getHandle()](TerrainMultiDetailWorkspace* workspace) {
1274 return eve::script::projectResult(vm, workspace->redo(), [](int n) { return eve::Value(n); });
1275 });
1276 multiDetail.addFunc("getTileCount",
1277 [](const TerrainMultiDetailWorkspace* workspace) { return workspace->getTileCount(); });
1278 multiDetail.addFunc("getLastChangedSamples", [](const TerrainMultiDetailWorkspace* workspace) {
1279 return workspace->getLastChangedSamples();
1280 });
1281 multiDetail.addFunc("getLastAffectedTiles", [](const TerrainMultiDetailWorkspace* workspace) {
1282 return workspace->getLastAffectedTiles();
1283 });
1284 multiDetail.addFunc("getOperationCount", [](const TerrainMultiDetailWorkspace* workspace) {
1285 return workspace->getOperationCount();
1286 });
1287 multiDetail.addFunc("getAppliedCount", [](const TerrainMultiDetailWorkspace* workspace) {
1288 return workspace->getAppliedCount();
1289 });
1290
1291 auto multiTree = table.addClass("TerrainMultiTreeWorkspace", ssq::Class::Ctor<TerrainMultiTreeWorkspace()>());
1292 multiTree.addFunc("addTile", [vm = table.getHandle()](TerrainMultiTreeWorkspace* workspace,
1293 const std::string& name, const PointSet* trees,
1294 const Heightmap* heights, float originX, float originZ,
1295 float width, float depth, int resolutionX,
1296 int resolutionY, bool worldMap) {
1297 auto result = trees && heights ? workspace->addTile(name, *trees, *heights, originX, originZ, width, depth,
1298 resolutionX, resolutionY, worldMap)
1299 : missingRaster();
1300 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1301 });
1302 multiTree.addFunc("apply", [vm = table.getHandle()](TerrainMultiTreeWorkspace* workspace,
1303 const Heightmap* fitness,
1304 const TerrainTreePlacementSettings* settings,
1305 const TerrainStampSettings* operationSettings, int mode,
1306 bool worldMap) {
1307 auto result = fitness && settings && operationSettings
1308 ? workspace->apply(*fitness, *settings, *operationSettings,
1309 static_cast<TerrainTreeOperationMode>(mode), worldMap)
1310 : missingRaster();
1311 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1312 });
1313 multiTree.addFunc("copyTile", [vm = table.getHandle()](const TerrainMultiTreeWorkspace* workspace,
1314 const std::string& name, PointSet* output) {
1315 auto result = output ? workspace->copyTile(name, *output) : missingRaster();
1316 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1317 });
1318 multiTree.addFunc("undo", [vm = table.getHandle()](TerrainMultiTreeWorkspace* workspace) {
1319 return eve::script::projectResult(vm, workspace->undo(), [](int n) { return eve::Value(n); });
1320 });
1321 multiTree.addFunc("redo", [vm = table.getHandle()](TerrainMultiTreeWorkspace* workspace) {
1322 return eve::script::projectResult(vm, workspace->redo(), [](int n) { return eve::Value(n); });
1323 });
1324 multiTree.addFunc("getTileCount",
1325 [](const TerrainMultiTreeWorkspace* workspace) { return workspace->getTileCount(); });
1326 multiTree.addFunc("getLastChangedSamples", [](const TerrainMultiTreeWorkspace* workspace) {
1327 return workspace->getLastChangedSamples();
1328 });
1329 multiTree.addFunc("getLastAffectedTiles", [](const TerrainMultiTreeWorkspace* workspace) {
1330 return workspace->getLastAffectedTiles();
1331 });
1332 multiTree.addFunc("getOperationCount", [](const TerrainMultiTreeWorkspace* workspace) {
1333 return workspace->getOperationCount();
1334 });
1335 multiTree.addFunc("getAppliedCount", [](const TerrainMultiTreeWorkspace* workspace) {
1336 return workspace->getAppliedCount();
1337 });
1338
1339 auto distance = table.addClass("TerrainDistanceMaskSettings", ssq::Class::Ctor<TerrainDistanceMaskSettings()>());
1347
1348 auto smooth = table.addClass("TerrainSmoothSettings", ssq::Class::Ctor<TerrainSmoothSettings()>());
1349 smooth.addVar("radius", &TerrainSmoothSettings::radius);
1350 smooth.addVar("verticality", &TerrainSmoothSettings::verticality);
1351 smooth.addVar("strength", &TerrainSmoothSettings::strength);
1352 auto ridge = table.addClass("TerrainRidgeSettings", ssq::Class::Ctor<TerrainRidgeSettings()>());
1353 ridge.addVar("mixStrength", &TerrainRidgeSettings::mixStrength);
1354 ridge.addVar("exponent", &TerrainRidgeSettings::exponent);
1355 ridge.addVar("strength", &TerrainRidgeSettings::strength);
1356 ridge.addVar("minimum", &TerrainRidgeSettings::minimum);
1357 ridge.addVar("maximum", &TerrainRidgeSettings::maximum);
1358 ridge.addVar("passes", &TerrainRidgeSettings::passes);
1359 auto terrace = table.addClass("TerrainTerraceSettings", ssq::Class::Ctor<TerrainTerraceSettings()>());
1360 terrace.addVar("count", &TerrainTerraceSettings::count);
1361 terrace.addVar("bevel", &TerrainTerraceSettings::bevel);
1362 terrace.addVar("strength", &TerrainTerraceSettings::strength);
1363
1364 auto mix = table.addClass("TerrainHeightMixSettings", ssq::Class::Ctor<TerrainHeightMixSettings()>());
1365 mix.addVar("minimum", &TerrainHeightMixSettings::minimum);
1366 mix.addVar("maximum", &TerrainHeightMixSettings::maximum);
1367 mix.addVar("midpoint", &TerrainHeightMixSettings::midpoint);
1368 mix.addVar("strength", &TerrainHeightMixSettings::strength);
1369 mix.addVar("clipMinimum", &TerrainHeightMixSettings::clipMinimum);
1370 mix.addVar("clipMaximum", &TerrainHeightMixSettings::clipMaximum);
1371
1372 auto thermal = table.addClass("TerrainThermalSettings", ssq::Class::Ctor<TerrainThermalSettings()>());
1373 thermal.addVar("spacingX", &TerrainThermalSettings::spacingX);
1374 thermal.addVar("spacingZ", &TerrainThermalSettings::spacingZ);
1375 thermal.addVar("heightScale", &TerrainThermalSettings::heightScale);
1376 thermal.addVar("reposeSlope", &TerrainThermalSettings::reposeSlope);
1377 thermal.addVar("dt", &TerrainThermalSettings::dt);
1378 thermal.addVar("iterations", &TerrainThermalSettings::iterations);
1379
1380 auto waterSettings = table.addClass("TerrainWaterSettings", ssq::Class::Ctor<TerrainWaterSettings()>());
1381 waterSettings.addVar("spacingX", &TerrainWaterSettings::spacingX);
1382 waterSettings.addVar("spacingZ", &TerrainWaterSettings::spacingZ);
1383 waterSettings.addVar("heightScale", &TerrainWaterSettings::heightScale);
1384 waterSettings.addVar("waterScale", &TerrainWaterSettings::waterScale);
1385 waterSettings.addVar("dt", &TerrainWaterSettings::dt);
1386 waterSettings.addVar("precipitation", &TerrainWaterSettings::precipitation);
1387 waterSettings.addVar("evaporation", &TerrainWaterSettings::evaporation);
1388 waterSettings.addVar("flowAcceleration", &TerrainWaterSettings::flowAcceleration);
1389
1390 auto waterFlowSettings = table.addClass("TerrainWaterFlowMapSettings", ssq::Class::Ctor<TerrainWaterFlowMapSettings()>());
1391 waterFlowSettings.addVar("dropletVolume", &TerrainWaterFlowMapSettings::dropletVolume);
1392 waterFlowSettings.addVar("absorptionRate", &TerrainWaterFlowMapSettings::absorptionRate);
1393 waterFlowSettings.addVar("smoothIterations", &TerrainWaterFlowMapSettings::smoothIterations);
1394 table.addFunc("generateTerrainWaterFlowMap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1395 const TerrainWaterFlowMapSettings* settings) {
1396 auto result = target && source && settings
1399 "terrain.waterFlow: target, source and settings required"));
1400 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1401 });
1402 table.addFunc("generateTerrainVelocityFlowMap", [vm = table.getHandle()](Heightmap* target,
1403 const Heightmap* source,
1404 int iterations) {
1405 auto result = target && source ? generateTerrainVelocityFlowMap(*target, *source, iterations) : missingRaster();
1406 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1407 });
1408 table.addFunc("generateTerrainHeightmapCurvature", [vm = table.getHandle()](Heightmap* target,
1409 const Heightmap* source, int mode) {
1410 auto result = target && source
1412 static_cast<TerrainHeightmapCurvature>(mode))
1413 : missingRaster();
1414 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1415 });
1416 table.addFunc("generateTerrainHeightmapAspect", [vm = table.getHandle()](Heightmap* target,
1417 const Heightmap* source, int mode) {
1418 auto result = target && source
1420 static_cast<TerrainHeightmapAspect>(mode))
1421 : missingRaster();
1422 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1423 });
1424 table.addFunc("filterTerrainHeightmapNeighborhood", [vm = table.getHandle()](Heightmap* target,
1425 const Heightmap* source, int radius,
1426 int mode) {
1427 auto result = target && source
1429 static_cast<TerrainHeightmapNeighborhood>(mode))
1430 : missingRaster();
1431 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1432 });
1433 table.addFunc("smoothTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1434 int iterations) {
1435 auto result = target && source ? smoothTerrainHeightmap(*target, *source, iterations) : missingRaster();
1436 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1437 });
1438 table.addFunc("smoothTerrainHeightmapRadius", [vm = table.getHandle()](Heightmap* target,
1439 const Heightmap* source, int radius) {
1440 auto result = target && source ? smoothTerrainHeightmapRadius(*target, *source, radius) : missingRaster();
1441 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1442 });
1443 table.addFunc("convolveTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1444 const Heightmap* kernel) {
1445 auto result = target && source && kernel ? convolveTerrainHeightmap(*target, *source, *kernel) : missingRaster();
1446 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1447 });
1448 table.addFunc("generateTerrainHeightmapSlope", [vm = table.getHandle()](Heightmap* target,
1449 const Heightmap* source) {
1450 auto result = target && source ? generateTerrainHeightmapSlope(*target, *source) : missingRaster();
1451 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1452 });
1453 table.addFunc("quantizeTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1454 float divisor) {
1455 auto result = target && source ? quantizeTerrainHeightmap(*target, *source, divisor) : missingRaster();
1456 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1457 });
1458 table.addFunc("applyTerrainHeightmapScalarArithmetic",
1459 [vm = table.getHandle()](Heightmap* target, const Heightmap* source, float operand, int operation,
1460 bool clampResult, float minValue, float maxValue) {
1461 auto result = target && source
1463 *target, *source, operand,
1464 static_cast<TerrainHeightmapArithmetic>(operation), clampResult,
1465 minValue, maxValue)
1466 : missingRaster();
1467 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1468 });
1469 table.addFunc("applyTerrainHeightmapRasterArithmetic",
1470 [vm = table.getHandle()](Heightmap* target, const Heightmap* source, const Heightmap* operand,
1471 int operation, bool clampResult, float minValue, float maxValue) {
1472 auto result = target && source && operand
1474 *target, *source, *operand,
1475 static_cast<TerrainHeightmapArithmetic>(operation), clampResult,
1476 minValue, maxValue)
1477 : missingRaster();
1478 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1479 });
1480 table.addFunc("lerpTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1481 const Heightmap* values, const Heightmap* mask) {
1482 auto result = target && source && values && mask ? lerpTerrainHeightmap(*target, *source, *values, *mask)
1483 : missingRaster();
1484 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1485 });
1486 table.addFunc("transformTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1487 int transform, float parameter) {
1488 auto result = target && source
1490 parameter)
1491 : missingRaster();
1492 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1493 });
1494 table.addFunc("copyTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1495 int mode) {
1496 auto result = target && source
1497 ? copyTerrainHeightmap(*target, *source, static_cast<TerrainHeightmapCopy>(mode))
1498 : missingRaster();
1499 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1500 });
1501 table.addFunc("copyTerrainHeightmapClamped", [vm = table.getHandle()](Heightmap* target,
1502 const Heightmap* source, float minValue,
1503 float maxValue) {
1504 auto result = target && source ? copyTerrainHeightmapClamped(*target, *source, minValue, maxValue)
1505 : missingRaster();
1506 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1507 });
1508 table.addFunc("flipTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, const Heightmap* source) {
1509 auto result = target && source ? flipTerrainHeightmap(*target, *source) : missingRaster();
1510 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1511 });
1512 table.addFunc("measureTerrainHeightmap", [vm = table.getHandle()](const Heightmap* source, int measure) {
1513 auto result = source
1514 ? measureTerrainHeightmap(*source, static_cast<TerrainHeightmapMeasure>(measure))
1515 : Result<double>::failure(missingRaster().status());
1516 return eve::script::projectResult(vm, std::move(result), [](double value) { return eve::Value(value); });
1517 });
1518 table.addFunc("quantizeTerrainHeightmapTerraces",
1519 [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1520 const Heightmap* startHeights, const Heightmap* curves) {
1521 auto result = target && source && startHeights && curves
1522 ? quantizeTerrainHeightmapTerraces(*target, *source, *startHeights, *curves)
1523 : missingRaster();
1524 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1525 });
1526 table.addFunc("measureTerrainHeightmapSlope",
1527 [vm = table.getHandle()](const Heightmap* source, float x, float y, int mode) {
1528 auto result = source
1530 *source, x, y, static_cast<TerrainHeightmapSlopeQuery>(mode))
1531 : Result<double>::failure(missingRaster().status());
1532 return eve::script::projectResult(vm, std::move(result),
1533 [](double value) { return eve::Value(value); });
1534 });
1535 table.addFunc("fillTerrainHeightmap", [vm = table.getHandle()](Heightmap* target, float value) {
1536 auto result = target ? fillTerrainHeightmap(*target, value) : missingRaster();
1537 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1538 });
1539 table.addFunc("setTerrainHeightmapSafe",
1540 [vm = table.getHandle()](Heightmap* target, int x, int y, float value) {
1541 auto result = target ? setTerrainHeightmapSafe(*target, x, y, value) : missingRaster();
1542 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1543 });
1544 table.addFunc("setTerrainHeightmapRow", [vm = table.getHandle()](Heightmap* target, int rowX,
1545 const Heightmap* values) {
1546 auto result = target && values ? setTerrainHeightmapRow(*target, rowX, *values) : missingRaster();
1547 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1548 });
1549 table.addFunc("setTerrainHeightmapColumn", [vm = table.getHandle()](Heightmap* target, int columnZ,
1550 const Heightmap* values) {
1551 auto result = target && values ? setTerrainHeightmapColumn(*target, columnZ, *values) : missingRaster();
1552 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1553 });
1554 table.addFunc("resetTerrainHeightmap", [vm = table.getHandle()](Heightmap* target) {
1555 auto result = target ? resetTerrainHeightmap(*target) : missingRaster();
1556 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1557 });
1558 table.addFunc("sampleTerrainHeightmapSafe", [vm = table.getHandle()](const Heightmap* source, int x, int z) {
1559 auto result = source ? sampleTerrainHeightmapSafe(*source, x, z)
1561 "terrain: heightmap required"));
1562 return eve::script::projectResult(vm, std::move(result), [](float value) { return eve::Value(value); });
1563 });
1564 table.addFunc("sampleTerrainHeightmapNormalized",
1565 [vm = table.getHandle()](const Heightmap* source, float x, float z) {
1567 : Result<float>::failure(Diagnostic::error(
1568 DiagnosticCode::InvalidArgument, "terrain: heightmap required"));
1569 return eve::script::projectResult(vm, std::move(result),
1570 [](float value) { return eve::Value(value); });
1571 });
1572 auto terraceRemoval = table.addClass("TerrainTerraceRemovalSettings",
1573 ssq::Class::Ctor<TerrainTerraceRemovalSettings()>());
1574 terraceRemoval.addVar("perlinScale", &TerrainTerraceRemovalSettings::perlinScale);
1575 terraceRemoval.addVar("perlinStrength", &TerrainTerraceRemovalSettings::perlinStrength);
1576 terraceRemoval.addVar("slopeTerraceThreshold", &TerrainTerraceRemovalSettings::slopeTerraceThreshold);
1577 terraceRemoval.addVar("flatThreshold", &TerrainTerraceRemovalSettings::flatThreshold);
1578 terraceRemoval.addVar("verticalGradientThreshold", &TerrainTerraceRemovalSettings::verticalGradientThreshold);
1579 terraceRemoval.addVar("minimumTerraceThreshold", &TerrainTerraceRemovalSettings::minimumTerraceThreshold);
1580 terraceRemoval.addVar("maximumTerraceThreshold", &TerrainTerraceRemovalSettings::maximumTerraceThreshold);
1581 terraceRemoval.addVar("excludeRed", &TerrainTerraceRemovalSettings::excludeRed);
1582 terraceRemoval.addVar("excludeBlack", &TerrainTerraceRemovalSettings::excludeBlack);
1583 terraceRemoval.addVar("terrainWorkflow", &TerrainTerraceRemovalSettings::terrainWorkflow);
1584 terraceRemoval.addVar("noiseSeed", &TerrainTerraceRemovalSettings::noiseSeed);
1585 table.addFunc("analyzeTerrainTerraces", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1586 const TerrainTerraceRemovalSettings* settings) {
1587 auto result = target && source && settings ? analyzeTerrainTerraces(*target, *source, *settings) : missingRaster();
1588 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1589 });
1590 table.addFunc("removeTerrainTerraces", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1591 const Heightmap* classification,
1592 const TerrainTerraceRemovalSettings* settings) {
1593 auto result = target && source && classification && settings
1594 ? removeTerrainTerraces(*target, *source, *classification, *settings)
1595 : missingRaster();
1596 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1597 });
1598 auto sedimentSettings = table.addClass("TerrainSedimentSettings", ssq::Class::Ctor<TerrainSedimentSettings()>());
1599 sedimentSettings.addVar("effect", &TerrainSedimentSettings::effect);
1600 sedimentSettings.addVar("depositRate", &TerrainSedimentSettings::depositRate);
1601 sedimentSettings.addVar("bankDeposit", &TerrainSedimentSettings::bankDeposit);
1602 sedimentSettings.addVar("bedDeposit", &TerrainSedimentSettings::bedDeposit);
1603 auto water = table.addClass("TerrainWaterField", ssq::Class::Ctor<TerrainWaterField()>());
1604 water.addFunc(
1605 "exportChannel", [vm = table.getHandle()](const TerrainWaterField* field, Heightmap* target, int channel) {
1606 auto result = field && target ? field->exportChannel(*target, static_cast<TerrainWaterChannel>(channel))
1607 : missingRaster();
1608 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1609 });
1610 water.addFunc("advanceHydraulic", [vm = table.getHandle()](
1611 TerrainWaterField* field, Heightmap* heights, Heightmap* sediment,
1612 const TerrainWaterSettings* settings, const TerrainSedimentSettings* reaction,
1613 const TerrainThermalSettings* thermal, int iterations) {
1614 auto result = field && heights && sediment && settings && reaction && thermal
1615 ? field->advanceHydraulic(*heights, *sediment, *settings, *reaction, *thermal, iterations)
1616 : missingRaster();
1617 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1618 });
1619 water.addFunc("getWidth", [](const TerrainWaterField* field) { return field ? field->getWidth() : 0; });
1620 water.addFunc("getHeight", [](const TerrainWaterField* field) { return field ? field->getHeight() : 0; });
1621 water.addFunc("reset", [vm = table.getHandle()](TerrainWaterField* field, int width, int height, float depth) {
1622 auto result = field ? field->reset(width, height, depth) : missingRaster();
1623 return eve::script::projectResult(vm, std::move(result), [](int count) { return eve::Value(count); });
1624 });
1625 water.addFunc("advance", [vm = table.getHandle()](TerrainWaterField* field, const Heightmap* terrain,
1626 const TerrainWaterSettings* settings) {
1627 auto result = field && terrain && settings ? field->advance(*terrain, *settings) : missingRaster();
1628 return eve::script::projectResult(vm, std::move(result), [](int count) { return eve::Value(count); });
1629 });
1630 water.addFunc("sample", [vm = table.getHandle()](const TerrainWaterField* field, int x, int z) {
1631 auto result = field ? field->sample(x, z)
1633 DiagnosticCode::InvalidArgument, "terrain.water.sample: missing field"));
1634 return eve::script::projectResult(vm, std::move(result), [](const TerrainWaterSample& cell) {
1635 return eve::Value(eve::Value::Object{{"depth", eve::Value(cell.depth)},
1636 {"velocityX", eve::Value(cell.velocityX)},
1637 {"velocityZ", eve::Value(cell.velocityZ)},
1638 {"fluxRight", eve::Value(cell.fluxRight)},
1639 {"fluxLeft", eve::Value(cell.fluxLeft)},
1640 {"fluxBottom", eve::Value(cell.fluxBottom)},
1641 {"fluxTop", eve::Value(cell.fluxTop)}});
1642 });
1643 });
1644
1645 auto heightmap = table.addClass<Heightmap>(
1646 "ProcgenHeightmap", std::function<Heightmap*()>([]() -> Heightmap* { return nullptr; }), true);
1647 heightmap.addFunc("resize", &Heightmap::resize);
1648 auto imageMask = table.addClass("TerrainImageMaskSettings", ssq::Class::Ctor<TerrainImageMaskSettings()>());
1649 imageMask.addVar("offsetX", &TerrainImageMaskSettings::offsetX);
1650 imageMask.addVar("offsetZ", &TerrainImageMaskSettings::offsetZ);
1651 imageMask.addVar("scaleX", &TerrainImageMaskSettings::scaleX);
1652 imageMask.addVar("scaleZ", &TerrainImageMaskSettings::scaleZ);
1653 imageMask.addVar("rotation", &TerrainImageMaskSettings::rotation);
1654 imageMask.addVar("red", &TerrainImageMaskSettings::red);
1655 imageMask.addVar("green", &TerrainImageMaskSettings::green);
1656 imageMask.addVar("blue", &TerrainImageMaskSettings::blue);
1657 imageMask.addVar("accuracy", &TerrainImageMaskSettings::accuracy);
1658 imageMask.addVar("tiling", &TerrainImageMaskSettings::tiling);
1659 auto collisionMask = table.addClass("TerrainCollisionMaskStack", ssq::Class::Ctor<TerrainCollisionMaskStack()>());
1660 collisionMask.addFunc("addLayer", [vm = table.getHandle()](TerrainCollisionMaskStack* self,
1661 const Heightmap* mask, int type, bool active,
1662 bool invert) {
1663 auto result = mask ? self->addLayer(*mask, static_cast<TerrainCollisionMaskType>(type), active, invert)
1664 : missingRaster();
1665 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1666 });
1667 collisionMask.addFunc("clear", &TerrainCollisionMaskStack::clear);
1668 collisionMask.addFunc("getLayerCount", [](const TerrainCollisionMaskStack* self) { return self->getLayerCount(); });
1669 collisionMask.addFunc("apply", [vm = table.getHandle()](const TerrainCollisionMaskStack* self,
1670 Heightmap* target, const Heightmap* input,
1671 const Heightmap* curve, int mode) {
1672 auto result = target && input && curve
1673 ? self->apply(*target, *input, *curve, static_cast<TerrainMaskBlend>(mode))
1674 : missingRaster();
1675 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1676 });
1677 auto polygonMask = table.addClass("TerrainPolygonMask", ssq::Class::Ctor<TerrainPolygonMask()>());
1678 polygonMask.addFunc("addNode", [vm = table.getHandle()](TerrainPolygonMask* self, float x, float z, float radius,
1679 float strength) {
1680 return eve::script::projectResult(vm, self->addNode(x, z, radius, strength),
1681 [](int n) { return eve::Value(n); });
1682 });
1683 polygonMask.addFunc("clear", &TerrainPolygonMask::clear);
1684 polygonMask.addFunc("getNodeCount", [](const TerrainPolygonMask* self) { return self->getNodeCount(); });
1685 polygonMask.addFunc("rasterize", [vm = table.getHandle()](const TerrainPolygonMask* self, Heightmap* target,
1686 const Heightmap* brush, float originX, float originZ,
1687 float spacingX, float spacingZ, int type) {
1688 TerrainSampleGrid grid;
1689 if (target) {
1690 grid = {originX, originZ, spacingX, spacingZ, target->getWidth(), target->getHeight()};
1691 }
1692 auto result = target && brush
1693 ? self->rasterize(*target, *brush, grid, static_cast<TerrainPolygonMaskType>(type))
1694 : missingRaster();
1695 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1696 });
1697 auto bakedMasks = table.addClass("TerrainBakedMaskCache", ssq::Class::Ctor<TerrainBakedMaskCache()>());
1698 bakedMasks.addFunc("store", [vm = table.getHandle()](TerrainBakedMaskCache* self, const std::string& terrainId,
1699 const std::string& maskGuid, const Heightmap* raster) {
1700 auto result = raster ? self->store(terrainId, maskGuid, *raster) : missingRaster();
1701 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1702 });
1703 bakedMasks.addFunc("markDirty", [vm = table.getHandle()](TerrainBakedMaskCache* self,
1704 const std::string& maskGuid) {
1705 return eve::script::projectResult(vm, self->markDirty(maskGuid), [](int n) { return eve::Value(n); });
1706 });
1707 bakedMasks.addFunc("erase", [vm = table.getHandle()](TerrainBakedMaskCache* self,
1708 const std::string& terrainId,
1709 const std::string& maskGuid) {
1710 return eve::script::projectResult(vm, self->erase(terrainId, maskGuid),
1711 [](int n) { return eve::Value(n); });
1712 });
1713 bakedMasks.addFunc("clear", &TerrainBakedMaskCache::clear);
1714 bakedMasks.addFunc("getEntryCount", [](const TerrainBakedMaskCache* self) { return self->getEntryCount(); });
1715 bakedMasks.addFunc("copyMask", [vm = table.getHandle()](const TerrainBakedMaskCache* self,
1716 const std::string& terrainId,
1717 const std::string& maskGuid, Heightmap* output) {
1718 auto result = output ? self->copyMask(terrainId, maskGuid, *output) : missingRaster();
1719 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1720 });
1721 heightmap.addFunc("generateImageMask",
1722 [vm = table.getHandle()](Heightmap* target, const Heightmap* input, const Heightmap* red,
1723 const Heightmap* green, const Heightmap* blue, const Heightmap* alpha,
1724 const Heightmap* curve, const TerrainImageMaskSettings* settings,
1725 int filter, int mode) {
1726 auto result = [&]() -> Result<int> {
1727 if (target && input && red && green && blue && alpha && curve && settings) {
1728 auto copy = *settings;
1729 copy.filter = static_cast<TerrainImageFilter>(filter);
1730 return generateTerrainImageMask(*target, *input, *red, *green, *blue, *alpha, *curve,
1731 copy, static_cast<TerrainMaskBlend>(mode));
1732 }
1733 return missingRaster();
1734 }();
1735 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1736 });
1737 heightmap.addFunc("applyGlobalSpawnerMask",
1738 [vm = table.getHandle()](Heightmap* target, const Heightmap* input, const Heightmap* source,
1739 const Heightmap* curve, const TerrainImageMaskSettings* settings,
1740 int mode) {
1741 auto result = target && input && source && curve && settings
1743 *settings,
1744 static_cast<TerrainMaskBlend>(mode))
1745 : missingRaster();
1746 return eve::script::projectResult(vm, std::move(result),
1747 [](int n) { return eve::Value(n); });
1748 });
1749 auto noiseMask = table.addClass("TerrainNoiseMaskSettings", ssq::Class::Ctor<TerrainNoiseMaskSettings()>());
1750 noiseMask.addVar("translationX", &TerrainNoiseMaskSettings::translationX);
1751 noiseMask.addVar("translationZ", &TerrainNoiseMaskSettings::translationZ);
1752 noiseMask.addVar("scaleX", &TerrainNoiseMaskSettings::scaleX);
1753 noiseMask.addVar("scaleZ", &TerrainNoiseMaskSettings::scaleZ);
1754 noiseMask.addVar("rotation", &TerrainNoiseMaskSettings::rotation);
1755 noiseMask.addVar("octaves", &TerrainNoiseMaskSettings::octaves);
1756 noiseMask.addVar("amplitude", &TerrainNoiseMaskSettings::amplitude);
1757 noiseMask.addVar("frequency", &TerrainNoiseMaskSettings::frequency);
1758 noiseMask.addVar("persistence", &TerrainNoiseMaskSettings::persistence);
1759 noiseMask.addVar("lacunarity", &TerrainNoiseMaskSettings::lacunarity);
1760 noiseMask.addVar("warpIterations", &TerrainNoiseMaskSettings::warpIterations);
1761 noiseMask.addVar("warpStrength", &TerrainNoiseMaskSettings::warpStrength);
1762 noiseMask.addVar("warpOffsetX", &TerrainNoiseMaskSettings::warpOffsetX);
1763 noiseMask.addVar("warpOffsetZ", &TerrainNoiseMaskSettings::warpOffsetZ);
1764 noiseMask.addVar("seed", &TerrainNoiseMaskSettings::seed);
1765 heightmap.addFunc("generateNoiseMask",
1766 [vm = table.getHandle()](Heightmap* target, const Heightmap* input, const Heightmap* curve,
1767 const TerrainNoiseMaskSettings* settings, int type, int mode) {
1768 auto result = [&]() -> Result<int> {
1769 if (!target || !input || !curve || !settings) return missingRaster();
1770 auto copy = *settings;
1771 copy.type = static_cast<TerrainNoiseType>(type);
1772 return generateTerrainNoiseMask(*target, *input, *curve, copy,
1773 static_cast<TerrainMaskBlend>(mode));
1774 }();
1775 return eve::script::projectResult(vm, std::move(result),
1776 [](int n) { return eve::Value(n); });
1777 });
1778
1779 auto concavity = table.addClass("TerrainConcavitySettings", ssq::Class::Ctor<TerrainConcavitySettings()>());
1780 concavity.addVar("featureSize", &TerrainConcavitySettings::featureSize);
1781 concavity.addVar("concavity", &TerrainConcavitySettings::concavity);
1782 heightmap.addFunc(
1783 "generateConcavityMask",
1784 [vm = table.getHandle()](Heightmap* target, const Heightmap* input, const Heightmap* heights,
1785 const Heightmap* curve, const TerrainConcavitySettings* settings, int mode) {
1786 auto result = target && input && heights && curve && settings
1788 static_cast<TerrainMaskBlend>(mode))
1789 : missingRaster();
1790 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1791 });
1792
1793 auto curvature = table.addClass("TerrainCurvatureSettings", ssq::Class::Ctor<TerrainCurvatureSettings()>());
1794 curvature.addVar("radius", &TerrainCurvatureSettings::radius);
1795 curvature.addVar("worldUnits", &TerrainCurvatureSettings::worldUnits);
1796 curvature.addVar("intensity", &TerrainCurvatureSettings::intensity);
1797 curvature.addVar("steps", &TerrainCurvatureSettings::steps);
1798 curvature.addVar("directions", &TerrainCurvatureSettings::directions);
1799 heightmap.addFunc(
1800 "generateCurvatureMask",
1801 [vm = table.getHandle()](Heightmap* target, const Heightmap* input, const Heightmap* heights,
1802 const Heightmap* curve, const TerrainCurvatureSettings* settings, int mode) {
1803 auto result = target && input && heights && curve && settings
1805 static_cast<TerrainMaskBlend>(mode))
1806 : missingRaster();
1807 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1808 });
1809
1810 heightmap.addFunc("growShrinkMask", [vm = table.getHandle()](Heightmap* target, const Heightmap* source,
1811 const Heightmap* curve, float distance) {
1812 auto result =
1813 target && source && curve ? growShrinkTerrainMask(*target, *source, *curve, distance) : missingRaster();
1814 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1815 });
1816
1817 heightmap.addFunc(
1818 "applyStrength", [vm = table.getHandle()](Heightmap* target, const Heightmap* source, const Heightmap* curve,
1819 int mode, float strength, bool invert) {
1820 auto result = target && source && curve
1821 ? applyTerrainStrength(*target, *source, *curve, static_cast<TerrainStrengthMode>(mode),
1822 strength, invert)
1823 : missingRaster();
1824 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1825 });
1826 heightmap.addFunc("generateErosionMask",
1827 [vm = table.getHandle()](Heightmap* target, const Heightmap* oldHeights, const Heightmap* erosion,
1828 const Heightmap* brush, const TerrainBrushBlendSettings* spatial,
1829 const Heightmap* curve, int mode, float strength, bool userInvert) {
1830 auto result = target && oldHeights && erosion && brush && spatial && curve
1832 *target, *oldHeights, *erosion, *brush, *spatial, *curve,
1833 static_cast<TerrainStrengthMode>(mode), strength, userInvert)
1834 : missingRaster();
1835 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1836 });
1837
1838 auto sampleGrid = table.addClass("TerrainSampleGrid", ssq::Class::Ctor<TerrainSampleGrid()>());
1839 sampleGrid.addVar("width", &TerrainSampleGrid::width);
1840 sampleGrid.addVar("height", &TerrainSampleGrid::height);
1841 sampleGrid.addFunc("setOrigin", [](TerrainSampleGrid* grid, float x, float z) {
1842 grid->originX = x;
1843 grid->originZ = z;
1844 });
1845 sampleGrid.addFunc("setSpacing", [](TerrainSampleGrid* grid, float x, float z) {
1846 grid->spacingX = x;
1847 grid->spacingZ = z;
1848 });
1849 auto brushBlend = table.addClass("TerrainBrushBlendSettings", ssq::Class::Ctor<TerrainBrushBlendSettings()>());
1850 brushBlend.addFunc(
1851 "configureWorld", [vm = table.getHandle()](TerrainBrushBlendSettings* target, const TerrainStampSettings* world,
1852 int width, int height, const TerrainSampleGrid* grid) {
1853 auto result = target && world && grid ? configureTerrainBrushWorld(*target, *world, width, height, *grid)
1854 : missingRaster();
1855 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1856 });
1857
1858 brushBlend.addVar("heightXX", &TerrainBrushBlendSettings::heightXX);
1859 brushBlend.addVar("heightXZ", &TerrainBrushBlendSettings::heightXZ);
1860 brushBlend.addVar("heightZX", &TerrainBrushBlendSettings::heightZX);
1861 brushBlend.addVar("heightZZ", &TerrainBrushBlendSettings::heightZZ);
1862 brushBlend.addVar("heightOffsetX", &TerrainBrushBlendSettings::heightOffsetX);
1863 brushBlend.addVar("heightOffsetZ", &TerrainBrushBlendSettings::heightOffsetZ);
1864 brushBlend.addVar("brushXX", &TerrainBrushBlendSettings::brushXX);
1865 brushBlend.addVar("brushXZ", &TerrainBrushBlendSettings::brushXZ);
1866 brushBlend.addVar("brushZX", &TerrainBrushBlendSettings::brushZX);
1867 brushBlend.addVar("brushZZ", &TerrainBrushBlendSettings::brushZZ);
1868 brushBlend.addVar("brushOffsetX", &TerrainBrushBlendSettings::brushOffsetX);
1869 brushBlend.addVar("brushOffsetZ", &TerrainBrushBlendSettings::brushOffsetZ);
1870 brushBlend.addVar("strength", &TerrainBrushBlendSettings::strength);
1871 heightmap.addFunc("blendBrush", [vm = table.getHandle()](Heightmap* target, const Heightmap* oldHeights,
1872 const Heightmap* newHeights, const Heightmap* brush,
1873 const TerrainBrushBlendSettings* settings) {
1874 auto result = target && oldHeights && newHeights && brush && settings
1875 ? blendTerrainBrush(*target, *oldHeights, *newHeights, *brush, *settings)
1876 : missingRaster();
1877 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1878 });
1879
1880 heightmap.addFunc(
1881 "applySediment", [vm = table.getHandle()](Heightmap* heights, Heightmap* sediment, const Heightmap* velocityX,
1882 const Heightmap* velocityZ, const TerrainWaterSettings* water,
1883 const TerrainSedimentSettings* settings) {
1884 auto result = heights && sediment && velocityX && velocityZ && water && settings
1885 ? applyTerrainSediment(*heights, *sediment, *velocityX, *velocityZ, *water, *settings)
1886 : missingRaster();
1887 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1888 });
1889 heightmap.addFunc("applyThermal", [vm = table.getHandle()](Heightmap* heights, Heightmap* sediment,
1890 const TerrainThermalSettings* settings) {
1891 auto result =
1892 heights && sediment && settings ? applyTerrainThermal(*heights, *sediment, *settings) : missingRaster();
1893 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1894 });
1895 heightmap.addFunc(
1896 "applyHeightCurve", [vm = table.getHandle()](Heightmap* target, const Heightmap* mask, const Heightmap* curve,
1897 float minimum, float maximum) {
1899 : missingRaster();
1900 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1901 });
1902 heightmap.addFunc("applyHeightMix", [vm = table.getHandle()](Heightmap* target, const Heightmap* local,
1903 const Heightmap* global,
1904 const TerrainHeightMixSettings* settings) {
1906 : missingRaster();
1907 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1908 });
1909 heightmap.addFunc("applySmooth", [vm = table.getHandle()](Heightmap* target, const Heightmap* mask,
1910 const TerrainSmoothSettings* settings) {
1911 auto result = target && mask && settings ? applyTerrainSmooth(*target, *mask, *settings) : missingRaster();
1912 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1913 });
1914 heightmap.addFunc("applyRidges", [vm = table.getHandle()](Heightmap* target, const Heightmap* mask,
1915 const TerrainRidgeSettings* settings) {
1916 auto result = target && mask && settings ? applyTerrainRidges(*target, *mask, *settings) : missingRaster();
1917 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1918 });
1919 heightmap.addFunc("applyTerrace", [vm = table.getHandle()](Heightmap* target, const Heightmap* mask,
1920 const TerrainTerraceSettings* settings) {
1921 auto result = target && mask && settings ? applyTerrainTerrace(*target, *mask, *settings) : missingRaster();
1922 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1923 });
1924 heightmap.addFunc("applyPower", [vm = table.getHandle()](Heightmap* target, const Heightmap* mask, float power) {
1925 auto result = target && mask ? applyTerrainPower(*target, *mask, power) : missingRaster();
1926 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1927 });
1928 heightmap.addFunc("getWidth", &Heightmap::getWidth);
1929 heightmap.addFunc("getHeight", &Heightmap::getHeight);
1930 heightmap.addFunc("setHeight", &Heightmap::setHeight);
1931 heightmap.addFunc("height", &Heightmap::height);
1932 heightmap.addFunc("sampleBilinear", &Heightmap::sampleBilinear);
1933 heightmap.addFunc("sampleBilinearSeamless", &Heightmap::sampleBilinearSeamless);
1934 heightmap.addFunc("hasData", [vm = table.getHandle()](const Heightmap* source) {
1935 auto result = source ? terrainHeightmapHasData(*source)
1936 : Result<bool>::failure(
1937 Diagnostic::error(DiagnosticCode::InvalidArgument, "terrain: heightmap required"));
1938 return eve::script::projectResult(vm, std::move(result), [](bool value) { return eve::Value(value); });
1939 });
1940 heightmap.addFunc("isPowerOfTwo", [vm = table.getHandle()](const Heightmap* source) {
1942 : Result<bool>::failure(
1943 Diagnostic::error(DiagnosticCode::InvalidArgument, "terrain: heightmap required"));
1944 return eve::script::projectResult(vm, std::move(result), [](bool value) { return eve::Value(value); });
1945 });
1946 heightmap.addFunc("blendMask", [vm = table.getHandle()](Heightmap* target, const Heightmap* source, int mode,
1947 float strength, bool invert) {
1948 auto result = target && source
1949 ? blendTerrainMask(*target, *source, static_cast<TerrainMaskBlend>(mode), strength, invert)
1950 : missingRaster();
1951 return eve::script::projectResult(vm, std::move(result), [](int changed) { return eve::Value(changed); });
1952 });
1953 heightmap.addFunc("applyStamp", [vm = table.getHandle()](Heightmap* target, const Heightmap* stamp,
1954 const TerrainStampSettings* config, int operation,
1955 const Heightmap* local, const Heightmap* global) {
1956 if (!target || !stamp || !config || !local || !global)
1957 return eve::script::projectResult(vm, missingRaster(), [](int changed) { return eve::Value(changed); });
1958 auto copy = *config;
1959 copy.operation = static_cast<TerrainStampOperation>(operation);
1961 [](int changed) { return eve::Value(changed); });
1962 });
1963 heightmap.addFunc(
1964 "transformMask", [vm = table.getHandle()](Heightmap* target, const Heightmap* source, const Heightmap* curve) {
1965 auto result = target && source && curve ? transformTerrainMask(*target, *source, *curve) : missingRaster();
1966 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1967 });
1968 heightmap.addFunc("smoothMask", [vm = table.getHandle()](Heightmap* target, const Heightmap* input,
1969 float verticality, float blurRadius) {
1970 auto result = target && input ? smoothTerrainMask(*target, *input, verticality, blurRadius) : missingRaster();
1971 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
1972 });
1973 auto legacyHydraulic = table.addClass("TerrainLegacyHydraulicSettings",
1974 ssq::Class::Ctor<TerrainLegacyHydraulicSettings()>());
1975 legacyHydraulic.addVar("iterations", &TerrainLegacyHydraulicSettings::iterations);
1976 legacyHydraulic.addVar("rainFrequency", &TerrainLegacyHydraulicSettings::rainFrequency);
1977 legacyHydraulic.addVar("sedimentDissolveRate", &TerrainLegacyHydraulicSettings::sedimentDissolveRate);
1978 heightmap.addFunc("applyLegacyHydraulic",
1979 [vm = table.getHandle()](Heightmap* heights, Heightmap* sediment, const Heightmap* hardness,
1980 const Heightmap* rain,
1981 const TerrainLegacyHydraulicSettings* settings) {
1982 auto result = heights && sediment && hardness && rain && settings
1983 ? applyTerrainLegacyHydraulic(*heights, *sediment, *hardness, *rain,
1984 *settings)
1985 : missingRaster();
1986 return eve::script::projectResult(vm, std::move(result),
1987 [](int n) { return eve::Value(n); });
1988 });
1989 auto distributedErosion = table.addClass("TerrainLegacyDistributedErosionSettings",
1990 ssq::Class::Ctor<TerrainLegacyDistributedErosionSettings()>());
1991 distributedErosion.addVar("minimumThreshold", &TerrainLegacyDistributedErosionSettings::minimumThreshold);
1992 distributedErosion.addVar("maximumThreshold", &TerrainLegacyDistributedErosionSettings::maximumThreshold);
1993 distributedErosion.addVar("iterations", &TerrainLegacyDistributedErosionSettings::iterations);
1994 heightmap.addFunc("applyLegacyDistributedErosion",
1995 [vm = table.getHandle()](Heightmap* target,
1996 const TerrainLegacyDistributedErosionSettings* settings) {
1998 : missingRaster();
1999 return eve::script::projectResult(vm, std::move(result),
2000 [](int n) { return eve::Value(n); });
2001 });
2002 auto steepestErosion = table.addClass("TerrainLegacySteepestErosionSettings",
2003 ssq::Class::Ctor<TerrainLegacySteepestErosionSettings()>());
2004 steepestErosion.addVar("iterations", &TerrainLegacySteepestErosionSettings::iterations);
2005 steepestErosion.addVar("talusMinimum", &TerrainLegacySteepestErosionSettings::talusMinimum);
2006 steepestErosion.addVar("talusMaximum", &TerrainLegacySteepestErosionSettings::talusMaximum);
2007 heightmap.addFunc("applyLegacySteepestErosion",
2008 [vm = table.getHandle()](Heightmap* target, const Heightmap* hardness,
2009 const TerrainLegacySteepestErosionSettings* settings) {
2010 auto result = target && hardness && settings
2012 : missingRaster();
2013 return eve::script::projectResult(vm, std::move(result),
2014 [](int n) { return eve::Value(n); });
2015 });
2016 heightmap.addFunc(
2017 "rangeMask", [vm = table.getHandle()](Heightmap* target, const Heightmap* source, float minimum, float maximum,
2018 const Heightmap* curve, const Heightmap* strength) {
2019 auto result = target && source && curve && strength
2021 : missingRaster();
2022 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
2023 });
2024 heightmap.addFunc("applyContrast", [vm = table.getHandle()](Heightmap* target, const Heightmap* mask,
2025 float strength, float size) {
2026 auto result = target && mask ? applyTerrainContrast(*target, *mask, strength, size) : missingRaster();
2027 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
2028 });
2029 heightmap.addFunc("deriveSlope", [vm = table.getHandle()](Heightmap* target, const Heightmap* heights, float dx,
2030 float dz, float scale) {
2031 auto result = target && heights ? deriveTerrainSlope(*target, *heights, dx, dz, scale) : missingRaster();
2032 return eve::script::projectResult(vm, std::move(result), [](int n) { return eve::Value(n); });
2033 });
2034 heightmap.addFunc(
2035 "distanceMask", [vm = table.getHandle()](Heightmap* target, const TerrainDistanceMaskSettings* settings,
2036 int axis, const Heightmap* curve, const Heightmap* strength) {
2037 if (!target || !settings || !curve || !strength)
2038 return eve::script::projectResult(vm, missingRaster(), [](int n) { return eve::Value(n); });
2039 auto copy = *settings;
2040 copy.axis = static_cast<TerrainDistanceAxis>(axis);
2042 [](int n) { return eve::Value(n); });
2043 });
2044}
2045} // namespace eve::procgen
LogicalId target
ActionParameterOperation operation
double value
bool & active
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::map< std::string, std::vector< Key >, std::less<> > channels
std::string output
std::string terrain
eve::action::ActionSpatialBinding spatial
const std::string & s
int mask
float contrast
HSQUIRRELVM vm
Definition ECS.cpp:20
std::map< std::string, Var > values
scene::NodeDesc desc
EvpackChunkInput input
Definition Evpack.cpp:170
float maximum[3]
float minimum[3]
wgpu::PopErrorScopeStatus status
glm::vec3 n
Definition Grass.cpp:63
std::uint32_t height
std::uint32_t width
std::string local
Range range
std::array< float, 3 > scale
std::string name
float distance
std::string error
Definition Package.cpp:60
TileLayer * layer
World3D * world
float radius
std::string id
Definition PlayHost.cpp:108
std::uint32_t seed
Definition PointSet.cpp:807
std::shared_ptr< const std::vector< glm::vec2 > > points
int detail
float power
Definition RockMesh.cpp:23
std::string filter
float dz
float dx
std::uint32_t count
The single Squirrel projection for common Result, Status and Value.
Cell cell
std::optional< InteractionSession > session
Definition Tactics.cpp:39
TerrainWaterField water
Heightmap curve
TerrainThermalSettings settings
Heightmap stamp
TerrainThermalSettings thermal
Heightmap global
Heightmap sediment
double spacingZ
double spacingX
int iterations
Definition TreeMesh.cpp:311
float size
Definition TreeMesh.cpp:156
uint32_t index
const UnitySourceAsset & source
std::uint32_t depth
glm::vec3 point
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
The canonical owning dynamic value used by data-facing protocols.
Definition Value.h:31
std::map< std::string, Value > Object
Definition Value.h:34
void resize(int width, int height)
Resize.
Definition Heightmap.cpp:10
Caller-owned, deterministic progress state corresponding to Pcg SpawnProgressBar. @thread Spawning th...
void beginScan()
Begin a candidate hierarchy scan without changing the published cache.
void cancelScan()
Discard a candidate scan.
eve::Diagnostic Diagnostic
eve::Result< T > Result
const EditorValue * field(const EditorValue &value, const char *name)
TerrainStrengthMode
StrengthTransform pass order; source pass 0 named Multiply actually replaces with the curve value.
Definition TerrainMask.h:82
Result< int > resetTerrainHeightmap(Heightmap &target)
Reset a heightmap to Pcg's empty zero-by-zero state.
void exposeHeightmap(ssq::Table &table)
Register heightmap and stamp value bindings; VM-thread only, retains no table reference.
Result< int > removeTerrainObjectPoints(PointSet &output, const PointSet &input, const Heightmap &fitness, const TerrainObjectPlacementSettings &s, float removalStrength)
Remove matching prototype points wherever fitness is strictly above removalStrength.
Result< int > generateTerrainVelocityFlowMap(Heightmap &target, const Heightmap &source, int iterations)
Generate Pcg HeightMap.FlowMap's normalized four-direction velocity magnitude.
TerrainHeightmapNeighborhood
Pcg HeightMap neighborhood mutation modes.
Result< int > quantizeTerrainHeightmapTerraces(Heightmap &target, const Heightmap &source, const Heightmap &startHeights, const Heightmap &curves)
Apply Pcg's curve-driven Quantize overload using one sampled curve per raster row.
Result< int > applyTerrainTerrace(Heightmap &target, const Heightmap &mask, const TerrainTerraceSettings &settings)
Terrace scalar heights using nearest-even rounding and the shader's one-sided bevel.
Result< int > generateTerrainHeightmapSlope(Heightmap &target, const Heightmap &source)
Generate Pcg HeightMap.SlopeMap's normalized gradient magnitude.
Result< int > generateTerrainDistanceMask(Heightmap &target, const TerrainDistanceMaskSettings &s, const Heightmap &filterCurve, const Heightmap &strengthCurve)
Generate a transformed distance mask using circle, X, Z or rounded-square coordinates.
Result< int > removeTerrainTreePoints(PointSet &output, const PointSet &input, const Heightmap &fitness, const TerrainTreePlacementSettings &s)
Remove matching tree points wherever the current fitness is strictly above the threshold.
EVENGINE_API_DOMAINS Result< int > applyTerrainLegacyHydraulic(Heightmap &heights, Heightmap &sediment, const Heightmap &hardness, const Heightmap &rain, const TerrainLegacyHydraulicSettings &settings)
Apply Pcg HeightMap.ErodeHydraulic's rain, four-way water and sediment loop atomically.
Result< int > generateTerrainImageMask(Heightmap &target, const Heightmap &input, const Heightmap &red, const Heightmap &green, const Heightmap &blue, const Heightmap &alpha, const Heightmap &curve, const TerrainImageMaskSettings &s, TerrainMaskBlend mode)
Generate the reference image-mask filter from borrowed RGBA scalar planes.
Result< int > transformTerrainMask(Heightmap &target, const Heightmap &source, const Heightmap &curve)
Transform scalar input through a clamped bilinear one-row curve texture.
Result< int > generateTerrainRangeMask(Heightmap &target, const Heightmap &source, float minimum, float maximum, const Heightmap &filterCurve, const Heightmap &strengthCurve)
Generate height/range fitness with smoothstep followed by filter and strength curves.
Result< int > generateTerrainNoiseMask(Heightmap &target, const Heightmap &input, const Heightmap &curve, const TerrainNoiseMaskSettings &s, TerrainMaskBlend mode)
Generate a transformed Pcg-style fBm noise source, curve it, then combine it with an input mask.
PcgSpawnProgressStatus
Observable lifecycle of a Pcg spawning progress operation.
Result< int > setTerrainHeightmapRow(Heightmap &target, int rowX, const Heightmap &values)
Set Pcg's fixed-X row from a one-dimensional strip.
TerrainProbeOperationMode
Mutation performed by a multi-terrain probe rule.
Result< int > analyzeTerrainTerraces(Heightmap &target, const Heightmap &source, const TerrainTerraceRemovalSettings &s)
Classify a heightmap into Pcg's black/red/green/blue important-detail categories.
Result< int > copyTerrainHeightmapClamped(Heightmap &target, const Heightmap &source, float minValue, float maxValue)
Copy a Pcg heightmap with inclusive output clamping and normalized resampling.
Result< int > generateTerrainCurvatureMask(Heightmap &target, const Heightmap &input, const Heightmap &heights, const Heightmap &curve, const TerrainCurvatureSettings &s, TerrainMaskBlend mode)
Radially blur heights, derive source curvature, transform its curve and combine with an input mask.
Result< int > exportTerrainProbePoints(PointSet &output, const Heightmap &fitness, const Heightmap &heights, const TerrainProbePlacementSettings &s)
Export Pcg ReflectionProbe or LightProbe placements into an owned attributed PointSet.
Result< int > applyTerrainContrast(Heightmap &target, const Heightmap &mask, float strength, float featureSize)
Apply the nine-tap Pcg contrast equation to native scalar heights.
Result< int > applyTerrainGlobalSpawnerMask(Heightmap &target, const Heightmap &input, const Heightmap &source, const Heightmap &curve, const TerrainImageMaskSettings &settings, TerrainMaskBlend mode)
Apply a scalar GlobalSpawnerMaskStack output through Pcg's image-mask transform, curve and blend pass...
Result< int > rescaleTerrainTreePoints(PointSet &output, const PointSet &input, const TerrainTreeRescaleSettings &s)
Atomically refresh scale, bounds and bend metadata for one tree asset while preserving identity/trans...
Result< int > configureTerrainBrushWorld(TerrainBrushBlendSettings &target, const TerrainStampSettings &w, int contextWidth, int contextHeight, const TerrainSampleGrid &h)
Configure paint-context UV matrices from world sample centers and a rotated stamp footprint.
Result< int > applyTerrainHeightmapRasterArithmetic(Heightmap &target, const Heightmap &source, const Heightmap &operand, TerrainHeightmapArithmetic operation, bool clampResult, float minValue, float maxValue)
Apply a raster Pcg HeightMap arithmetic operation, resampling a differently sized operand.
TerrainHeightmapCurvature
Pcg HeightMap.CurvatureMap modes in source enum order.
Result< int > flipTerrainHeightmap(Heightmap &target, const Heightmap &source)
Transpose a Pcg HeightMap exactly as HeightMap.Flip does.
Result< int > blendTerrainMask(Heightmap &target, const Heightmap &source, TerrainMaskBlend mode, float strength, bool invert)
Blend one scalar raster into an existing mask stack, in call order.
EVENGINE_API_DOMAINS Result< int > applyTerrainLegacyDistributedErosion(Heightmap &heights, const TerrainLegacyDistributedErosionSettings &settings)
Apply Pcg HeightMap.Erode's synchronous four-neighbor material redistribution.
EVENGINE_API_DOMAINS Result< int > applyTerrainLegacySteepestErosion(Heightmap &heights, const Heightmap &hardness, const TerrainLegacySteepestErosionSettings &settings)
Apply Pcg HeightMap.ErodeThermal's ordered steepest-cardinal transport with hardness.
Result< int > smoothTerrainHeightmap(Heightmap &target, const Heightmap &source, int iterations)
Apply Pcg HeightMap.Smooth's in-place four-neighbor passes.
TerrainHeightmapSlopeQuery
Pcg HeightMap point slope query variants.
TerrainProbeType
Pcg probe resource kind.
Result< int > fillTerrainHeightmap(Heightmap &target, float value)
Fill a finite Pcg heightmap with one value clamped to [0,1].
TerrainSessionRunStatus
Observable lifecycle of a caller-driven staged session replay.
Result< int > blendTerrainBrush(Heightmap &target, const Heightmap &oldHeights, const Heightmap &newHeights, const Heightmap &brush, const TerrainBrushBlendSettings &s)
Blend an erosion scalar output with old heights through transformed brush UVs.
Result< int > smoothTerrainHeightmapRadius(Heightmap &target, const Heightmap &source, int radius)
Apply Pcg HeightMap.SmoothRadius's scaled sliding-window filter, including its first-row omission.
Result< int > convolveTerrainHeightmap(Heightmap &target, const Heightmap &source, const Heightmap &kernel)
Apply Pcg HeightMap.Convolve with an odd square kernel and source-order in-place feedback.
Result< int > copyTerrainHeightmap(Heightmap &target, const Heightmap &source, TerrainHeightmapCopy mode)
Copy or conditionally merge a Pcg heightmap, resampling when dimensions differ.
TerrainMaskBlend
Ordered scalar-mask arithmetic; intermediate values are not clamped.
Definition TerrainStamp.h:9
Result< int > transformTerrainHeightmap(Heightmap &target, const Heightmap &source, TerrainHeightmapTransform transform, float parameter)
Apply Pcg Invert, Normalise, Power, or Contrast to a finite heightmap.
Result< int > setTerrainHeightmapColumn(Heightmap &target, int columnZ, const Heightmap &values)
Set Pcg's fixed-Z column from a one-dimensional strip.
TerrainTreeScaleMode
Pcg-compatible rules for deriving tree scale from placement fitness.
Result< int > smoothTerrainMask(Heightmap &target, const Heightmap &input, float verticality, float blurRadius)
Apply Pcg's two-pass Smooth ImageMask operation to a scalar mask.
Result< int > applyTerrainHeightMix(Heightmap &target, const Heightmap &local, const Heightmap &global, const TerrainHeightMixSettings &settings)
Mix centered local brush heights into terrain, then globally mask and clip.
Result< int > applyTerrainSmooth(Heightmap &target, const Heightmap &mask, const TerrainSmoothSettings &settings)
Apply Pcg's horizontal then vertical seven-pair weighted smooth passes.
TerrainPolygonMaskType
Pcg PolyMask topology: open strokes only, or closed flood fill plus strokes.
Result< int > applyTerrainPower(Heightmap &target, const Heightmap &mask, float power)
Apply the Pcg PowerOf control: lerp(height,pow(height,4-power),mask).
Result< int > paintTerrainSplatLayer(TerrainSplatmap &target, const Heightmap &paint, int targetLayer)
Replace one terrain layer with a normalized paint raster and proportionally renormalize all other lay...
TerrainNoiseType
Pcg NoiseLib families available to the native scalar mask generator.
Result< int > applyTerrainStrength(Heightmap &target, const Heightmap &source, const Heightmap &curve, TerrainStrengthMode mode, float strength, bool invert)
Apply the reference strength curve, inversion, mode and final interpolation.
Result< bool > terrainHeightmapHasData(const Heightmap &source)
Return whether a heightmap contains a valid positive-size sample array.
Result< int > deriveTerrainSlope(Heightmap &target, const Heightmap &heights, float spacingX, float spacingZ, float heightScale)
Derive the shader's slope metric 1-normal.y from world-scaled height gradients.
Result< float > sampleTerrainHeightmapSafe(const Heightmap &source, int x, int z)
Read a finite heightmap at an integer coordinate clamped to its nearest border.
Result< int > removeTerrainTerraces(Heightmap &target, const Heightmap &source, const Heightmap &classes, const TerrainTerraceRemovalSettings &s)
Apply Pcg's adaptive smoothing, gradient noise, 3x3 filter, and fixed 5x5 Gaussian blur.
TerrainHeightmapTransform
Pcg HeightMap whole-raster value transforms.
Result< int > quantizeTerrainHeightmap(Heightmap &target, const Heightmap &source, float divisor)
Quantize every sample using Pcg HeightMap.Quantize's Mathf.Round rule.
TerrainSessionAccess
Edit policy for the owned operation history and terrain.
Result< bool > terrainHeightmapIsPowerOfTwo(const Heightmap &source)
Return whether both positive heightmap dimensions are powers of two; malformed storage fails.
Result< int > generateTerrainErosionMask(Heightmap &target, const Heightmap &oldHeights, const Heightmap &erosion, const Heightmap &brush, const TerrainBrushBlendSettings &spatial, const Heightmap &curve, TerrainStrengthMode mode, float strength, bool userInvert)
Compose spatial erosion-output blending and the source's inverted strength filter atomically.
TerrainWaterChannel
Stored scalar channels; Pcg erosion masks read FluxRight or VelocityX, not vector magnitude.
TerrainHeightmapMeasure
Pcg HeightMap read-only scalar measurements.
TerrainObjectScaleMode
Pcg-compatible scale policy for one terrain object instance resource.
Result< int > applyTerrainStamp(Heightmap &target, const Heightmap &stamp, const TerrainStampSettings &s, const Heightmap &localMask, const Heightmap &globalMask)
Apply a rotated, bilinearly sampled stamp; publish only after all checks succeed.
TerrainDetailMode
Native detail-density operation corresponding to Pcg SpawnMode.
Result< double > measureTerrainHeightmap(const Heightmap &source, TerrainHeightmapMeasure measure)
Measure Pcg height range, sum, average, or scanner base level from current samples.
Result< int > applyGtsHeightBlend(TerrainSplatmap &output, const TerrainSplatmap &input, const GtsHeightBlendSet &heights, float blendFactor)
Recompute all splat weights using the GTS texture-height blending equation.
Result< int > generateTerrainConcavityMask(Heightmap &target, const Heightmap &input, const Heightmap &heights, const Heightmap &curve, const TerrainConcavitySettings &s, TerrainMaskBlend mode)
Generate source normalized-gradient concavity with border attenuation and indexed curve lookup.
PcgBiomeLoadMode
Pcg TerrainLoader activation modes retained by a biome controller.
TerrainWorldRunStatus
Observable lifecycle of a caller-driven staged world spawn.
Result< int > applyTerrainRidges(Heightmap &target, const Heightmap &mask, const TerrainRidgeSettings &settings)
Apply ordered horizontal/vertical ridge powers, neighbor mixing and per-pass clipping.
Result< int > filterTerrainHeightmapNeighborhood(Heightmap &target, const Heightmap &source, int radius, TerrainHeightmapNeighborhood mode)
Apply Pcg HeightMap.DeNoise, GrowEdges, or ShrinkEdges in source traversal order.
TerrainDistanceAxis
Distance coordinates used by the Pcg distance-mask shader.
TerrainHeightmapCopy
Pcg HeightMap.Copy conditional modes in source enum order.
EVENGINE_API_DOMAINS Result< int > applyTerrainSediment(Heightmap &heights, Heightmap &sediment, const Heightmap &velocityX, const Heightmap &velocityZ, const TerrainWaterSettings &water, const TerrainSedimentSettings &settings)
Apply the source sediment reaction and backtrace equations with atomic dual output.
TerrainTreeYOffsetMode
Height reference used when a tree does not snap directly to terrain.
TerrainStampOperation
Native height operations, in terrain height units (not Unity packed heights).
Result< float > sampleTerrainHeightmapNormalized(const Heightmap &source, float x, float z)
Read Pcg HeightMap's normalized bilinear sample using x*width and z*depth coordinates.
Result< int > lerpTerrainHeightmap(Heightmap &target, const Heightmap &source, const Heightmap &values, const Heightmap &mask)
Lerp source toward values under a mask using Pcg's clamped Mathf.Lerp semantics.
TerrainHeightmapAspect
Pcg HeightMap.Aspect modes in source enum order.
Result< int > generateTerrainWaterFlowMap(Heightmap &target, const Heightmap &source, const TerrainWaterFlowMapSettings &settings)
Generate Pcg's legacy transposed water-flow accumulation map.
Result< int > generateTerrainHeightmapAspect(Heightmap &target, const Heightmap &source, TerrainHeightmapAspect mode)
Derive Pcg HeightMap.Aspect's aspect, northerness, or easterness raster.
Result< int > exportTerrainTreePoints(PointSet &output, const Heightmap &fitness, const Heightmap &heights, const TerrainTreePlacementSettings &s)
Scan a terrain rectangle and atomically export accepted Pcg-style tree instances.
Result< int > growShrinkTerrainMask(Heightmap &target, const Heightmap &source, const Heightmap &curve, float distance)
Ordered radial Grow/Shrink followed by the reference strength curve.
Result< int > exportTerrainObjectPoints(PointSet &output, const Heightmap &fitness, const Heightmap &heights, const TerrainObjectPlacementSettings &s)
Export Pcg-style terrain game-object resources into an attributed PointSet atomically.
TerrainObjectYOffsetMode
Height reference used by one terrain object instance resource.
Result< int > applyTerrainThermal(Heightmap &heights, Heightmap &sediment, const TerrainThermalSettings &settings)
Apply the source thermal equation, publishing height and sediment together.
TerrainImageFilter
Reference image selection modes; MaximumRgb is not luminance.
Result< int > setTerrainHeightmapSafe(Heightmap &target, int x, int y, float value)
Set one sample after clamping its coordinates to the nearest border.
Result< int > alignTerrainSplatTextures(TerrainSplatmap &terrainA, TerrainSplatmap &terrainB, const TerrainTextureAlignSettings &settings)
Blend texture weights on adjacent terrain edges using Pcg's synchronized-noise equation.
Result< int > exportTerrainDetailPoints(PointSet &output, const TerrainDetailLayer &layer, const Heightmap &heights, const TerrainDetailPlacementSettings &s)
Expand integer detail counts into the existing attributed PointSet, atomically.
Result< int > applyTerrainHeightmapScalarArithmetic(Heightmap &target, const Heightmap &source, float operand, TerrainHeightmapArithmetic operation, bool clampResult, float minValue, float maxValue)
Apply a scalar Pcg HeightMap arithmetic operation with optional clamping.
TerrainObjectOperationMode
Mutation performed by a multi-terrain game-object operation.
TerrainTreeOperationMode
Pcg SetTerrainTrees operation branch. Add and Replace both append after upstream clearing policy.
TerrainHeightmapArithmetic
Pcg HeightMap pointwise arithmetic operations.
Result< int > applyTerrainHeightCurve(Heightmap &target, const Heightmap &mask, const Heightmap &curve, float minimum, float maximum)
Apply the height-transform shader's smoothstep and one-row height curve.
Result< double > measureTerrainHeightmapSlope(const Heightmap &source, float x, float y, TerrainHeightmapSlopeQuery mode)
Evaluate one of Pcg HeightMap's three point-slope formulas.
Result< int > generateTerrainHeightmapCurvature(Heightmap &target, const Heightmap &source, TerrainHeightmapCurvature mode)
Derive Pcg HeightMap.CurvatureMap's normalized differential curvature.
std::unordered_map< std::string, SkillDefinition > & table()
Definition Skill.cpp:65
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
int axis(int64_t a, size_t rank)
Axis.
WidgetDesc progress(float fraction, std::string id, std::string overlay)
Progress bar; fraction is clamped to [0,1].
Definition Widget.cpp:395
WidgetDesc grid(int columns, std::vector< WidgetDesc > children, std::string id)
Fixed-column grid; children are placed in source order.
Definition Widget.cpp:687
DiagnosticCode
Stable machine-readable diagnostic codes.
Definition Diagnostic.h:47
bool enabled
Engine-neutral description of one generated reflection or light probe.
std::uint64_t sourcePointId
float noiseSpread
Normalized frequency control for deterministic healthy/dry color patches.
float minimumWidth
Independent horizontal and vertical multipliers, applied after the uniform scale.
uint64_t densityNamespaceId
Density resource layer to export; zero selects the compatibility/default layer.
float healthyR
Linear RGBA endpoints passed to generated points for renderer-side instance tint.
std::uint64_t namespaceId
Stable resource namespace; zero addresses the compatibility/default layer.
float flowAcceleration
Signed flowRate*gravity; source default is negative.
std::uint64_t sourceNamespace
Zero clears any source; non-zero clears only points emitted by that stable namespace.