9#include <simplesquirrel/simplesquirrel.hpp>
19 const SQInteger
n = sq_gettop(
vm);
20 if (n < 5 || n > 6)
return sq_throwerror(
vm,
"wrong number of parameters");
21 VoxelWorld*
world =
nullptr;
22 if (SQ_FAILED(sq_getinstanceup(
vm, 1,
reinterpret_cast<SQUserPointer*
>(&
world),
nullptr)) ||
24 return sq_throwerror(
vm,
"invalid VoxelWorld");
25 SQInteger
wx = 0,
wy = 0,
wz = 0, orientation = 0;
26 const SQChar*
name =
nullptr;
27 if (SQ_FAILED(sq_getinteger(
vm, 2, &
wx)) || SQ_FAILED(sq_getinteger(
vm, 3, &
wy)) ||
28 SQ_FAILED(sq_getinteger(
vm, 4, &
wz)) || SQ_FAILED(sq_getstring(
vm, 5, &
name)))
29 return sq_throwerror(
vm,
"setVoxelByName expects (x, y, z, name [, orientation])");
30 if (
n >= 6 && SQ_FAILED(sq_getinteger(
vm, 6, &orientation)))
31 return sq_throwerror(
vm,
"setVoxelByName orientation must be an integer");
32 world->setVoxelByName(
static_cast<int>(
wx),
static_cast<int>(
wy),
static_cast<int>(
wz),
33 name ?
name :
"", static_cast<int>(orientation));
39 const SQInteger
n = sq_gettop(
vm);
40 if (n < 5 || n > 6)
return sq_throwerror(
vm,
"wrong number of parameters");
41 VoxelWorld *
world =
nullptr;
42 if (SQ_FAILED(sq_getinstanceup(
vm, 1,
reinterpret_cast<SQUserPointer *
>(&
world),
nullptr)) ||
44 return sq_throwerror(
vm,
"invalid VoxelWorld");
45 SQInteger
cx = 0,
cy = 0, cz = 0,
radius = 0, maxCreates = 0;
46 if (SQ_FAILED(sq_getinteger(
vm, 2, &
cx)) || SQ_FAILED(sq_getinteger(
vm, 3, &
cy)) ||
47 SQ_FAILED(sq_getinteger(
vm, 4, &cz)) || SQ_FAILED(sq_getinteger(
vm, 5, &
radius)))
48 return sq_throwerror(
vm,
"streamAround expects (cx, cy, cz, radius [, maxCreates])");
49 if (
n >= 6 && SQ_FAILED(sq_getinteger(
vm, 6, &maxCreates)))
50 return sq_throwerror(
vm,
"streamAround maxCreates must be an integer");
51 const StreamStats
stats =
52 world->streamAround(
int(
cx),
int(
cy),
int(cz),
int(
radius), {}, int(maxCreates));
53 sq_pushinteger(
vm,
stats.created);
67void Voxel::expose(ssq::Table &table) {
68 auto cls = table.addClass(
name, Voxel::create,
false);
72 "VoxelCubeTypes", std::function<CubeTypeRegistry *()>(
75 cubeTypes.addFunc(
"loadFromJson",
76 std::function<
int(CubeTypeRegistry *,
const std::string &)>(
77 [](CubeTypeRegistry *
r,
const std::string &json) {
78 return r->loadFromJson(json,
nullptr);
84 auto world = table.addClass<VoxelWorld>(
85 "VoxelWorld", std::function<VoxelWorld *()>([]() -> VoxelWorld * {
return nullptr; }),
true);
93 sq_pushobject(
vm,
world.getRaw());
94 sq_pushstring(
vm,
"streamAround", -1);
95 sq_newclosure(
vm, sqStreamAround, 0);
96 sq_setparamscheck(
vm, -5, _SC(
"xiiii|i"));
97 sq_newslot(
vm, -3, SQFalse);
102 std::function<
void(VoxelWorld *,
int,
int,
int,
int,
float,
float,
float)>(
103 [](VoxelWorld *
w,
int seed,
int top,
int sub,
int stone,
float baseHeight,
104 float amplitude,
float scale) {
106 w->setTerrainParams(uint32_t(
seed), uint8_t(
top), uint8_t(sub), uint8_t(stone),
107 baseHeight, amplitude,
scale);
113 std::function<
bool(VoxelWorld *, data::ByteData *,
float,
float)>(
118 "streamTerrainAssetAround",
119 std::function<
int(VoxelWorld *,
int,
int,
int,
int)>(
120 [](VoxelWorld *
w,
int wx,
int wz,
int radius,
int maxLoads) {
121 return w ?
w->streamTerrainAssetAround(
wx,
wz,
radius, maxLoads).loaded : 0;
124 "setTerrainAssetMaterials",
125 std::function<
void(VoxelWorld *,
int,
int,
int,
int,
int)>(
126 [](VoxelWorld *
w,
int vegetation,
int sand,
int snow,
int alpine,
int riverbed) {
127 if (
w)
w->setTerrainAssetMaterials(uint8_t(vegetation), uint8_t(sand),
128 uint8_t(snow), uint8_t(alpine),
140 world.addFunc(
"remeshDirty",
141 std::function<
int(VoxelWorld *)>([](VoxelWorld *
w) ->
int {
142 return w ?
w->remeshDirty() : 0;
149 sq_pushobject(
vm,
world.getRaw());
150 sq_pushstring(
vm,
"setVoxelByName", -1);
151 sq_newclosure(
vm, sqSetVoxelByName, 0);
152 sq_setparamscheck(
vm, -5, _SC(
"xiiis|i"));
153 sq_newslot(
vm, -3, SQFalse);
160 std::function<
bool(VoxelWorld *,
float,
float,
float,
float,
float,
float,
float)>(
161 [](VoxelWorld *
w,
float ox,
float oy,
float oz,
float dx,
float dy,
float dz,
162 float maxDist) ->
bool {
163 return w &&
w->raycastScript(
ox,
oy, oz,
dx,
dy,
dz, maxDist);
180 std::function<
void(VoxelWorld *,
float,
float,
float,
float,
float,
float,
float,
float,
181 float,
float,
float,
float,
float,
float,
float,
float,
float,
float,
182 float,
float,
bool)>(
183 [](VoxelWorld *
w,
float m0,
float m1,
float m2,
float m3,
float m4,
float m5,
float m6,
184 float m7,
float m8,
float m9,
float m10,
float m11,
float m12,
float m13,
float m14,
185 float m15,
float eyeX,
float eyeY,
float eyeZ,
float viewRange,
bool faceCull) {
187 float vp[16] = {m0, m1, m2, m3, m4, m5, m6, m7,
188 m8, m9, m10, m11, m12, m13, m14, m15};
189 w->selectVisible(vp, eyeX, eyeY, eyeZ, viewRange, faceCull);
194void Voxel::expose(ssq::Class &
cls) {
197 cls.addFunc(
"newWorld", std::function<VoxelWorld *(
Voxel *)>(
198 [](
Voxel *
m) -> VoxelWorld * {
return m->newWorld(
nullptr); }));
199 cls.addFunc(
"newWorldWithTypes",
200 std::function<VoxelWorld *(
Voxel *, CubeTypeRegistry *)>(
201 [](
Voxel *
m, CubeTypeRegistry *types) -> VoxelWorld * {
202 return m->newWorld(types);
struct SQVM * HSQUIRRELVM
std::array< float, 3 > scale
#define Module_IMPL(ModuleName, newExpr)
EVENGINE_API_DOMAINS public API.
int variantCount() const
类型总数(含方向变体,不含空气占位)。
int count() const
命名的方块类型数量(不含方向变体)。
Sparse chunk map + visibility selection (frustum + distance + face orientation). Meshing is neighbor-...
int lastRaycastHitY() const
Last raycast hit y.
data::ByteData * saveWorld() const
Script-facing wrappers around serialize/deserialize.
int terrainHeightAt(int wx, int wz) const
Terrain height (world blocks) at a column for the configured seed.
int getTerrainAssetResidentCount() const
Returns the terrain asset resident count.
uint8_t getCubeTypeTex(int wx, int wy, int wz, const std::string &faceDir) const
该体素在某面方向上的纹理 id(faceDir 如 "posX"/"+y"/"negZ")。
int lastRaycastHitZ() const
Last raycast hit z.
uint8_t getVoxel(int wx, int wy, int wz) const
World-space voxel get/set. Air (0) never allocates a chunk; a border edit also invalidates the adjace...
void drawVisible(graphics::Graphics *gfx, graphics::Texture *atlas, int tilesPerRow=16)
Issue Graphics::drawVoxelFaceInstances for every visible batch. Requires begin3DFrame + setMesh3DView...
bool lastRaycastHit() const
Last raycast hit.
int getVisibleChunkCount() const
Script accessors for the last selectVisible result.
int lastRaycastHitX() const
Last raycast hit x.
void setVoxel(int wx, int wy, int wz, uint8_t texId)
Sets the voxel.
int getVisibleBatchCount() const
Returns the visible batch count.
int getChunkCount() const
Returns the chunk count.
int getDirtyCount() const
Number of chunks whose mesh is stale.
int lastRaycastFaceX() const
Last raycast face x.
int lastRaycastPrevY() const
Last raycast prev y.
int lastRaycastFaceZ() const
Last raycast face z.
uint64_t getRevision() const
Monotonic content revision incremented by voxel/chunk mutations.
std::string getCubeTypeName(int wx, int wy, int wz) const
该体素所属方块类型名(未注册或空气返回空串)。
bool loadWorld(data::ByteData *bytes)
Loads world.
void disableTerrain()
Disables terrain.
int lastRaycastPrevX() const
Last raycast prev x.
int getInflightStreamCount() const
Terrain jobs still running (not yet inserted into the world).
void removeChunk(int cx, int cy, int cz)
Removes chunk.
bool hasChunk(int cx, int cy, int cz) const
True when chunk.
int lastRaycastFaceY() const
Last raycast face y.
int getVisibleRectCount() const
Returns the visible rect count.
void setStreamCacheChunks(int extraChunks)
Extra chunk radius kept after leaving the stream sphere. streamAround still creates only inside radiu...
int lastRaycastPrevZ() const
Last raycast prev z.
int unloadChunksOutside(int centerX, int centerY, int centerZ, int radiusChunks)
Streaming eviction: drop chunks whose center is farther than radiusChunks chunk units from (centerX,...
void setTerrainParam(const std::string &key, float value)
细粒度地形参数配置(脚本用)。key 支持: seed/top/sub/stone/sand/base/amplitude/scale(=frequency)/ octaves/lacunarity/g...
int getStreamCacheChunks() const
Returns the stream cache chunks.
High-performance voxel rendering module.
CubeTypeRegistry * newCubeTypes()
返回一个新的方块类型注册表(由调用者持有 / 脚本持有)。
int getChunkSize() const
Returns the chunk size.
VoxelWorld * newWorld(const CubeTypeRegistry *types=nullptr)
创建世界;内部拷贝注册表(传 nullptr 表示空注册表,类型 id 即纹理 id)。
std::unordered_map< std::string, SkillDefinition > & table()
方块类型定义:名字、各面图集纹理、方向性、组合声明。 方向性方块在注册时按 orientation 绕 Y 轴展开成多个"具体类型"变体, 每个变体持有旋转后的各面纹理;渲染端只消费纹理 id,不接触 ...