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)))
|
#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];
|
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};
|
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 * 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_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_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 meshvert_ix = face->meshvert;
|
||||||
|
|
||||||
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;
|
|
||||||
q3bsp_meshvert_t * mv = &meshvert[meshvert_ix];
|
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 &&
|
bool has_texture = 1 &&
|
||||||
(face[i].texture >= 0) &&
|
(face->texture >= 0) &&
|
||||||
(face[i].texture < textures_length) &&
|
(face->texture < textures_length) &&
|
||||||
(textures[face[i].texture].size != 0);
|
(textures[face->texture].size != 0);
|
||||||
|
|
||||||
if (face[i].texture != last_texture) {
|
if (face->texture != *last_texture) {
|
||||||
last_texture = face[i].texture;
|
*last_texture = face->texture;
|
||||||
if (has_texture) {
|
if (has_texture) {
|
||||||
global_texture(writer, face[i].texture);
|
global_texture(writer, face->texture);
|
||||||
} else {
|
} else {
|
||||||
//global_polygon_type_1(writer, 0, 0, 0);
|
//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++) {
|
for (int j = 0; j < triangles; j++) {
|
||||||
|
|
||||||
int aix = mv[j * 3 + 0].offset + face[i].vertex;
|
int aix = mv[j * 3 + 0].offset + face->vertex;
|
||||||
int bix = mv[j * 3 + 1].offset + face[i].vertex;
|
int bix = mv[j * 3 + 1].offset + face->vertex;
|
||||||
int cix = mv[j * 3 + 2].offset + face[i].vertex;
|
int cix = mv[j * 3 + 2].offset + face->vertex;
|
||||||
|
|
||||||
vec3 ap = vertex_cache[aix].position;
|
vec3 ap = vertex_cache[aix].position;
|
||||||
vec3 bp = vertex_cache[bix].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) {
|
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 at = {vert[aix].texcoord[0], vert[aix].texcoord[1] * v_mul};
|
||||||
vec2 bt = {vert[bix].texcoord[0], vert[bix].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};
|
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)
|
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)
|
void transfer_scene(ta_parameter_writer& writer, const mat4x4& screen_trans)
|
||||||
{
|
{
|
||||||
uint8_t * buf = reinterpret_cast<uint8_t *>(&_binary_pk_maps_20kdm2_bsp_start);
|
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];
|
q3bsp_direntry * ve = &header->direntries[LUMP_VERTEXES];
|
||||||
transform_vertices(&buf[ve->offset], ve->length, trans);
|
transform_vertices(&buf[ve->offset], ve->length, trans);
|
||||||
|
|
||||||
transfer_faces(buf, header, writer);
|
//transfer_faces(writer);
|
||||||
transfer_icosphere(writer, trans);
|
transfer_icosphere(writer, trans);
|
||||||
|
|
||||||
render_matrix(writer, trans);
|
render_matrix(writer, trans);
|
||||||
render_leaf_ix(writer);
|
render_leaf_ix(writer);
|
||||||
render_sphere_position(writer);
|
render_sphere_position(writer);
|
||||||
|
|
||||||
|
render_sphere_bounding_box(writer, trans);
|
||||||
|
|
||||||
writer.append<ta_global_parameter::end_of_list>() =
|
writer.append<ta_global_parameter::end_of_list>() =
|
||||||
ta_global_parameter::end_of_list(para_control::para_type::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, 0, 0},
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
root_ix = 1552;
|
||||||
//render_bounding_boxes(writer, trans);
|
//render_bounding_boxes(writer, trans);
|
||||||
|
|
||||||
writer.append<ta_global_parameter::end_of_list>() =
|
writer.append<ta_global_parameter::end_of_list>() =
|
||||||
ta_global_parameter::end_of_list(para_control::para_type::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)
|
constexpr inline mat4x4 rotate_x(float t)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user