example/q3bsp: only draw visible leaves
This commit is contained in:
parent
f34e6cf4ef
commit
8c03d19520
@ -84,7 +84,7 @@ using mat4x4 = mat<4, 4, float>;
|
||||
|
||||
#define _fsrra(n) (1.0f / (__builtin_sqrtf(n)))
|
||||
|
||||
static vec3 sphere_position = {890, 480, 400};
|
||||
static vec3 sphere_position = {890, 480, 450};
|
||||
|
||||
static ft0::data_transfer::data_format data[4];
|
||||
|
||||
@ -334,36 +334,33 @@ float light_intensity(vec3 light_vec, vec3 n)
|
||||
|
||||
static vec3 light_vec = {20, -20, -20};
|
||||
|
||||
void transfer_faces(uint8_t * buf, q3bsp_header_t * header, ta_parameter_writer& writer)
|
||||
static inline void transfer_face(ta_parameter_writer& writer, q3bsp_face_t * face, int * last_texture)
|
||||
{
|
||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
||||
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
|
||||
|
||||
q3bsp_direntry * ve = &header->direntries[LUMP_VERTEXES];
|
||||
q3bsp_direntry * me = &header->direntries[LUMP_MESHVERTS];
|
||||
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
|
||||
|
||||
q3bsp_vertex_t * vert = reinterpret_cast<q3bsp_vertex_t *>(&buf[ve->offset]);
|
||||
|
||||
q3bsp_direntry * me = &header->direntries[LUMP_MESHVERTS];
|
||||
q3bsp_meshvert_t * meshvert = reinterpret_cast<q3bsp_meshvert_t *>(&buf[me->offset]);
|
||||
q3bsp_face_t * face = reinterpret_cast<q3bsp_face_t *>(&buf[fe->offset]);
|
||||
|
||||
int face_count = fe->length / (sizeof (struct q3bsp_face));
|
||||
|
||||
int textures_length = (sizeof (textures)) / (sizeof (textures[0]));
|
||||
int last_texture = -1;
|
||||
|
||||
for (int i = 0; i < face_count; i++) {
|
||||
int meshvert_ix = face[i].meshvert;
|
||||
int meshvert_ix = face->meshvert;
|
||||
q3bsp_meshvert_t * mv = &meshvert[meshvert_ix];
|
||||
|
||||
int triangles = face[i].n_meshverts / 3;
|
||||
int triangles = face->n_meshverts / 3;
|
||||
|
||||
int textures_length = (sizeof (textures)) / (sizeof (textures[0]));
|
||||
|
||||
bool has_texture = 1 &&
|
||||
(face[i].texture >= 0) &&
|
||||
(face[i].texture < textures_length) &&
|
||||
(textures[face[i].texture].size != 0);
|
||||
(face->texture >= 0) &&
|
||||
(face->texture < textures_length) &&
|
||||
(textures[face->texture].size != 0);
|
||||
|
||||
if (face[i].texture != last_texture) {
|
||||
last_texture = face[i].texture;
|
||||
if (face->texture != *last_texture) {
|
||||
*last_texture = face->texture;
|
||||
if (has_texture) {
|
||||
global_texture(writer, face[i].texture);
|
||||
global_texture(writer, face->texture);
|
||||
} else {
|
||||
//global_polygon_type_1(writer, 0, 0, 0);
|
||||
}
|
||||
@ -371,9 +368,9 @@ void transfer_faces(uint8_t * buf, q3bsp_header_t * header, ta_parameter_writer&
|
||||
|
||||
for (int j = 0; j < triangles; j++) {
|
||||
|
||||
int aix = mv[j * 3 + 0].offset + face[i].vertex;
|
||||
int bix = mv[j * 3 + 1].offset + face[i].vertex;
|
||||
int cix = mv[j * 3 + 2].offset + face[i].vertex;
|
||||
int aix = mv[j * 3 + 0].offset + face->vertex;
|
||||
int bix = mv[j * 3 + 1].offset + face->vertex;
|
||||
int cix = mv[j * 3 + 2].offset + face->vertex;
|
||||
|
||||
vec3 ap = vertex_cache[aix].position;
|
||||
vec3 bp = vertex_cache[bix].position;
|
||||
@ -395,7 +392,7 @@ void transfer_faces(uint8_t * buf, q3bsp_header_t * header, ta_parameter_writer&
|
||||
|
||||
|
||||
if (has_texture) {
|
||||
float v_mul = textures[face[i].texture].v_mul;
|
||||
float v_mul = textures[face->texture].v_mul;
|
||||
vec2 at = {vert[aix].texcoord[0], vert[aix].texcoord[1] * v_mul};
|
||||
vec2 bt = {vert[bix].texcoord[0], vert[bix].texcoord[1] * v_mul};
|
||||
vec2 ct = {vert[cix].texcoord[0], vert[cix].texcoord[1] * v_mul};
|
||||
@ -425,6 +422,22 @@ void transfer_faces(uint8_t * buf, q3bsp_header_t * header, ta_parameter_writer&
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void transfer_faces(ta_parameter_writer& writer)
|
||||
{
|
||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
||||
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
|
||||
|
||||
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
|
||||
q3bsp_face_t * faces = reinterpret_cast<q3bsp_face_t *>(&buf[fe->offset]);
|
||||
|
||||
int face_count = fe->length / (sizeof (struct q3bsp_face));
|
||||
|
||||
int last_texture = -1;
|
||||
|
||||
for (int i = 0; i < face_count; i++) {
|
||||
transfer_face(writer, &faces[i], &last_texture);
|
||||
}
|
||||
}
|
||||
|
||||
void transfer_icosphere(ta_parameter_writer& writer, mat4x4& screen_trans)
|
||||
@ -736,6 +749,128 @@ void render_bounding_boxes(ta_parameter_writer& writer, mat4x4& trans)
|
||||
}
|
||||
}
|
||||
|
||||
bool vec3_in_bb(vec3 v, int mins[3], int maxs[3])
|
||||
{
|
||||
return
|
||||
v.x >= mins[0] &&
|
||||
v.y >= mins[1] &&
|
||||
v.z >= mins[2] &&
|
||||
v.x <= maxs[0] &&
|
||||
v.y <= maxs[1] &&
|
||||
v.z <= maxs[2];
|
||||
}
|
||||
|
||||
void render_leaf_faces(ta_parameter_writer& writer, mat4x4& trans, q3bsp_leaf_t * leaf)
|
||||
{
|
||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
||||
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
|
||||
|
||||
//int leafface First leafface for leaf.
|
||||
//int n_leaffaces Number of leaffaces for leaf.
|
||||
|
||||
q3bsp_direntry * fe = &header->direntries[LUMP_FACES];
|
||||
q3bsp_face_t * faces = reinterpret_cast<q3bsp_face_t *>(&buf[fe->offset]);
|
||||
|
||||
q3bsp_direntry * lef = &header->direntries[LUMP_LEAFFACES];
|
||||
q3bsp_leafface_t * leaffaces = reinterpret_cast<q3bsp_leafface_t *>(&buf[lef->offset]);
|
||||
|
||||
q3bsp_leafface_t * lf = &leaffaces[leaf->leafface];
|
||||
|
||||
int last_texture = -1;
|
||||
|
||||
for (int i = 0; i < leaf->n_leaffaces; i++) {
|
||||
int face_ix = lf[i].face;
|
||||
transfer_face(writer, &faces[face_ix], &last_texture);
|
||||
}
|
||||
}
|
||||
|
||||
void render_sphere_bounding_box(ta_parameter_writer& writer, mat4x4& trans)
|
||||
{
|
||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
||||
q3bsp_header_t * header = reinterpret_cast<q3bsp_header_t *>(buf);
|
||||
|
||||
q3bsp_direntry * le = &header->direntries[LUMP_LEAFS];
|
||||
q3bsp_leaf_t * leafs = reinterpret_cast<q3bsp_leaf_t *>(&buf[le->offset]);
|
||||
|
||||
q3bsp_direntry * ne = &header->direntries[LUMP_NODES];
|
||||
q3bsp_node_t * nodes = reinterpret_cast<q3bsp_node_t *>(&buf[ne->offset]);
|
||||
q3bsp_node_t * root = &nodes[0];
|
||||
|
||||
q3bsp_direntry * ve = &header->direntries[LUMP_VISDATA];
|
||||
q3bsp_visdata_t * visdata = reinterpret_cast<q3bsp_visdata_t *>(&buf[ve->offset]);
|
||||
|
||||
q3bsp_leaf_t * bb_leaf = NULL;
|
||||
|
||||
while (true) {
|
||||
bool a_inside;
|
||||
bool b_inside;
|
||||
q3bsp_node_t * new_root = NULL;
|
||||
if (root->children[0] >= 0) {
|
||||
q3bsp_node_t * node = &nodes[root->children[0]];
|
||||
a_inside = vec3_in_bb(sphere_position, node->mins, node->maxs);
|
||||
if (a_inside) {
|
||||
new_root = node;
|
||||
}
|
||||
} else {
|
||||
int leaf_ix = -(root->children[0] + 1);
|
||||
q3bsp_leaf_t * leaf = &leafs[leaf_ix];
|
||||
a_inside = vec3_in_bb(sphere_position, leaf->mins, leaf->maxs);
|
||||
if (a_inside) {
|
||||
bb_leaf = leaf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (root->children[1] >= 0) {
|
||||
q3bsp_node_t * node = &nodes[root->children[1]];
|
||||
b_inside = vec3_in_bb(sphere_position, node->mins, node->maxs);
|
||||
if (b_inside) {
|
||||
new_root = node;
|
||||
}
|
||||
} else {
|
||||
int leaf_ix = -(root->children[1] + 1);
|
||||
q3bsp_leaf_t * leaf = &leafs[leaf_ix];
|
||||
b_inside = vec3_in_bb(sphere_position, leaf->mins, leaf->maxs);
|
||||
if (b_inside) {
|
||||
bb_leaf = leaf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (!(a_inside ^ b_inside)) {
|
||||
printf("root_ix %d\n", root - nodes);
|
||||
}
|
||||
*/
|
||||
|
||||
assert(a_inside || b_inside);
|
||||
//assert(new_root != NULL);
|
||||
root = new_root;
|
||||
}
|
||||
|
||||
assert(bb_leaf != NULL);
|
||||
uint32_t color = 0x8000ff16;
|
||||
//render_bounding_box_mm(writer, trans, bb_leaf->maxs, bb_leaf->mins, color);
|
||||
render_leaf_faces(writer, trans, bb_leaf);
|
||||
|
||||
int leaf_count = le->length / (sizeof (struct q3bsp_leaf));
|
||||
for (int i = 0; i < leaf_count; i++) {
|
||||
q3bsp_leaf_t * leaf = &leafs[i];
|
||||
|
||||
// Cluster x is visible from cluster y if the (1 << y % 8) bit of vecs[x * sz_vecs + y / 8] is set.
|
||||
if (leaf->mins[2] > 450 && leaf->maxs[2] > 450)
|
||||
continue;
|
||||
|
||||
int y = bb_leaf->cluster;
|
||||
int x = leaf->cluster;
|
||||
bool visible = (visdata->vecs[x * visdata->sz_vecs + y / 8] & (1 << (y % 8))) != 0;
|
||||
if (visible) {
|
||||
uint32_t color = 0x40ff00e6;
|
||||
//render_bounding_box_mm(writer, trans, leaf->maxs, leaf->mins, color);
|
||||
render_leaf_faces(writer, trans, leaf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans)
|
||||
{
|
||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
||||
@ -746,13 +881,15 @@ void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans)
|
||||
q3bsp_direntry * ve = &header->direntries[LUMP_VERTEXES];
|
||||
transform_vertices(&buf[ve->offset], ve->length, trans);
|
||||
|
||||
transfer_faces(buf, header, writer);
|
||||
//transfer_faces(writer);
|
||||
transfer_icosphere(writer, trans);
|
||||
|
||||
render_matrix(writer, trans);
|
||||
render_leaf_ix(writer);
|
||||
render_sphere_position(writer);
|
||||
|
||||
render_sphere_bounding_box(writer, trans);
|
||||
|
||||
writer.append<ta_global_parameter::end_of_list>() =
|
||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
|
||||
@ -764,13 +901,14 @@ void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans)
|
||||
{0, 0, 0},
|
||||
0);
|
||||
|
||||
root_ix = 1552;
|
||||
//render_bounding_boxes(writer, trans);
|
||||
|
||||
writer.append<ta_global_parameter::end_of_list>() =
|
||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
}
|
||||
|
||||
uint8_t __attribute__((aligned(32))) ta_parameter_buf[1024 * 1024];
|
||||
uint8_t __attribute__((aligned(32))) ta_parameter_buf[1024 * 1024 * 2];
|
||||
|
||||
constexpr inline mat4x4 rotate_x(float t)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user