correct normals for vheight floors
This commit is contained in:
parent
c10b3fefae
commit
00810b7d11
@ -327,10 +327,10 @@ enum
|
||||
STBVOX_GEOM_force, // all faces always visible, e.g. minecraft fancy leaves
|
||||
|
||||
// these access vheight input
|
||||
STBVOX_GEOM_floor_vheight_02 = 12, // diagonal is SW-NE -- assuming index buffer 0,1,2,0,2,3
|
||||
STBVOX_GEOM_floor_vheight_13, // diagonal is SE-NW -- assuming index buffer 0,1,2,0,2,3
|
||||
STBVOX_GEOM_ceil_vheight_02,
|
||||
STBVOX_GEOM_ceil_vheight_13,
|
||||
STBVOX_GEOM_floor_vheight_03 = 12, // diagonal is SW-NE
|
||||
STBVOX_GEOM_floor_vheight_12, // diagonal is SE-NW
|
||||
STBVOX_GEOM_ceil_vheight_03,
|
||||
STBVOX_GEOM_ceil_vheight_12,
|
||||
|
||||
STBVOX_GEOM_count, // number of geom cases
|
||||
};
|
||||
@ -551,51 +551,62 @@ struct stbvox_mesh_maker
|
||||
// mode, and all the bits to choose the normal.
|
||||
// Thus the bottom 3 bits have to be:
|
||||
// e, n, w, s, u, d, u, d
|
||||
//
|
||||
// These use compact names so tables are readable
|
||||
|
||||
enum
|
||||
{
|
||||
STBVOX_EFACE_east,
|
||||
STBVOX_EFACE_north,
|
||||
STBVOX_EFACE_west,
|
||||
STBVOX_EFACE_south,
|
||||
STBVOX_EFACE_up,
|
||||
STBVOX_EFACE_down,
|
||||
STBVOX_EFACE_east_up,
|
||||
STBVOX_EFACE_east_down,
|
||||
STBVF_e,
|
||||
STBVF_n,
|
||||
STBVF_w,
|
||||
STBVF_s,
|
||||
STBVF_u,
|
||||
STBVF_d,
|
||||
STBVF_eu,
|
||||
STBVF_ed,
|
||||
|
||||
STBVOX_EFACE_east_up_wall,
|
||||
STBVOX_EFACE_north_up_wall,
|
||||
STBVOX_EFACE_west_up_wall,
|
||||
STBVOX_EFACE_south_up_wall,
|
||||
STBVOX_EFACE_dummy_up_2,
|
||||
STBVOX_EFACE_dummy_down_2,
|
||||
STBVOX_EFACE_north_up,
|
||||
STBVOX_EFACE_north_down,
|
||||
STBVF_eu_wall,
|
||||
STBVF_nu_wall,
|
||||
STBVF_wu_wall,
|
||||
STBVF_su_wall,
|
||||
STBVF_ne_u,
|
||||
STBVF_ne_d,
|
||||
STBVF_nu,
|
||||
STBVF_nd,
|
||||
|
||||
STBVOX_EFACE_ne_up,
|
||||
STBVOX_EFACE_nw_up,
|
||||
STBVOX_EFACE_sw_up,
|
||||
STBVOX_EFACE_se_up,
|
||||
STBVOX_EFACE_dummy_up_3,
|
||||
STBVOX_EFACE_dummy_down_3,
|
||||
STBVOX_EFACE_west_up,
|
||||
STBVOX_EFACE_west_down,
|
||||
STBVF_ed_wall,
|
||||
STBVF_nd_wall,
|
||||
STBVF_wd_wall,
|
||||
STBVF_sd_wall,
|
||||
STBVF_nw_u,
|
||||
STBVF_nw_d,
|
||||
STBVF_wu,
|
||||
STBVF_wd,
|
||||
|
||||
STBVOX_EFACE_ne_down,
|
||||
STBVOX_EFACE_nw_down,
|
||||
STBVOX_EFACE_sw_down,
|
||||
STBVOX_EFACE_se_down,
|
||||
STBVOX_EFACE_dummy_up_4,
|
||||
STBVOX_EFACE_dummy_down_4,
|
||||
STBVOX_EFACE_south_up,
|
||||
STBVOX_EFACE_south_down,
|
||||
STBVF_ne_u_cross,
|
||||
STBVF_nw_u_cross,
|
||||
STBVF_sw_u_cross,
|
||||
STBVF_se_u_cross,
|
||||
STBVF_sw_u,
|
||||
STBVF_sw_d,
|
||||
STBVF_su,
|
||||
STBVF_sd,
|
||||
|
||||
// @TODO either we need more than 5 bits to encode the normal to fit these, or we can replace 'dummy' above with them but need to use full-size texgen table
|
||||
// so for now we just texture them with the wrong projection
|
||||
STBVOX_EFACE_east_down_wall = STBVOX_EFACE_east_down,
|
||||
STBVOX_EFACE_north_down_wall = STBVOX_EFACE_north_down,
|
||||
STBVOX_EFACE_west_down_wall = STBVOX_EFACE_west_down,
|
||||
STBVOX_EFACE_south_down_wall = STBVOX_EFACE_south_down,
|
||||
// @TODO we need more than 5 bits to encode the normal to fit the following
|
||||
// so for now we use the right projection but the wrong normal
|
||||
STBVF_se_u = STBVF_su,
|
||||
STBVF_se_d = STBVF_sd,
|
||||
|
||||
STBVF_count,
|
||||
};
|
||||
|
||||
// get opposite-facing normal & texgen for opposite face, used to map up-facing vheight data to down-facing data
|
||||
static unsigned char stbvox_reverse_face[STBVF_count] =
|
||||
{
|
||||
STBVF_w, STBVF_s, STBVF_e, STBVF_n, STBVF_d , STBVF_u , STBVF_wd, STBVF_wu,
|
||||
0, 0, 0, 0, STBVF_sw_d, STBVF_sw_u, STBVF_sd, STBVF_su,
|
||||
0, 0, 0, 0, STBVF_se_d, STBVF_se_u, STBVF_ed, STBVF_eu,
|
||||
0, 0, 0, 0, STBVF_ne_d, STBVF_ne_d, STBVF_nd, STBVF_nu
|
||||
};
|
||||
|
||||
static float stbvox_default_texgen[2][32][3] =
|
||||
@ -638,26 +649,26 @@ static float stbvox_default_normals[32][3] =
|
||||
{ 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up
|
||||
{ -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up
|
||||
{ 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up
|
||||
{ 0,0,1 }, // up
|
||||
{ 0,0,-1 }, // down
|
||||
{ STBVOX_RSQRT3, STBVOX_RSQRT3, STBVOX_RSQRT3 }, // ne & up
|
||||
{ STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // ne & down
|
||||
{ 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up
|
||||
{ 0, STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // north & down
|
||||
|
||||
{ STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NE & up
|
||||
{ STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // east & down
|
||||
{ 0, STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // north & down
|
||||
{ -STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // west & down
|
||||
{ 0,-STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // south & down
|
||||
{ -STBVOX_RSQRT3, STBVOX_RSQRT3, STBVOX_RSQRT3 }, // NW & up
|
||||
{ -STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SW & up
|
||||
{ STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SE & up
|
||||
{ 0,0,1 }, // up
|
||||
{ 0,0,-1 }, // down
|
||||
{ -STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // NW & down
|
||||
{ -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up
|
||||
{ -STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // west & down
|
||||
|
||||
{ STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // NE & down
|
||||
{ -STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // NW & down
|
||||
{ -STBVOX_RSQRT3,-STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // SW & down
|
||||
{ STBVOX_RSQRT3,-STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // SE & down
|
||||
{ 0,0,1 }, // up
|
||||
{ 0,0,-1 }, // down
|
||||
{ STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NE & up crossed
|
||||
{ -STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NW & up crossed
|
||||
{ -STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SW & up crossed
|
||||
{ STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SE & up crossed
|
||||
{ -STBVOX_RSQRT3,-STBVOX_RSQRT3, STBVOX_RSQRT3 }, // SW & up
|
||||
{ -STBVOX_RSQRT3,-STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // SW & up
|
||||
{ 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up
|
||||
{ 0,-STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // south & down
|
||||
};
|
||||
@ -758,6 +769,9 @@ stbvox_tagged_string stbvox_vertex_program[] =
|
||||
// per-buffer data
|
||||
"uniform vec3 transform[3];\n"
|
||||
|
||||
// per-frame data
|
||||
"uniform vec4 camera_pos;\n" // 4th value is used for arbitrary hacking
|
||||
|
||||
// to simplify things, we avoid using more than 256 uniform vectors
|
||||
// in fragment shader to avoid possible 1024 component limit, so
|
||||
// we access this table in the fragment shader.
|
||||
@ -802,6 +816,10 @@ stbvox_tagged_string stbvox_vertex_program[] =
|
||||
" vnormal = normal_table[(facedata.w>>2) & 31u];\n"
|
||||
" objectspace_pos = offset * transform[0];\n" // object-to-world scale
|
||||
" vec3 position = objectspace_pos + transform[1];\n" // object-to-world translate
|
||||
#if 0 // normal debugging
|
||||
" if ((facedata.w & 28u) == 16u || (facedata.w & 28u) == 24u)\n"
|
||||
" position += vnormal.xyz * camera_pos.w;\n"
|
||||
#endif
|
||||
},
|
||||
{ STBVOX_TAG_NOT | STBVOX_TAG_gl_modelview,
|
||||
|
||||
@ -846,7 +864,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
|
||||
"uniform vec3 transform[3];\n"
|
||||
|
||||
// per-frame data
|
||||
"uniform vec3 camera_pos;\n"
|
||||
"uniform vec4 camera_pos;\n" // 4th value is used for arbitrary hacking
|
||||
|
||||
// probably constant data
|
||||
"uniform vec3 ambient[4];\n"
|
||||
@ -955,7 +973,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
|
||||
" amb_color *= amb_occ;\n"
|
||||
|
||||
" vec3 lit_color;\n"
|
||||
" vec3 lighting = compute_lighting(objectspace_pos + transform[1], normal) + amb_color * 0.25;\n"
|
||||
" vec3 lighting = compute_lighting(objectspace_pos + transform[1], normal) + amb_color;\n"
|
||||
" if (!emissive)\n"
|
||||
" lit_color = lighting * albedo;\n"
|
||||
" else\n"
|
||||
@ -967,7 +985,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
|
||||
|
||||
// smoothstep fog:
|
||||
#if 1
|
||||
" vec3 dist = objectspace_pos + (transform[1] - camera_pos);\n"
|
||||
" vec3 dist = objectspace_pos + (transform[1] - camera_pos.xyz);\n"
|
||||
" float f = sqrt(dot(dist,dist))/1320.0;\n"
|
||||
" f = clamp(f, 0.0, 1.0);\n"
|
||||
" f = 3.0*f*f - 2.0*f*f*f;\n" // smoothstep
|
||||
@ -985,7 +1003,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
|
||||
"{\n"
|
||||
" vec3 light_dir = light_source[0] - pos;\n"
|
||||
" float lambert = dot(light_dir, norm) / dot(light_dir, light_dir);\n"
|
||||
" return light_source[1] * clamp(lambert, 0.0, 1.0);\n"
|
||||
" return clamp(light_source[1] * clamp(lambert, 0.0, 1.0), 0.0, 1.0);\n"
|
||||
"}\n"
|
||||
},
|
||||
};
|
||||
@ -1052,7 +1070,7 @@ stbvox_uniform_info stbvox_uniforms[] =
|
||||
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 64, "texgen" , stbvox_default_texgen[0][0] , STBVOX_TAG_textured },
|
||||
|
||||
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 4, "ambient" , 0 , STBVOX_TAG_all },
|
||||
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 1, "camera_pos" , stbvox_dummy_transform[0] , STBVOX_TAG_all },
|
||||
{ STBVOX_UNIFORM_TYPE_vec4 , 12, 1, "camera_pos" , stbvox_dummy_transform[0] , STBVOX_TAG_all },
|
||||
};
|
||||
|
||||
stbvox_uniform_info *stbvox_get_uniform_info(stbvox_mesh_maker *mm, int uniform)
|
||||
@ -1458,31 +1476,54 @@ void stbvox_make_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int fac
|
||||
}
|
||||
}
|
||||
|
||||
static stbvox_face_up_normal_012[4][4][4];
|
||||
static stbvox_face_up_normal_013[4][4][4];
|
||||
static stbvox_face_up_normal_023[4][4][4];
|
||||
static stbvox_face_up_normal_123[4][4][4];
|
||||
|
||||
// render non-planar quads by splitting into two triangles, rendering each as a degenerate quad
|
||||
void stbvox_make_02_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face1, int face2, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh)
|
||||
void stbvox_make_12_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh, unsigned char *ht)
|
||||
{
|
||||
stbvox_mesh_vertex v[4];
|
||||
v[0] = face_coord[0];
|
||||
v[1] = face_coord[1];
|
||||
v[2] = face_coord[2];
|
||||
v[3] = face_coord[0];
|
||||
stbvox_make_mesh_for_face(mm, rot, face1, v_off, pos, vertbase, v, mesh, face1);
|
||||
v[1] = face_coord[2];
|
||||
v[2] = face_coord[3];
|
||||
stbvox_make_mesh_for_face(mm, rot, face2, v_off, pos, vertbase, v, mesh, face2);
|
||||
|
||||
unsigned char normal1 = stbvox_face_up_normal_012[ht[2]][ht[1]][ht[0]];
|
||||
unsigned char normal2 = stbvox_face_up_normal_123[ht[3]][ht[2]][ht[1]];
|
||||
|
||||
if (face == STBVOX_FACE_down) {
|
||||
normal1 = stbvox_reverse_face[normal1];
|
||||
normal2 = stbvox_reverse_face[normal2];
|
||||
}
|
||||
|
||||
void stbvox_make_13_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face1, int face2, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh)
|
||||
// the floor side face_coord is stored in order NW,NE,SE,SW, but ht[] is stored SW,SE,NW,NE
|
||||
v[0] = face_coord[2];
|
||||
v[1] = face_coord[3];
|
||||
v[2] = face_coord[0];
|
||||
v[3] = face_coord[2];
|
||||
stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal1);
|
||||
v[1] = face_coord[0];
|
||||
v[2] = face_coord[1];
|
||||
stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal2);
|
||||
}
|
||||
|
||||
void stbvox_make_03_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh, unsigned char *ht)
|
||||
{
|
||||
stbvox_mesh_vertex v[4];
|
||||
|
||||
unsigned char normal1 = stbvox_face_up_normal_013[ht[3]][ht[1]][ht[0]];
|
||||
unsigned char normal2 = stbvox_face_up_normal_023[ht[3]][ht[2]][ht[0]];
|
||||
|
||||
if (face == STBVOX_FACE_down) {
|
||||
normal1 = stbvox_reverse_face[normal1];
|
||||
normal2 = stbvox_reverse_face[normal2];
|
||||
}
|
||||
v[0] = face_coord[1];
|
||||
v[1] = face_coord[2];
|
||||
v[2] = face_coord[3];
|
||||
v[3] = face_coord[1];
|
||||
stbvox_make_mesh_for_face(mm, rot, face1, v_off, pos, vertbase, v, mesh, face1);
|
||||
stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal1);
|
||||
v[1] = face_coord[3];
|
||||
v[2] = face_coord[0];
|
||||
stbvox_make_mesh_for_face(mm, rot, face2, v_off, pos, vertbase, v, mesh, face2);
|
||||
stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal2); // this one is correct!
|
||||
}
|
||||
|
||||
// simple case for mesh generation: we have only solid and empty blocks
|
||||
@ -1624,18 +1665,18 @@ static unsigned char stbvox_facetype[STBVOX_GEOM_count][6] =
|
||||
// @TODO this could be done with math given the current arrangement of the enum, but let's not require it
|
||||
static unsigned char stbvox_floor_slope_for_rot[4] =
|
||||
{
|
||||
STBVOX_EFACE_south_up,
|
||||
STBVOX_EFACE_west_up, // @TODO: why is this reversed from what it should be? this is a north-is-up face, so slope should be south&up
|
||||
STBVOX_EFACE_north_up,
|
||||
STBVOX_EFACE_east_up,
|
||||
STBVF_su,
|
||||
STBVF_wu, // @TODO: why is this reversed from what it should be? this is a north-is-up face, so slope should be south&up
|
||||
STBVF_nu,
|
||||
STBVF_eu,
|
||||
};
|
||||
|
||||
static unsigned char stbvox_ceil_slope_for_rot[4] =
|
||||
{
|
||||
STBVOX_EFACE_south_down,
|
||||
STBVOX_EFACE_east_down,
|
||||
STBVOX_EFACE_north_down,
|
||||
STBVOX_EFACE_west_down,
|
||||
STBVF_sd,
|
||||
STBVF_ed,
|
||||
STBVF_nd,
|
||||
STBVF_wd,
|
||||
};
|
||||
|
||||
// this table indicates whether, for each pair of types above, a face is visible.
|
||||
@ -1693,6 +1734,233 @@ static unsigned char stbvox_rotate_vertex[8][4] =
|
||||
{ 7,6,4,5 }, // zyx=111
|
||||
};
|
||||
|
||||
|
||||
#ifdef STBVOX_OPTIMIZED_VHEIGHT
|
||||
// optimized vheight generates a single normal over the entire face, even if it's not planar
|
||||
static stbvox_optimized_face_up_normal[4][4][4][4] =
|
||||
{
|
||||
{
|
||||
{
|
||||
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
|
||||
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
|
||||
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
|
||||
},{
|
||||
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
|
||||
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
},
|
||||
},{
|
||||
{
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
|
||||
},
|
||||
},{
|
||||
{
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
|
||||
},
|
||||
},{
|
||||
{
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_wu , STBVF_nw_u, },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
|
||||
},{
|
||||
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_wu , STBVF_nw_u, },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
|
||||
},
|
||||
},
|
||||
};
|
||||
#else
|
||||
// which normal to use for a given vheight that's planar
|
||||
// @TODO: this table was constructed by hand and may have bugs
|
||||
// nw se sw
|
||||
static stbvox_planar_face_up_normal[4][4][4] =
|
||||
{
|
||||
{ // sw,se,nw,ne
|
||||
{ STBVF_u , 0 , 0 , 0 }, // 0,0,0,0; 1,0,0,-1; 2,0,0,-2; 3,0,0,-3;
|
||||
{ STBVF_u , STBVF_u , 0 , 0 }, // 0,1,0,1; 1,1,0, 0; 2,1,0,-1; 3,1,0,-2;
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nu , 0 }, // 0,2,0,2; 1,2,0, 1; 2,2,0, 0; 3,2,0,-1;
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nu }, // 0,3,0,3; 1,3,0, 2; 2,3,0, 1; 3,3,0, 0;
|
||||
},{
|
||||
{ STBVF_u , STBVF_u , 0 , 0 }, // 0,0,1,1; 1,0,1, 0; 2,0,1,-1; 3,0,1,-2;
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, 0 }, // 0,1,1,2; 1,1,1, 1; 2,1,1, 0; 3,1,1,-1;
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_u , STBVF_ne_u }, // 0,2,1,3; 1,2,1, 2; 2,2,1, 1; 3,2,1, 0;
|
||||
{ 0 , STBVF_w , STBVF_nw_u, STBVF_nu }, // 0,3,1,4; 1,3,1, 3; 2,3,1, 2; 3,3,1, 1;
|
||||
},{
|
||||
{ STBVF_su , STBVF_se_u, STBVF_eu , 0 }, // 0,0,2,2; 1,0,2, 1; 2,0,2, 0; 3,0,2,-1;
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_u , STBVF_ne_u }, // 0,1,2,3; 1,1,2, 2; 2,1,2, 1; 3,1,2, 0;
|
||||
{ 0 , STBVF_sw_u, STBVF_u , STBVF_ne_u }, // 0,2,2,4; 1,2,2, 3; 2,2,2, 2; 3,2,2, 1;
|
||||
{ 0 , 0 , STBVF_u , STBVF_u }, // 0,3,2,5; 1,3,2, 4; 2,3,2, 3; 3,3,2, 2;
|
||||
},{
|
||||
{ STBVF_su , STBVF_se_u, STBVF_se_u, STBVF_eu }, // 0,0,3,3; 1,0,3, 2; 2,0,3, 1; 3,0,3, 0;
|
||||
{ 0 , STBVF_su , STBVF_se_u, STBVF_eu }, // 0,1,3,4; 1,1,3, 3; 2,1,3, 2; 3,1,3, 1;
|
||||
{ 0 , 0 , STBVF_u , STBVF_u }, // 0,2,3,5; 1,2,3, 4; 2,2,3, 3; 3,2,3, 2;
|
||||
{ 0 , 0 , 0 , STBVF_u }, // 0,3,3,6; 1,3,3, 5; 2,3,3, 4; 3,3,3, 3;
|
||||
}
|
||||
};
|
||||
|
||||
// these tables were constructed automatically using a variant of the code
|
||||
// below; however, they seem wrong, so who knows
|
||||
static stbvox_face_up_normal_012[4][4][4] =
|
||||
{
|
||||
{
|
||||
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_nu , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_nu , STBVF_ne_u, },
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
|
||||
{ STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_ne_u, },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
|
||||
}
|
||||
};
|
||||
|
||||
static stbvox_face_up_normal_013[4][4][4] =
|
||||
{
|
||||
{
|
||||
{ STBVF_u , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_nw_u, STBVF_nu , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_wu , STBVF_u , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
|
||||
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_u , STBVF_eu , },
|
||||
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
|
||||
},{
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
|
||||
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_su , STBVF_eu , },
|
||||
{ STBVF_wu , STBVF_wu , STBVF_wu , STBVF_u , },
|
||||
}
|
||||
};
|
||||
|
||||
static stbvox_face_up_normal_023[4][4][4] =
|
||||
{
|
||||
{
|
||||
{ STBVF_u , STBVF_nu , STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
|
||||
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
|
||||
},{
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
|
||||
{ STBVF_su , STBVF_u , STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
},{
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
|
||||
{ STBVF_su , STBVF_su , STBVF_u , STBVF_nu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
|
||||
},{
|
||||
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_u , },
|
||||
}
|
||||
};
|
||||
|
||||
static stbvox_face_up_normal_123[4][4][4] =
|
||||
{
|
||||
{
|
||||
{ STBVF_u , STBVF_nu , STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
|
||||
},{
|
||||
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
|
||||
{ STBVF_su , STBVF_u , STBVF_nu , STBVF_nu , },
|
||||
{ STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
|
||||
{ STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
|
||||
},{
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
|
||||
{ STBVF_su , STBVF_su , STBVF_u , STBVF_nu , },
|
||||
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
|
||||
},{
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
|
||||
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
|
||||
{ STBVF_su , STBVF_su , STBVF_su , STBVF_u , },
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off)
|
||||
{
|
||||
int ns_off = mm->y_stride_in_bytes;
|
||||
@ -1911,7 +2179,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
||||
if (visible_faces & (1 << STBVOX_FACE_west))
|
||||
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_west , v_off, pos, basevert, vmesh[STBVOX_FACE_west ], mesh, STBVOX_FACE_west);
|
||||
}
|
||||
if (geo >= STBVOX_GEOM_floor_vheight_02) {
|
||||
if (geo >= STBVOX_GEOM_floor_vheight_03) {
|
||||
// this case can also be generated with regular block gen with special vmesh,
|
||||
// except:
|
||||
// if we want to generate middle diagonal for 'weird' blocks
|
||||
@ -1951,7 +2219,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
||||
// our visible_faces test was wrong
|
||||
extreme = (ht[0] == 3 || ht[1] == 3 || ht[2] == 3 || ht[3] == 3);
|
||||
|
||||
if (geo >= STBVOX_GEOM_ceil_vheight_02) {
|
||||
if (geo >= STBVOX_GEOM_ceil_vheight_03) {
|
||||
cube[0] = stbvox_vertex_p(0,0,ht[0],0,0);
|
||||
cube[1] = stbvox_vertex_p(0,0,ht[1],0,0);
|
||||
cube[2] = stbvox_vertex_p(0,0,ht[2],0,0);
|
||||
@ -1992,30 +2260,44 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
||||
|
||||
// @TODO generate split faces
|
||||
if (visible_faces & (1 << STBVOX_FACE_up)) {
|
||||
#ifndef STBVOX_OPTIMIZED_VHEIGHT
|
||||
// check if it's planar
|
||||
if (geo < STBVOX_GEOM_ceil_vheight_02 && cube[5] + cube[6] != cube[4] + cube[7]) {
|
||||
// not planar, split along diagonal and make degenerate
|
||||
if (geo == STBVOX_GEOM_floor_vheight_02)
|
||||
stbvox_make_02_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh);
|
||||
else
|
||||
stbvox_make_13_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh);
|
||||
} else
|
||||
#endif
|
||||
if (geo >= STBVOX_GEOM_ceil_vheight_03)
|
||||
// flat
|
||||
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, STBVOX_FACE_up);
|
||||
else {
|
||||
#ifndef STBVOX_OPTIMIZED_VHEIGHT
|
||||
// check if it's non-planar
|
||||
if (cube[5] + cube[6] != cube[4] + cube[7]) {
|
||||
// not planar, split along diagonal and make degenerate quads
|
||||
if (geo == STBVOX_GEOM_floor_vheight_03)
|
||||
stbvox_make_03_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, ht);
|
||||
else
|
||||
stbvox_make_12_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, ht);
|
||||
} else
|
||||
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, stbvox_planar_face_up_normal[ht[2]][ht[1]][ht[0]]);
|
||||
#else
|
||||
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, stbvox_optimized_face_up_normal[ht[3]][ht[2]][ht[1]][ht[0]]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (visible_faces & (1 << STBVOX_FACE_down)) {
|
||||
#ifndef STBVOX_OPTIMIZED_VHEIGHT
|
||||
// check if it's planar
|
||||
if (geo >= STBVOX_GEOM_ceil_vheight_02 && cube[1] + cube[2] != cube[0] + cube[3]) {
|
||||
// not planar, split along diagonal and make degenerate
|
||||
if (geo == STBVOX_GEOM_ceil_vheight_02)
|
||||
stbvox_make_02_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh);
|
||||
else
|
||||
stbvox_make_13_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh);
|
||||
} else
|
||||
#endif
|
||||
if (geo < STBVOX_GEOM_ceil_vheight_03)
|
||||
// flat
|
||||
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, STBVOX_FACE_down);
|
||||
else {
|
||||
#ifndef STBVOX_OPTIMIZED_VHEIGHT
|
||||
// check if it's non-planar
|
||||
if (cube[1] + cube[2] != cube[0] + cube[3]) {
|
||||
// not planar, split along diagonal and make degenerate quads
|
||||
if (geo == STBVOX_GEOM_ceil_vheight_03)
|
||||
stbvox_make_03_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, ht);
|
||||
else
|
||||
stbvox_make_12_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, ht);
|
||||
} else
|
||||
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, stbvox_reverse_face[stbvox_planar_face_up_normal[ht[2]][ht[1]][ht[0]]]);
|
||||
#else
|
||||
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, stbvox_reverse_face[stbvox_optimized_face_up_normal[ht[3]][ht[2]][ht[1]][ht[0]]]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (mm->input.rotate) {
|
||||
@ -2067,10 +2349,10 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
||||
}
|
||||
rot.facerot = 0;
|
||||
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_north], mesh, STBVOX_EFACE_ne_up);
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh, STBVOX_EFACE_sw_up);
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_east , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_east ], mesh, STBVOX_EFACE_se_up);
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_west , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_west ], mesh, STBVOX_EFACE_nw_up);
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_north], mesh, STBVF_ne_u_cross);
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh, STBVF_sw_u_cross);
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_east , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_east ], mesh, STBVF_se_u_cross);
|
||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_west , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_west ], mesh, STBVF_nw_u_cross);
|
||||
}
|
||||
|
||||
|
||||
@ -2357,4 +2639,57 @@ void stbvox_config_set_z_precision(stbvox_mesh_maker *mm, int z_fractional_bits)
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// offline computation
|
||||
//
|
||||
|
||||
#if 0
|
||||
// compute optimized vheight table
|
||||
static char *normal_names[32] =
|
||||
{
|
||||
0,0,0,0,"u ",0, "eu ",0,
|
||||
0,0,0,0,"ne_u",0, "nu ",0,
|
||||
0,0,0,0,"nw_u",0, "wu ",0,
|
||||
0,0,0,0,"sw_u",0, "su ",0,
|
||||
};
|
||||
|
||||
static char *find_best_normal(float x, float y, float z)
|
||||
{
|
||||
int best_slot = 4;
|
||||
float best_dot = 0;
|
||||
int i;
|
||||
for (i=0; i < 32; ++i) {
|
||||
if (normal_names[i]) {
|
||||
float dot = x * stbvox_default_normals[i].x + y * stbvox_default_normals[i].y + z * stbvox_default_normals[i].z;
|
||||
if (dot > best_dot) {
|
||||
best_dot = dot;
|
||||
best_slot = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return normal_names[best_slot];
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int sw,se,nw,ne;
|
||||
for (ne=0; ne < 4; ++ne) {
|
||||
for (nw=0; nw < 4; ++nw) {
|
||||
for (se=0; se < 4; ++se) {
|
||||
printf(" { ");
|
||||
for (sw=0; sw < 4; ++sw) {
|
||||
float x = (float) (nw + sw - ne - se);
|
||||
float y = (float) (sw + se - nw - ne);
|
||||
float z = 2;
|
||||
printf("STBVF_%s, ", find_best_normal(x,y,z));
|
||||
}
|
||||
printf("},\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // STB_VOXEL_RENDER_IMPLEMENTATION
|
||||
|
@ -13,8 +13,11 @@
|
||||
#include "sdl_thread.h"
|
||||
#include <math.h>
|
||||
|
||||
#define STB_VOXEL_RENDER_IMPLEMENTATION
|
||||
//#define VHEIGHT_TEST
|
||||
//#define STBVOX_OPTIMIZED_VHEIGHT
|
||||
|
||||
#define STBVOX_ROTATION_IN_LIGHTING
|
||||
#define STB_VOXEL_RENDER_IMPLEMENTATION
|
||||
#include "stb_voxel_render.h"
|
||||
|
||||
extern void ods(char *fmt, ...);
|
||||
@ -585,7 +588,9 @@ void build_chunk(int chunk_x, int chunk_y, fast_chunk *fc_table[4][4], raw_mesh
|
||||
int a,b,z;
|
||||
stbvox_input_description *map;
|
||||
|
||||
//unsigned char vheight[34][34][18];
|
||||
#ifdef VHEIGHT_TEST
|
||||
unsigned char vheight[34][34][18];
|
||||
#endif
|
||||
|
||||
assert((chunk_x & 1) == 0);
|
||||
assert((chunk_y & 1) == 0);
|
||||
@ -632,7 +637,7 @@ void build_chunk(int chunk_x, int chunk_y, fast_chunk *fc_table[4][4], raw_mesh
|
||||
map->blocktype = &rm->sv_blocktype[1][1][1-z]; // specify location of 0,0,0 so that accessing z0..z1 gets right data
|
||||
map->lighting = &rm->sv_lighting[1][1][1-z];
|
||||
|
||||
#if 0
|
||||
#ifdef VHEIGHT_TEST
|
||||
// hacky test of vheight
|
||||
for (a=0; a < 34; ++a) {
|
||||
for (b=0; b < 34; ++b) {
|
||||
@ -640,8 +645,12 @@ void build_chunk(int chunk_x, int chunk_y, fast_chunk *fc_table[4][4], raw_mesh
|
||||
for (c=0; c < 17; ++c) {
|
||||
if (rm->sv_blocktype[a][b][c] != 0 && rm->sv_blocktype[a][b][c+1] == 0) {
|
||||
// topmost block
|
||||
rm->sv_blocktype[a][b][c] = 168;
|
||||
vheight[a][b][c] = rand() & 255;
|
||||
rm->sv_blocktype[a][b][c] = 168;
|
||||
} else if (c > 0 && rm->sv_blocktype[a][b][c] != 0 && rm->sv_blocktype[a][b][c-1] == 0) {
|
||||
// bottommost block
|
||||
vheight[a][b][c] = ((rand() % 3) << 6) + ((rand() % 3) << 4) + ((rand() % 3) << 2) + (rand() % 3);
|
||||
rm->sv_blocktype[a][b][c] = 169;
|
||||
}
|
||||
}
|
||||
vheight[a][b][c] = STBVOX_MAKE_VHEIGHT(2,2,2,2); // flat top
|
||||
@ -792,7 +801,7 @@ void mesh_init(void)
|
||||
minecraft_color_for_blocktype[11][i] = 63; // emissive
|
||||
}
|
||||
|
||||
#if 0 // vheight test
|
||||
#ifdef VHEIGHT_TEST
|
||||
effective_blocktype[168] = 168;
|
||||
minecraft_tex1_for_blocktype[168][0] = 1;
|
||||
minecraft_tex1_for_blocktype[168][1] = 1;
|
||||
@ -800,7 +809,15 @@ void mesh_init(void)
|
||||
minecraft_tex1_for_blocktype[168][3] = 1;
|
||||
minecraft_tex1_for_blocktype[168][4] = 1;
|
||||
minecraft_tex1_for_blocktype[168][5] = 1;
|
||||
minecraft_geom_for_blocktype[168] = STBVOX_GEOM_floor_vheight_02;
|
||||
minecraft_geom_for_blocktype[168] = STBVOX_GEOM_floor_vheight_12;
|
||||
effective_blocktype[169] = 169;
|
||||
minecraft_tex1_for_blocktype[169][0] = 1;
|
||||
minecraft_tex1_for_blocktype[169][1] = 1;
|
||||
minecraft_tex1_for_blocktype[169][2] = 1;
|
||||
minecraft_tex1_for_blocktype[169][3] = 1;
|
||||
minecraft_tex1_for_blocktype[169][4] = 1;
|
||||
minecraft_tex1_for_blocktype[169][5] = 1;
|
||||
minecraft_geom_for_blocktype[169] = STBVOX_GEOM_ceil_vheight_03;
|
||||
#endif
|
||||
|
||||
remap[53] = 1;
|
||||
|
@ -184,9 +184,12 @@ GLint uniform_loc[16];
|
||||
float table3[128][3];
|
||||
GLint tablei[2];
|
||||
|
||||
float step=0;
|
||||
|
||||
void setup_uniforms(float pos[3])
|
||||
{
|
||||
int i,j;
|
||||
step += 1.0f/60.0f;
|
||||
for (i=0; i < STBVOX_UNIFORM_count; ++i) {
|
||||
stbvox_uniform_info *ui = stbvox_get_uniform_info(&g_mesh_maker, i);
|
||||
uniform_loc[i] = -1;
|
||||
@ -224,9 +227,11 @@ void setup_uniforms(float pos[3])
|
||||
table3[0][0] = pos[0];
|
||||
table3[0][1] = pos[1];
|
||||
table3[0][2] = pos[2];
|
||||
table3[0][3] = stb_max(0,(float)sin(step*2)*0.125f);
|
||||
break;
|
||||
|
||||
case STBVOX_UNIFORM_ambient: {
|
||||
float bright = 0.75;
|
||||
float amb[3][3];
|
||||
|
||||
// ambient direction is sky-colored upwards
|
||||
@ -245,8 +250,8 @@ void setup_uniforms(float pos[3])
|
||||
// amb[1] + (amb[2] - amb[1]) * dot/2 + (amb[2]-amb[1])/2
|
||||
|
||||
for (j=0; j < 3; ++j) {
|
||||
table3[1][j] = (amb[2][j] - amb[1][j])/2;
|
||||
table3[2][j] = (amb[1][j] + amb[2][j])/2;
|
||||
table3[1][j] = (amb[2][j] - amb[1][j])/2 * bright;
|
||||
table3[2][j] = (amb[1][j] + amb[2][j])/2 * bright;
|
||||
}
|
||||
|
||||
// fog color
|
||||
@ -783,7 +788,7 @@ void render_caves(float campos[3])
|
||||
|
||||
{
|
||||
float lighting[2][3] = { { campos[0],campos[1],campos[2] }, { 0.75,0.75,0.65f } };
|
||||
float bright = 15;
|
||||
float bright = 8;
|
||||
lighting[1][0] *= bright;
|
||||
lighting[1][1] *= bright;
|
||||
lighting[1][2] *= bright;
|
||||
|
Loading…
Reference in New Issue
Block a user