Skip to content

Commit

Permalink
Use a struct for side surfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed Apr 27, 2024
1 parent fc4b771 commit 46eec83
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 46 deletions.
13 changes: 5 additions & 8 deletions meshers/blocky/voxel_blocky_library_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,16 @@ void rasterize_side( //
}
}

void rasterize_side( //
void rasterize_side_all_surfaces( //
const VoxelBlockyModel::BakedData &model_data, //
const unsigned int side, //
const unsigned int side_index, //
std::bitset<RASTER_SIZE * RASTER_SIZE> &bitmap //
) {
// For each surface (they are all combined for simplicity, though it is also a limitation)
for (unsigned int surface_index = 0; surface_index < model_data.model.surface_count; ++surface_index) {
const VoxelBlockyModel::BakedData::Surface &surface = model_data.model.surfaces[surface_index];

const StdVector<Vector3f> &positions = surface.side_positions[side];
const StdVector<int> &indices = surface.side_indices[side];

rasterize_side(to_span(positions), to_span(indices), side, bitmap);
const VoxelBlockyModel::BakedData::SideSurface &side = surface.sides[side_index];
rasterize_side(to_span(side.positions), to_span(side.indices), side_index, bitmap);
}
}

Expand Down Expand Up @@ -204,7 +201,7 @@ void generate_side_culling_matrix(VoxelBlockyLibraryBase::BakedData &baked_data)
// For each side
for (uint16_t side = 0; side < Cube::SIDE_COUNT; ++side) {
std::bitset<RASTER_SIZE * RASTER_SIZE> bitmap;
rasterize_side(model_data, side, bitmap);
rasterize_side_all_surfaces(model_data, side, bitmap);

// Find if the same pattern already exists
uint32_t pattern_index = VoxelBlockyLibraryBase::NULL_INDEX;
Expand Down
19 changes: 10 additions & 9 deletions meshers/blocky/voxel_blocky_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ void VoxelBlockyModel::bake(BakedData &baked_data, bool bake_tangents, MaterialI
bool empty = true;
for (unsigned int surface_index = 0; surface_index < model.surface_count; ++surface_index) {
const BakedData::Surface &surface = model.surfaces[surface_index];
if (surface.side_indices[side].size() > 0) {
if (surface.sides[side].indices.size() > 0) {
empty = false;
break;
}
Expand Down Expand Up @@ -356,9 +356,9 @@ Ref<Mesh> VoxelBlockyModel::make_mesh_from_baked_data(const BakedData &baked_dat
// Get vertex and index count in the surface
unsigned int vertex_count = surface.positions.size();
unsigned int index_count = surface.indices.size();
for (unsigned int side = 0; side < surface.side_positions.size(); ++side) {
vertex_count += surface.side_positions[side].size();
index_count += surface.side_indices[side].size();
for (const BakedData::SideSurface &side_surface : surface.sides) {
vertex_count += side_surface.positions.size();
index_count += side_surface.indices.size();
}

// Allocate surface arrays
Expand Down Expand Up @@ -414,11 +414,12 @@ Ref<Mesh> VoxelBlockyModel::make_mesh_from_baked_data(const BakedData &baked_dat
++ii;
}

for (unsigned int side = 0; side < surface.side_positions.size(); ++side) {
Span<const Vector3f> side_positions = to_span(surface.side_positions[side]);
Span<const Vector2f> side_uvs = to_span(surface.side_uvs[side]);
Span<const int> side_indices = to_span(surface.side_indices[side]);
Span<const float> side_tangents = to_span(surface.side_tangents[side]);
for (unsigned int side = 0; side < surface.sides.size(); ++side) {
const BakedData::SideSurface &side_surface = surface.sides[side];
Span<const Vector3f> side_positions = to_span(side_surface.positions);
Span<const Vector2f> side_uvs = to_span(side_surface.uvs);
Span<const int> side_indices = to_span(side_surface.indices);
Span<const float> side_tangents = to_span(side_surface.tangents);
const Vector3 side_normal = to_vec3(Cube::g_side_normals[side]);

const unsigned int vi0 = vi;
Expand Down
27 changes: 18 additions & 9 deletions meshers/blocky/voxel_blocky_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ class VoxelBlockyModel : public Resource {
// while the configuration that produced the data can be changed by the user at any time.
// Also, it is lighter than Godot resources.
struct BakedData {
struct SideSurface {
StdVector<Vector3f> positions;
StdVector<Vector2f> uvs;
StdVector<int> indices;
StdVector<float> tangents;
// Normals aren't stored because they are assumed to be the same for the whole side

void clear() {
positions.clear();
uvs.clear();
indices.clear();
tangents.clear();
}
};

struct Surface {
// Inside part of the model.
StdVector<Vector3f> positions;
Expand All @@ -40,10 +55,7 @@ class VoxelBlockyModel : public Resource {
// Model sides:
// They are separated because this way we can occlude them easily.
// Due to these defining cube side triangles, normals are known already.
FixedArray<StdVector<Vector3f>, Cube::SIDE_COUNT> side_positions;
FixedArray<StdVector<Vector2f>, Cube::SIDE_COUNT> side_uvs;
FixedArray<StdVector<int>, Cube::SIDE_COUNT> side_indices;
FixedArray<StdVector<float>, Cube::SIDE_COUNT> side_tangents;
FixedArray<SideSurface, Cube::SIDE_COUNT> sides;

uint32_t material_id = 0;
bool collision_enabled = true;
Expand All @@ -55,11 +67,8 @@ class VoxelBlockyModel : public Resource {
indices.clear();
tangents.clear();

for (int side = 0; side < Cube::SIDE_COUNT; ++side) {
side_positions[side].clear();
side_uvs[side].clear();
side_indices[side].clear();
side_tangents[side].clear();
for (SideSurface &side : sides) {
side.clear();
}
}
};
Expand Down
12 changes: 7 additions & 5 deletions meshers/blocky/voxel_blocky_model_cube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ void bake_cube_geometry(const VoxelBlockyModelCube &config, VoxelBlockyModel::Ba
VoxelBlockyModel::BakedData::Surface &surface = baked_data.model.surfaces[0];

for (unsigned int side = 0; side < Cube::SIDE_COUNT; ++side) {
StdVector<Vector3f> &positions = surface.side_positions[side];
VoxelBlockyModel::BakedData::SideSurface &side_surface = surface.sides[side];
StdVector<Vector3f> &positions = side_surface.positions;
positions.resize(4);
for (unsigned int i = 0; i < 4; ++i) {
int corner = Cube::g_side_corners[side][i];
Expand All @@ -134,7 +135,7 @@ void bake_cube_geometry(const VoxelBlockyModelCube &config, VoxelBlockyModel::Ba
positions[i] = p;
}

StdVector<int> &indices = surface.side_indices[side];
StdVector<int> &indices = side_surface.indices;
indices.resize(6);
for (unsigned int i = 0; i < 6; ++i) {
indices[i] = Cube::g_side_quad_triangles[side][i];
Expand Down Expand Up @@ -166,8 +167,9 @@ void bake_cube_geometry(const VoxelBlockyModelCube &config, VoxelBlockyModel::Ba
const Vector2f s = Vector2f(1.0f) / atlas_size;

for (unsigned int side = 0; side < Cube::SIDE_COUNT; ++side) {
surface.side_uvs[side].resize(4);
StdVector<Vector2f> &uvs = surface.side_uvs[side];
VoxelBlockyModel::BakedData::SideSurface &side_surface = surface.sides[side];
StdVector<Vector2f> &uvs = side_surface.uvs;
uvs.resize(4);

const Vector2f *uv_norm = Cube::g_side_normals[side].y != 0 ? uv_norm_top_bottom : uv_norm_side;

Expand All @@ -176,7 +178,7 @@ void bake_cube_geometry(const VoxelBlockyModelCube &config, VoxelBlockyModel::Ba
}

if (bake_tangents) {
StdVector<float> &tangents = surface.side_tangents[side];
StdVector<float> &tangents = side_surface.tangents;
for (unsigned int i = 0; i < 4; ++i) {
for (unsigned int j = 0; j < 4; ++j) {
tangents.push_back(Cube::g_side_tangents[side][j]);
Expand Down
20 changes: 11 additions & 9 deletions meshers/blocky/voxel_blocky_model_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ void bake_mesh_geometry(Span<const Array> surfaces, Span<const Ref<Material>> ma
tri_positions[0], tri_positions[1], tri_positions[2], side, side_vertex_tolerance)) {
// That triangle is on the face

int next_side_index = surface.side_positions[side].size();
VoxelBlockyModel::BakedData::SideSurface &side_surface = surface.sides[side];

int next_side_index = side_surface.positions.size();

for (int j = 0; j < 3; ++j) {
const int src_index = indices[i + j];
Expand All @@ -279,26 +281,26 @@ void bake_mesh_geometry(Span<const Array> surfaces, Span<const Ref<Material>> ma
if (existing_dst_index_it == added_indices.end()) {
// Add new vertex

surface.side_indices[side].push_back(next_side_index);
surface.side_positions[side].push_back(tri_positions[j]);
surface.side_uvs[side].push_back(to_vec2f(uvs[indices[i + j]]));
side_surface.indices.push_back(next_side_index);
side_surface.positions.push_back(tri_positions[j]);
side_surface.uvs.push_back(to_vec2f(uvs[indices[i + j]]));

if (bake_tangents) {
// i is the first vertex of each triangle which increments by steps of 3.
// There are 4 floats per tangent.
int ti = indices[i + j] * 4;
surface.side_tangents[side].push_back(tangents[ti]);
surface.side_tangents[side].push_back(tangents[ti + 1]);
surface.side_tangents[side].push_back(tangents[ti + 2]);
surface.side_tangents[side].push_back(tangents[ti + 3]);
side_surface.tangents.push_back(tangents[ti]);
side_surface.tangents.push_back(tangents[ti + 1]);
side_surface.tangents.push_back(tangents[ti + 2]);
side_surface.tangents.push_back(tangents[ti + 3]);
}

added_indices.insert({ src_index, next_side_index });
++next_side_index;

} else {
// Vertex was already added, just add index referencing it
surface.side_indices[side].push_back(existing_dst_index_it->second);
side_surface.indices.push_back(existing_dst_index_it->second);
}
}

Expand Down
14 changes: 8 additions & 6 deletions meshers/blocky/voxel_mesher_blocky.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void generate_blocky_mesh( //
}

// Subtracting 1 because the data is padded
Vector3f pos(x - 1, y - 1, z - 1);
const Vector3f pos(x - 1, y - 1, z - 1);

for (unsigned int surface_index = 0; surface_index < model.surface_count; ++surface_index) {
const VoxelBlockyModel::BakedData::Surface &surface = model.surfaces[surface_index];
Expand All @@ -224,11 +224,13 @@ void generate_blocky_mesh( //
ZN_ASSERT(surface.material_id >= 0 && surface.material_id < index_offsets.size());
int &index_offset = index_offsets[surface.material_id];

const StdVector<Vector3f> &side_positions = surface.side_positions[side];
const unsigned int vertex_count = side_positions.size();
const VoxelBlockyModel::BakedData::SideSurface &side_surface = surface.sides[side];

const StdVector<Vector3f> &side_positions = side_surface.positions;
const unsigned int vertex_count = side_surface.positions.size();

const StdVector<Vector2f> &side_uvs = surface.side_uvs[side];
const StdVector<float> &side_tangents = surface.side_tangents[side];
const StdVector<Vector2f> &side_uvs = side_surface.uvs;
const StdVector<float> &side_tangents = side_surface.tangents;

// Append vertices of the faces in one go, don't use push_back

Expand Down Expand Up @@ -306,7 +308,7 @@ void generate_blocky_mesh( //
}
}

const StdVector<int> &side_indices = surface.side_indices[side];
const StdVector<int> &side_indices = side_surface.indices;
const unsigned int index_count = side_indices.size();

{
Expand Down

0 comments on commit 46eec83

Please sign in to comment.