Fix entity AABB computation
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
@@ -1,11 +1,17 @@
|
||||
#include "chunkman.h"
|
||||
|
||||
/* TODO: Lots of entities are generated per-chunk. Perhaps adding them
|
||||
to a queue would be better. */
|
||||
|
||||
/* TODO: Add queues regardless. */
|
||||
|
||||
int n_frame_chunks;
|
||||
|
||||
static GHashTable *chunks;
|
||||
static GHashTable *chunk_meshes;
|
||||
|
||||
static bool bound = false;
|
||||
static int frame_chunks = 0;
|
||||
|
||||
guint
|
||||
chunkman_ivec2_hash (gconstpointer key)
|
||||
@@ -108,6 +114,7 @@ chunkman_tick (vec3 position)
|
||||
chunkman_world_to_chunk (position[0], position[2], &cx, &cz);
|
||||
|
||||
unsigned int frame_time = SDL_GetTicks ();
|
||||
frame_chunks = 0;
|
||||
|
||||
for (int z = cz - RENDER_DISTANCE - 1; z <= cz + RENDER_DISTANCE + 1; ++z)
|
||||
{
|
||||
@@ -115,12 +122,13 @@ chunkman_tick (vec3 position)
|
||||
{
|
||||
if ((x - cx) * (x - cx) + (z - cz) * (z - cz) <= (RENDER_DISTANCE + 1) * (RENDER_DISTANCE + 1))
|
||||
{
|
||||
if (chunkman_get_Chunk_at (x, z) == NULL)
|
||||
if (chunkman_get_Chunk_at (x, z) == NULL)
|
||||
{
|
||||
chunkman_generate_Chunk_at (x, z);
|
||||
++frame_chunks;
|
||||
}
|
||||
|
||||
if (SDL_GetTicks () - frame_time > FRAME_BUDGET)
|
||||
if (frame_chunks > CHUNKS_PER_FRAME || SDL_GetTicks () - frame_time > FRAME_BUDGET)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -137,9 +145,10 @@ chunkman_tick (vec3 position)
|
||||
if (chunkman_get_ChunkMesh_at (x, z) == NULL)
|
||||
{
|
||||
chunkman_generate_ChunkMesh_at (x, z);
|
||||
++frame_chunks;
|
||||
}
|
||||
|
||||
if (SDL_GetTicks () - frame_time > FRAME_BUDGET)
|
||||
if (frame_chunks > CHUNKS_PER_FRAME || SDL_GetTicks () - frame_time > FRAME_BUDGET)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#define RENDER_DISTANCE 5
|
||||
#define RENDER_SQR (RENDER_DISTANCE*RENDER_DISTANCE)
|
||||
#define TERRAIN_HEIGHT 8.0
|
||||
#define FRAME_BUDGET 3
|
||||
#define FRAME_BUDGET 5
|
||||
#define CHUNKS_PER_FRAME 1
|
||||
|
||||
void chunkman_init ();
|
||||
void chunkman_tick (vec3 position);
|
||||
|
||||
+17
-15
@@ -33,21 +33,23 @@ typedef struct Entity
|
||||
static inline void
|
||||
entity_compute_aabb (Entity *e, vec3 out_min, vec3 out_max)
|
||||
{
|
||||
vec3 half = { 0.5f * e->scale[0], 0.5f * e->scale[1], 0.5f * e->scale[2] };
|
||||
|
||||
// The half extent is 1.0f, in that the mesh goes from -1 to 1.
|
||||
vec3 half = { e->scale[0] * 1.0f, e->scale[1] * 1.0f, e->scale[2] * 1.0f };
|
||||
|
||||
out_min[0] = e->position[0] - half[0];
|
||||
out_max[0] = e->position[0] + half[0];
|
||||
|
||||
if (e->origin == ORIGIN_BOTTOM)
|
||||
{
|
||||
out_min[0] = e->position[0] - half[0];
|
||||
out_min[1] = e->position[1];
|
||||
out_min[2] = e->position[2] - half[2];
|
||||
|
||||
out_max[0] = e->position[0] + half[0];
|
||||
out_max[1] = e->position[1] + e->scale[1];
|
||||
out_max[2] = e->position[2] + half[2];
|
||||
}
|
||||
{
|
||||
out_min[1] = e->position[1];
|
||||
out_max[1] = e->position[1] + 2.0f * half[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
glm_vec3_sub (e->position, half, out_min);
|
||||
glm_vec3_add (e->position, half, out_max);
|
||||
}
|
||||
{
|
||||
out_min[1] = e->position[1] - half[1];
|
||||
out_max[1] = e->position[1] + half[1];
|
||||
}
|
||||
|
||||
out_min[2] = e->position[2] - half[2];
|
||||
out_max[2] = e->position[2] + half[2];
|
||||
}
|
||||
|
||||
+20
-15
@@ -14,7 +14,7 @@ int n_frame_ents;
|
||||
/* The GArray is the fastest of all sequence types. Should work fine
|
||||
for a billion entities. */
|
||||
static GArray *entities;
|
||||
static SimpleMesh mesh_quad1, mesh_quad2, mesh_quad_x;
|
||||
static SimpleMesh mesh_quad1, mesh_quad2, mesh_quad_x, mesh_cube;
|
||||
static unsigned int last_program = -1;
|
||||
static unsigned int last_type = -1;
|
||||
static unsigned int last_texture = -1;
|
||||
@@ -32,6 +32,7 @@ entman_init ()
|
||||
mesh_quad1 = SimpleMesh_make_quad1 ();
|
||||
mesh_quad2 = SimpleMesh_make_quad2 ();
|
||||
mesh_quad_x = SimpleMesh_make_quad_x ();
|
||||
mesh_cube = SimpleMesh_make_cube ();
|
||||
|
||||
player_entity = malloc (sizeof (Entity));
|
||||
*player_entity = (Entity) {
|
||||
@@ -88,9 +89,10 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float cull_dist = entity->cull_distance * RENDER_DISTANCE * CHUNK_DIM;
|
||||
|
||||
if (glm_vec3_distance (camera_position, entity->position)
|
||||
> entity->cull_distance * RENDER_DISTANCE * CHUNK_DIM && !entity->dont_cull)
|
||||
if (glm_vec3_distance2 (camera_position, entity->position) > glm_pow2 (cull_dist) && !entity->dont_cull)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -101,7 +103,7 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
#if FRUSTUM_CULL
|
||||
vec3 aabb[2];
|
||||
entity_compute_aabb (entity, aabb[0], aabb[1]);
|
||||
|
||||
|
||||
if (!glm_aabb_frustum (aabb, *vp->frustum_planes))
|
||||
{
|
||||
return;
|
||||
@@ -200,6 +202,17 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
n_frame_ents++;
|
||||
}
|
||||
|
||||
static inline int
|
||||
entman_compare (gconstpointer a, gconstpointer b)
|
||||
/* This function is used to sort Entities by their mesh type, so that
|
||||
diferrent buffers aren't bound every single frame. */
|
||||
{
|
||||
const Entity *entity1 = a;
|
||||
const Entity *entity2 = b;
|
||||
|
||||
return (int) entity1->mesh_type - (int) entity2->mesh_type;
|
||||
}
|
||||
|
||||
void
|
||||
entman_render (mat4 *view, vec4 planes[6])
|
||||
{
|
||||
@@ -224,6 +237,9 @@ entman_render (mat4 *view, vec4 planes[6])
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Sort entities by mesh type. */
|
||||
g_array_sort (entities, entman_compare);
|
||||
|
||||
for (guint i = 0; i < entities->len; ++i)
|
||||
{
|
||||
Entity *e = g_array_index (entities, Entity*, i);
|
||||
@@ -231,17 +247,6 @@ entman_render (mat4 *view, vec4 planes[6])
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
entman_compare (gconstpointer a, gconstpointer b)
|
||||
/* This function is used to sort Entities by their mesh type, so that
|
||||
diferrent buffers aren't bound every single frame. */
|
||||
{
|
||||
const Entity *entity1 = a;
|
||||
const Entity *entity2 = b;
|
||||
|
||||
return (int) entity1->mesh_type - (int) entity2->mesh_type;
|
||||
}
|
||||
|
||||
void
|
||||
entman_add_entity (Entity *entity)
|
||||
{
|
||||
|
||||
@@ -179,3 +179,61 @@ SimpleMesh_make_quad_x ()
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
SimpleMesh
|
||||
SimpleMesh_make_cube ()
|
||||
{
|
||||
/* The positions are trivial. */
|
||||
float positions[24] = {
|
||||
-1.0f, -1.0f, -1.0f,
|
||||
+1.0f, -1.0f, -1.0f,
|
||||
+1.0f, 1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
+1.0f, -1.0f, 1.0f,
|
||||
+1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
unsigned int indices[36] = {
|
||||
4, 5, 6, 6, 7, 4,
|
||||
0, 3, 2, 2, 1, 0,
|
||||
0, 4, 7, 7, 3, 0,
|
||||
1, 2, 6, 6, 5, 1,
|
||||
0, 1, 5, 5, 4, 0,
|
||||
3, 7, 6, 6, 2, 3
|
||||
};
|
||||
|
||||
float uvs[16] = {
|
||||
0.0, 1.0,
|
||||
1.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
|
||||
0.0, 1.0,
|
||||
1.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0
|
||||
};
|
||||
|
||||
SimpleMesh mesh;
|
||||
mesh.indices_len = 36;
|
||||
glGenBuffers (1, &mesh.pbo);
|
||||
glGenBuffers (1, &mesh.uvbo);
|
||||
glGenBuffers (1, &mesh.ebo);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 24, positions, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray (0);
|
||||
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (float) * 3, 0);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh.uvbo);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 16, uvs, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray (1);
|
||||
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0);
|
||||
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo);
|
||||
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * mesh.indices_len, indices, GL_STATIC_DRAW);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,4 +19,4 @@ void SimpleMesh_render (SimpleMesh *mesh);
|
||||
SimpleMesh SimpleMesh_make_quad1 ();
|
||||
SimpleMesh SimpleMesh_make_quad2 ();
|
||||
SimpleMesh SimpleMesh_make_quad_x ();
|
||||
|
||||
SimpleMesh SimpleMesh_make_cube ();
|
||||
|
||||
@@ -152,7 +152,7 @@ resources_init ()
|
||||
RAP ("chunk", RLP ("res/shaders/chunk.vert", "res/shaders/chunk.frag"));
|
||||
RAP ("clouds", RLP ("res/shaders/clouds.vert", "res/shaders/clouds.frag"));
|
||||
RAP ("uielement", RLP ("res/shaders/uielement.vert", "res/shaders/uielement.frag"));
|
||||
|
||||
|
||||
RAT ("terrain0", RLT ("res/textures/dirt.png"));
|
||||
RAT ("terrain1", RLT ("res/textures/drygrass.png"));
|
||||
RAT ("terrain2", RLT ("res/textures/grass.png"));
|
||||
@@ -167,7 +167,7 @@ resources_init ()
|
||||
#undef RAP
|
||||
#undef RLP
|
||||
#undef RAT
|
||||
#undef RLP
|
||||
#undef RLT
|
||||
|
||||
program_use (RESPRG ("chunk"));
|
||||
program_set_int_array (RESPRG ("chunk"), "materials", 5, (int[5]) { 0, 1, 2, 3, 4 });
|
||||
|
||||
Reference in New Issue
Block a user