载入中...
搜索中...
未找到
PrimitiveScriptBindings.cpp
浏览该文件的文档.
2#include "graphics/Graphics.h"
6#include <simplesquirrel/simplesquirrel.hpp>
7#include <functional>
8#include <memory>
9
10namespace eve::graphics {
11namespace {
12struct ScriptPrimitive3D {
13 ScriptPrimitive3D(std::weak_ptr<PrimitiveScene> sceneValue, PrimitiveHandle handleValue)
14 : scene(std::move(sceneValue)), handle(handleValue) {}
15 ~ScriptPrimitive3D() noexcept {
16 if (auto owner = scene.lock(); owner && !owner->isStale(handle))
17 owner->remove(handle).ignore("script primitive proxy destruction");
18 }
19
20 std::weak_ptr<PrimitiveScene> scene;
21 PrimitiveHandle handle;
22};
23
24eve::Result<PrimitiveDescriptor3D> primitiveDescriptor(ScriptPrimitive3D* value) {
25 if (!value)
27 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "primitive proxy must not be null",
28 "primitive", {}, "graphics.primitive.binding"));
29 auto scene = value->scene.lock();
30 if (!scene)
32 eve::Diagnostic::error(eve::DiagnosticCode::StaleHandle, "primitive scene owner no longer exists",
33 "primitive", {}, "graphics.primitive.binding"));
34 const PrimitiveDescriptor3D* descriptor = scene->tryGet(value->handle);
35 if (!descriptor)
37 eve::Diagnostic::error(eve::DiagnosticCode::StaleHandle, "primitive handle is stale", "primitive", {},
38 "graphics.primitive.binding"));
40}
41
42template <class Mutator>
43eve::Result<PrimitiveUpdateStatus> mutatePrimitive(ScriptPrimitive3D* value, Mutator&& mutator) {
44 auto descriptor = primitiveDescriptor(value);
46 PrimitiveDescriptor3D copy = std::move(descriptor).takeValue();
47 std::invoke(std::forward<Mutator>(mutator), copy);
48 auto scene = value->scene.lock();
49 if (!scene)
51 eve::Diagnostic::error(eve::DiagnosticCode::StaleHandle, "primitive scene owner no longer exists",
52 "primitive", {}, "graphics.primitive.binding"));
53 return scene->update(value->handle, std::move(copy));
54}
55
56ssq::Table makePrimitiveProxy(HSQUIRRELVM vm, const std::shared_ptr<PrimitiveScene>& scene,
58 if (!result) return eve::script::projectStatusResult(vm, result.status());
59 const PrimitiveHandle handle = std::move(result).takeValue();
60 auto object = eve::script::makeOwnedSquirrelInstance<ScriptPrimitive3D>(
61 vm, std::make_unique<ScriptPrimitive3D>(scene, handle));
62 if (!object) {
63 const eve::Status status = object.status();
64 object.ignore("failed to create owned primitive proxy");
65 scene->remove(handle).ignore("rollback failed primitive proxy allocation");
67 }
69 projected.set("value", std::move(object).takeValue());
70 projected.set("ownership", std::string("owned"));
71 projected.set("owner", static_cast<std::int64_t>(handle.owner()));
72 projected.set("index", static_cast<std::int64_t>(handle.index()));
73 projected.set("generation", static_cast<std::int64_t>(handle.generation()));
74 return projected;
75}
76
77ScenePrimitivePaint scriptPrimitivePaint(float r, float g, float b, float a, float width) {
78 ScenePrimitivePaint paint;
79 paint.color = Color(r, g, b, a);
80 paint.mode = PaintMode::Stroke;
81 paint.stroke.width = width;
82 paint.stroke.widthSpace = WidthSpace::ScreenPixels;
83 return paint;
84}
85
86eve::Result<std::vector<glm::vec3>> scriptPoints(ssq::Array values, std::size_t minimum, std::size_t maximum) {
87 if (values.size() % 3 != 0 || values.size() / 3 < minimum || values.size() / 3 > maximum)
89 eve::DiagnosticCode::InvalidArgument, "expected a flat xyz array with the required point count", "points",
90 {}, "graphics.primitive.binding"));
91 std::vector<glm::vec3> points;
92 points.reserve(values.size() / 3);
93 try {
94 for (std::size_t i = 0; i < values.size(); i += 3)
95 points.push_back({values.get<float>(i), values.get<float>(i+1), values.get<float>(i+2)});
96 } catch (const std::exception& error) {
98 eve::DiagnosticCode::InvalidArgument, error.what(), "points", {}, "graphics.primitive.binding"));
99 }
100 return eve::Result<std::vector<glm::vec3>>::success(std::move(points));
101}
102} // namespace
103
104void exposePrimitiveScriptBindings(ssq::Table& table, ssq::Class& cls) {
105 const auto vm = table.getHandle();
106 cls.addFunc("newPrimitiveGrid3D", [vm](Graphics* self, ssq::Array xyz, int cellsU, int cellsV,
107 float r, float g, float b, float a, float width) {
108 auto parsed = scriptPoints(xyz, 3, 3);
109 if (!parsed) return eve::script::projectStatusResult(vm, parsed.status());
110 auto points = std::move(parsed).takeValue();
111 if (cellsU <= 0 || cellsV <= 0 || cellsU > 4096 || cellsV > 4096)
114 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "grid cells must be in [1,4096]",
115 "cells", {}, "graphics.primitive.binding"))
116 .status());
117 auto scene = self->getPrimitiveScene();
120 static_cast<std::uint32_t>(cellsU),static_cast<std::uint32_t>(cellsV)};
121 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
122 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
123 });
124 cls.addFunc("newPrimitiveArc3D", [vm](Graphics* self, ssq::Array xyz, float radius, float start, float sweep,
125 float r, float g, float b, float a, float width) {
126 auto parsed = scriptPoints(xyz, 3, 3);
127 if (!parsed) return eve::script::projectStatusResult(vm, parsed.status());
128 auto points = std::move(parsed).takeValue();
129 auto scene = self->getPrimitiveScene();
132 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
133 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
134 });
135 cls.addFunc("newPrimitivePolyline3D", [vm](Graphics* self, ssq::Array xyz, bool closed,
136 float r, float g, float b, float a, float width) {
137 auto parsed = scriptPoints(xyz, closed ? 3 : 2, 65536);
138 if (!parsed) return eve::script::projectStatusResult(vm, parsed.status());
139 auto points = std::move(parsed).takeValue();
140 auto scene = self->getPrimitiveScene();
143 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
144 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
145 });
146 cls.addFunc("newPrimitiveObb3D", [vm](Graphics* self, ssq::Array xyz,
147 float r, float g, float b, float a, float width) {
148 auto parsed = scriptPoints(xyz, 4, 4);
149 if (!parsed) return eve::script::projectStatusResult(vm, parsed.status());
150 auto points = std::move(parsed).takeValue();
151 auto scene = self->getPrimitiveScene();
154 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
155 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
156 });
157 cls.addFunc("newPrimitiveFrustum3D", [vm](Graphics* self, ssq::Array xyz,
158 float r, float g, float b, float a, float width) {
159 auto parsed = scriptPoints(xyz, 8, 8);
160 if (!parsed) return eve::script::projectStatusResult(vm, parsed.status());
161 auto points = std::move(parsed).takeValue();
162 auto scene = self->getPrimitiveScene();
165 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
166 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
167 });
168 cls.addFunc("newPrimitiveDisk3D", [vm](Graphics* self, float x, float y, float z, float nx, float ny, float nz, float radius,
169 float r, float g, float b, float a, float width) {
170 auto scene = self->getPrimitiveScene();
173 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
174 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
175 });
176 cls.addFunc("newPrimitiveCylinder3D", [vm](Graphics* self, float ax, float ay, float az, float bx, float by, float bz, float radius,
177 float r, float g, float b, float a, float width) {
178 auto scene = self->getPrimitiveScene();
181 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
182 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
183 });
184 cls.addFunc("newPrimitiveCapsule3D", [vm](Graphics* self, float ax, float ay, float az, float bx, float by, float bz, float radius,
185 float r, float g, float b, float a, float width) {
186 auto scene = self->getPrimitiveScene();
189 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
190 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
191 });
192 cls.addFunc("newPrimitiveCone3D", [vm](Graphics* self, float x, float y, float z, float dx, float dy, float dz, float height, float radius,
193 float r, float g, float b, float a, float width) {
194 auto scene = self->getPrimitiveScene();
197 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
198 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
199 });
200 cls.addFunc("newPrimitiveArrow3D", [vm](Graphics* self, float ax, float ay, float az, float bx, float by, float bz, float headLength, float headRadius,
201 float r, float g, float b, float a, float width) {
202 auto scene = self->getPrimitiveScene();
204 descriptor.geometry = PrimitiveArrow3D{{ax,ay,az},{bx,by,bz},headLength,headRadius};
205 descriptor.paint = scriptPrimitivePaint(r,g,b,a,width);
206 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
207 });
208 auto primitive = table.addClass<ScriptPrimitive3D>(
209 "Primitive3D", std::function<ScriptPrimitive3D*()>([]() { return nullptr; }), false);
210 const auto primitiveTag = primitive.getTypeTag();
211 cls.addFunc(
212 "setPrimitiveTransforms3D", [vm, primitiveTag](Graphics* self, ssq::Array proxies, ssq::Array matrices) {
213 auto failure = [vm](const std::string& message) {
216 message, "transforms", {},
217 "graphics.primitive.binding"))
218 .status());
219 };
220 if (!self || proxies.size() > 65536 || matrices.size() != proxies.size() * 16)
221 return failure("expected one column-major matrix per primitive, at most 65536 primitives");
222 auto scene = self->getPrimitiveScene();
223 std::vector<PrimitiveBatchUpdate> updates;
224 updates.reserve(proxies.size());
225 try {
226 for (std::size_t i = 0; i < proxies.size(); ++i) {
227 auto object = proxies.get<ssq::Object>(i);
228 if (object.getType() != ssq::Type::INSTANCE || object.getTypeTag() != primitiveTag)
229 return failure("batch entries must be Primitive3D proxies");
230 auto* proxy = object.toPtrUnsafe<ScriptPrimitive3D*>();
231 auto descriptor = primitiveDescriptor(proxy);
233 auto copy = std::move(descriptor).takeValue();
234 for (int column = 0; column < 4; ++column)
235 for (int row = 0; row < 4; ++row)
236 copy.transform[column][row] = matrices.get<float>(i * 16 + column * 4 + row);
237 updates.push_back({proxy->handle, std::move(copy)});
238 }
239 } catch (const std::exception& error) {
240 return failure(error.what());
241 }
242 auto result = scene->updateMany(updates);
243 const auto status = result.status();
244 if (!result) return eve::script::projectStatusResult(vm, status);
245 const auto count = std::move(result).takeValue();
247 projected.set("count", static_cast<std::int64_t>(count));
248 return projected;
249 });
250 primitive.addFunc("ownership", [](ScriptPrimitive3D*) { return std::string("owned"); });
251 primitive.addFunc("setPolyline", [vm](ScriptPrimitive3D* value, ssq::Array xyz, bool closed) {
252 auto parsed = scriptPoints(xyz, closed ? 3 : 2, 65536);
253 if (!parsed) return eve::script::projectStatusResult(vm, parsed.status());
254 auto points = std::move(parsed).takeValue();
255 auto result = mutatePrimitive(value, [&](PrimitiveDescriptor3D& descriptor) {
256 descriptor.geometry = PrimitivePolyline3D{std::move(points), closed};
257 });
258 const auto status = result.status();
259 if (!result) return eve::script::projectStatusResult(vm, status);
260 std::move(result).takeValue();
262 });
263 primitive.addFunc("setLayer", [vm](ScriptPrimitive3D* value, std::int64_t layer) {
264 if (layer < 0 || layer > 0xffffffffLL)
267 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "layer must fit uint32", "layer",
268 {}, "graphics.primitive.binding"))
269 .status());
270 auto result = mutatePrimitive(value, [layer](PrimitiveDescriptor3D& descriptor) {
271 descriptor.paint.layer = static_cast<std::uint32_t>(layer);
272 });
273 const auto status = result.status();
274 if (!result) return eve::script::projectStatusResult(vm, status);
275 std::move(result).takeValue();
277 });
278 primitive.addFunc("setTransform", [vm](ScriptPrimitive3D* value, ssq::Array elements) {
279 if (elements.size() != 16)
283 "transform requires 16 column-major floats", "transform", {},
284 "graphics.primitive.binding"))
285 .status());
286 glm::mat4 transform(1.f);
287 try {
288 for (int column = 0; column < 4; ++column)
289 for (int row = 0; row < 4; ++row)
290 transform[column][row] = elements.get<float>(column * 4 + row);
291 } catch (const std::exception& error) {
295 "graphics.primitive.binding"))
296 .status());
297 }
298 auto result = mutatePrimitive(value, [&](PrimitiveDescriptor3D& descriptor) {
299 descriptor.transform = transform;
300 });
301 const auto status = result.status();
302 if (!result) return eve::script::projectStatusResult(vm, status);
303 std::move(result).takeValue();
305 });
306 primitive.addFunc("setWidthSpace", [vm](ScriptPrimitive3D* value, const std::string& mode) {
307 std::optional<WidthSpace> parsed;
308 if (mode == "screen") parsed = WidthSpace::ScreenPixels;
309 if (mode == "world") parsed = WidthSpace::WorldUnits;
310 if (!parsed)
313 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "unsupported setWidthSpace value",
314 "setWidthSpace", {}, "graphics.primitive.binding"))
315 .status());
316 auto result = mutatePrimitive(value, [mode = *parsed](PrimitiveDescriptor3D& descriptor) {
317 descriptor.paint.stroke.widthSpace = mode;
318 });
319 const auto status = result.status();
320 if (!result) return eve::script::projectStatusResult(vm, status);
321 std::move(result).takeValue();
323 });
324 primitive.addFunc("setPaintMode", [vm](ScriptPrimitive3D* value, const std::string& mode) {
325 std::optional<PaintMode> parsed;
326 if (mode == "fill") parsed = PaintMode::Fill;
327 if (mode == "stroke") parsed = PaintMode::Stroke;
328 if (mode == "fill-stroke") parsed = PaintMode::FillAndStroke;
329 if (!parsed)
332 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "unsupported setPaintMode value",
333 "setPaintMode", {}, "graphics.primitive.binding"))
334 .status());
335 auto result = mutatePrimitive(value, [mode = *parsed](PrimitiveDescriptor3D& descriptor) {
336 descriptor.paint.mode = mode;
337 });
338 const auto status = result.status();
339 if (!result) return eve::script::projectStatusResult(vm, status);
340 std::move(result).takeValue();
342 });
343 primitive.addFunc("setLineCap", [vm](ScriptPrimitive3D* value, const std::string& mode) {
344 std::optional<LineCap> parsed;
345 if (mode == "butt") parsed = LineCap::Butt;
346 if (mode == "square") parsed = LineCap::Square;
347 if (mode == "round") parsed = LineCap::Round;
348 if (!parsed)
351 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "unsupported setLineCap value",
352 "setLineCap", {}, "graphics.primitive.binding"))
353 .status());
354 auto result = mutatePrimitive(value, [mode = *parsed](PrimitiveDescriptor3D& descriptor) {
355 descriptor.paint.stroke.cap = mode;
356 });
357 const auto status = result.status();
358 if (!result) return eve::script::projectStatusResult(vm, status);
359 std::move(result).takeValue();
361 });
362 primitive.addFunc("setLineJoin", [vm](ScriptPrimitive3D* value, const std::string& mode) {
363 std::optional<LineJoin> parsed;
364 if (mode == "miter") parsed = LineJoin::Miter;
365 if (mode == "bevel") parsed = LineJoin::Bevel;
366 if (mode == "round") parsed = LineJoin::Round;
367 if (!parsed)
370 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "unsupported setLineJoin value",
371 "setLineJoin", {}, "graphics.primitive.binding"))
372 .status());
373 auto result = mutatePrimitive(value, [mode = *parsed](PrimitiveDescriptor3D& descriptor) {
374 descriptor.paint.stroke.join = mode;
375 });
376 const auto status = result.status();
377 if (!result) return eve::script::projectStatusResult(vm, status);
378 std::move(result).takeValue();
380 });
381 primitive.addFunc("setCullMode", [vm](ScriptPrimitive3D* value, const std::string& mode) {
382 std::optional<PrimitiveCullMode> parsed;
383 if (mode == "none") parsed = PrimitiveCullMode::None;
384 if (mode == "back") parsed = PrimitiveCullMode::Back;
385 if (mode == "front") parsed = PrimitiveCullMode::Front;
386 if (!parsed)
389 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "unsupported setCullMode value",
390 "setCullMode", {}, "graphics.primitive.binding"))
391 .status());
392 auto result = mutatePrimitive(value, [mode = *parsed](PrimitiveDescriptor3D& descriptor) {
393 descriptor.paint.cull = mode;
394 });
395 const auto status = result.status();
396 if (!result) return eve::script::projectStatusResult(vm, status);
397 std::move(result).takeValue();
399 });
400 primitive.addFunc("setBlendMode", [vm](ScriptPrimitive3D* value, const std::string& mode) {
401 std::optional<BlendMode> parsed;
402 if (mode == "alpha") parsed = BlendMode::Alpha;
403 if (mode == "opaque") parsed = BlendMode::Opaque;
404 if (mode == "additive") parsed = BlendMode::Additive;
405 if (mode == "premultiplied") parsed = BlendMode::Premultiplied;
406 if (mode == "multiply") parsed = BlendMode::Multiply;
407 if (!parsed)
410 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "unsupported setBlendMode value",
411 "setBlendMode", {}, "graphics.primitive.binding"))
412 .status());
413 auto result = mutatePrimitive(value, [mode = *parsed](PrimitiveDescriptor3D& descriptor) {
414 descriptor.paint.blend = mode;
415 });
416 const auto status = result.status();
417 if (!result) return eve::script::projectStatusResult(vm, status);
418 std::move(result).takeValue();
420 });
421 primitive.addFunc("isStale", [](ScriptPrimitive3D* value) {
422 if (!value) return true;
423 auto scene = value->scene.lock();
424 return !scene || scene->isStale(value->handle);
425 });
426 primitive.addFunc("remove", [vm](ScriptPrimitive3D* value) {
427 if (!value)
430 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "primitive proxy must not be null",
431 "primitive", {}, "graphics.primitive.binding"))
432 .status());
433 auto scene = value->scene.lock();
434 if (!scene)
436 vm,
438 eve::Diagnostic::error(eve::DiagnosticCode::StaleHandle, "primitive scene owner no longer exists",
439 "primitive", {}, "graphics.primitive.binding"))
440 .status());
441 auto result = scene->remove(value->handle);
442 const eve::Status status = result.status();
443 if (!result) return eve::script::projectStatusResult(vm, status);
444 std::move(result).takeValue();
445 value->handle = {};
447 });
448 primitive.addFunc("setVisible", [vm](ScriptPrimitive3D* value, bool visible) {
449 auto result =
450 mutatePrimitive(value, [visible](PrimitiveDescriptor3D& descriptor) { descriptor.visible = visible; });
451 const eve::Status status = result.status();
452 if (!result) return eve::script::projectStatusResult(vm, status);
453 std::move(result).takeValue();
455 });
456 primitive.addFunc("setColor", [vm](ScriptPrimitive3D* value, float r, float g, float b, float a) {
457 auto result = mutatePrimitive(
458 value, [=](PrimitiveDescriptor3D& descriptor) { descriptor.paint.color = Color(r, g, b, a); });
459 const eve::Status status = result.status();
460 if (!result) return eve::script::projectStatusResult(vm, status);
461 std::move(result).takeValue();
463 });
464 primitive.addFunc("setLineWidth", [vm](ScriptPrimitive3D* value, float width) {
465 auto result = mutatePrimitive(
466 value, [width](PrimitiveDescriptor3D& descriptor) { descriptor.paint.stroke.width = width; });
467 const eve::Status status = result.status();
468 if (!result) return eve::script::projectStatusResult(vm, status);
469 std::move(result).takeValue();
471 });
472 primitive.addFunc("setDash", [vm](ScriptPrimitive3D* value, float drawLength, float gapLength, float phase,
473 const std::string& space) {
474 if (space != "screen" && space != "world")
476 vm,
478 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "dash space must be screen or world",
479 "dashSpace", {}, "graphics.primitive.binding"))
480 .status());
481 auto result = mutatePrimitive(value, [=](PrimitiveDescriptor3D& descriptor) {
482 DashPattern dash;
483 dash.intervals = {drawLength, gapLength};
484 dash.phase = phase;
485 dash.space = space == "screen" ? DashSpace::ScreenPixels : DashSpace::WorldUnits;
486 descriptor.paint.stroke.dash = std::move(dash);
487 });
488 const eve::Status status = result.status();
489 if (!result) return eve::script::projectStatusResult(vm, status);
490 std::move(result).takeValue();
492 });
493 primitive.addFunc("clearDash", [vm](ScriptPrimitive3D* value) {
494 auto result =
495 mutatePrimitive(value, [](PrimitiveDescriptor3D& descriptor) { descriptor.paint.stroke.dash.reset(); });
496 const eve::Status status = result.status();
497 if (!result) return eve::script::projectStatusResult(vm, status);
498 std::move(result).takeValue();
500 });
501 primitive.addFunc("setDepthMode", [vm](ScriptPrimitive3D* value, const std::string& mode) {
502 std::optional<PrimitiveDepthMode> parsed;
503 if (mode == "test-write")
505 else if (mode == "test")
507 else if (mode == "ignore")
509 if (!parsed)
513 "depth mode must be test-write, test, or ignore", "depthMode", {},
514 "graphics.primitive.binding"))
515 .status());
516 auto result = mutatePrimitive(
517 value, [mode = *parsed](PrimitiveDescriptor3D& descriptor) { descriptor.paint.depth = mode; });
518 const eve::Status status = result.status();
519 if (!result) return eve::script::projectStatusResult(vm, status);
520 std::move(result).takeValue();
522 });
523 primitive.addFunc("setObjectId", [vm](ScriptPrimitive3D* value, std::int64_t objectId) {
524 if (objectId < 0)
527 eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, "object id must be non-negative",
528 "objectId", {}, "graphics.primitive.binding"))
529 .status());
530 auto result = mutatePrimitive(value, [objectId](PrimitiveDescriptor3D& descriptor) {
531 descriptor.paint.objectId = static_cast<std::uint64_t>(objectId);
532 });
533 const eve::Status status = result.status();
534 if (!result) return eve::script::projectStatusResult(vm, status);
535 std::move(result).takeValue();
537 });
538
539 cls.addFunc("newPrimitiveLine3D", [vm](Graphics* self, float ax, float ay, float az, float bx, float by, float bz,
540 float r, float g, float b, float a, float width) {
541 auto scene = self->getPrimitiveScene();
543 descriptor.geometry = PrimitivePolyline3D{{{ax, ay, az}, {bx, by, bz}}, false};
544 descriptor.paint = scriptPrimitivePaint(r, g, b, a, width);
545 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
546 });
547 cls.addFunc("newPrimitiveSphere3D", [vm](Graphics* self, float x, float y, float z, float radius, float r, float g,
548 float b, float a, float width) {
549 auto scene = self->getPrimitiveScene();
552 descriptor.paint = scriptPrimitivePaint(r, g, b, a, width);
553 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
554 });
555 cls.addFunc("newPrimitiveAabb3D", [vm](Graphics* self, float minX, float minY, float minZ, float maxX, float maxY,
556 float maxZ, float r, float g, float b, float a, float width) {
557 auto scene = self->getPrimitiveScene();
559 descriptor.geometry = PrimitiveAabb3D{{minX, minY, minZ}, {maxX, maxY, maxZ}};
560 descriptor.paint = scriptPrimitivePaint(r, g, b, a, width);
561 return makePrimitiveProxy(vm, scene, scene->add(std::move(descriptor)));
562 });
563}
564} // namespace eve::graphics
double value
Duration start
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::string descriptor
Vec3 projected
Definition CaveMesh.cpp:122
float phase
Definition CaveMesh.cpp:58
int bz
Definition CaveMesh.cpp:114
int ax
Definition CaveMesh.cpp:113
int ay
Definition CaveMesh.cpp:113
int bx
Definition CaveMesh.cpp:114
int az
Definition CaveMesh.cpp:113
int by
Definition CaveMesh.cpp:114
float nx
float nz
float ny
struct SQVM * HSQUIRRELVM
int column
HSQUIRRELVM vm
Definition ECS.cpp:20
HSQOBJECT cls
Definition ECS.cpp:21
std::map< std::string, Var > values
std::string message
float maximum[3]
float minimum[3]
tensor::Graph g
Definition GpuGraph.cpp:7
wgpu::PopErrorScopeStatus status
double r
std::uint32_t height
std::uint32_t width
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
std::string error
Definition Package.cpp:60
TileLayer * layer
float radius
std::shared_ptr< const std::vector< glm::vec2 > > points
std::weak_ptr< PrimitiveScene > scene
PrimitiveHandle handle
float dz
float dy
float dx
std::uint32_t count
std::size_t elements
The single Squirrel projection for common Result, Status and Value.
Explicit Value/Owned/Borrowed semantics at the Squirrel boundary.
bool visible
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
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
const Status & status() const noexcept
Inspect the structured operation status.
Definition Result.h:269
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Structured status and zero or more diagnostics for an operation.
Definition Status.h:68
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
std::shared_ptr< PrimitiveScene > getPrimitiveScene() const noexcept
Returns the authoritative persistent spatial-primitive scene.
Definition Graphics.h:521
constexpr generation_type generation() const noexcept
Generation.
constexpr owner_type owner() const noexcept
Owner.
constexpr index_type index() const noexcept
Index.
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
void exposePrimitiveScriptBindings(ssq::Table &table, ssq::Class &cls)
Registers owning primitive proxies on the VM owner thread; retains no table references.
eve::Color Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13
ssq::Table projectStatusResult(HSQUIRRELVM vm, const Status &status)
Project a checked native status that carries no payload.
Owning alternating draw/gap pattern for stroked primitives.
std::vector< float > intervals
PrimitiveAabb3D public API.
PrimitiveArc3D public API.
PrimitiveArrow3D public API.
PrimitiveCapsule3D public API.
PrimitiveCone3D public API.
PrimitiveCylinder3D public API.
One persistent scene primitive owned by PrimitiveScene.
PrimitiveDisk3D public API.
PrimitiveFrustum3D public API.
PrimitiveGrid3D public API.
PrimitiveObb3D public API.
Owning persistent polyline descriptor.
PrimitiveSphere3D public API.