WIP progressive polygon reduction

main
Dominik Madarász 2024-08-19 14:10:35 +02:00
parent fbd958d659
commit 23ee065bc5
12 changed files with 4241 additions and 374224 deletions

View File

@ -280,7 +280,7 @@ if "%1"=="join" (
exit /b exit /b
) )
if "%1"=="3rd" ( if "%1"=="3rd" (
call tools\join_3rd call tools\join_3rd.bat
exit /b exit /b
) )
if "%1"=="swap" ( if "%1"=="swap" (
@ -941,7 +941,7 @@ if not "!other!"=="" (
rem framework rem framework
if "!v4k!"=="yes" ( if "!v4k!"=="yes" (
tools\file2hash engine\v4k.c engine\v4k.h engine\v4k. engine\joint\v4k.h !addons! -- !build! !import! !export! !args! !dll! > nul tools\file2hash engine\v4k.c engine\v4k.h engine\v4k engine\joint\v4k.h !addons! -- !build! !import! !export! !args! !dll! > nul
set cache=_cache\.!errorlevel! set cache=_cache\.!errorlevel!
md _cache 2>nul >nul md _cache 2>nul >nul

View File

@ -1248,6 +1248,7 @@ typedef struct skybox_t {
void skybox_destroy(skybox_t *sky); void skybox_destroy(skybox_t *sky);
void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity); void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity);
void skybox_sh_reset(skybox_t *sky); void skybox_sh_reset(skybox_t *sky);
void skybox_sh_shader(skybox_t *sky);
void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength); void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view);
int skybox_pop_state(); int skybox_pop_state();
@ -1380,6 +1381,11 @@ typedef struct model_t {
void *tris; void *tris;
int num_tris; int num_tris;
handle vao, ibo, vbo, vao_instanced; handle vao, ibo, vbo, vao_instanced;
int* lod_collapse_map;
void *lod_verts;
int lod_num_verts;
void *lod_tris;
int lod_num_tris;
unsigned flags; unsigned flags;
unsigned billboard; unsigned billboard;
float *instanced_matrices; float *instanced_matrices;
@ -1400,6 +1406,7 @@ enum BILLBOARD_MODE {
float model_animate_clip(model_t, float curframe, int minframe, int maxframe, bool loop); float model_animate_clip(model_t, float curframe, int minframe, int maxframe, bool loop);
float model_animate_blends(model_t m, anim_t *primary, anim_t *secondary, float delta); float model_animate_blends(model_t m, anim_t *primary, anim_t *secondary, float delta);
aabb model_aabb(model_t, mat44 transform); aabb model_aabb(model_t, mat44 transform);
void model_lod(model_t*, float lo_detail, float hi_detail, float morph);
void model_shading(model_t*, int shading); void model_shading(model_t*, int shading);
void model_skybox(model_t*, skybox_t sky, bool load_sh); void model_skybox(model_t*, skybox_t sky, bool load_sh);
void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader); void model_render(model_t, mat44 proj, mat44 view, mat44 model, int shader);

File diff suppressed because one or more lines are too long

237
demos/99-lod_old.c 100644

File diff suppressed because one or more lines are too long

View File

@ -1,48 +0,0 @@
#include "v4k.h"
int main() {
window_create(80, WINDOW_MSAA4);
window_title(__FILE__);
// load skybox: launch with --mie for rayleigh/mie scattering
skybox_t sky = skybox(flag("--mie") ? 0 : "cubemaps/stardust", 0);
// terrain model
// model_t mdl = model("terrain_demo.obj", 0);
model_t mdl = model("Mike.fbx", 0);
// camera
camera_t cam = camera();
// scene light
shader_bind(mdl.program);
light_t *l = scene_spawn_light();
light_update(1, l);
skybox_sh_shader(&sky);
// initialise LOD
model_lod(&mdl, 1.0, 1.0, 1);
// demo loop
while (window_swap())
{
// input
if( input_down(KEY_ESC) ) break;
if( input_down(KEY_F5) ) window_reload();
if( input_down(KEY_F11) ) window_fullscreen( window_has_fullscreen() ^ 1 );
// fps camera
bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R);
if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f);
vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active);
vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed);
camera_moveby(&cam, wasdecq);
camera_fps(&cam, mouse.x,mouse.y);
window_cursor( !active );
// draw scene
skybox_render(&sky, cam.proj, cam.view);
model_render(mdl, cam.proj, cam.view, mdl.pivot, 0);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +0,0 @@
# Blender 4.0.2 MTL File: 'None'
# www.blender.org
newmtl Material.003
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2

File diff suppressed because it is too large Load Diff

View File

@ -386029,13 +386029,40 @@ static inline int MapReduce(array(int) collapse_map, int n, int mx) {
API void ProgressiveMesh(int vert_n, int vert_stride, const float *v, int tri_n, const int *tri, int *map, int *permutation); API void ProgressiveMesh(int vert_n, int vert_stride, const float *v, int tri_n, const int *tri, int *map, int *permutation);
static inline
void MorphVertex(struct iqm_vertex *v, struct iqm_vertex *v0, struct iqm_vertex *v1, float t) {
v->position[0] = mixf(v0->position[0], v1->position[0], t);
v->position[1] = mixf(v0->position[1], v1->position[1], t);
v->position[2] = mixf(v0->position[2], v1->position[2], t);
v->normal[0] = mixf(v0->normal[0], v1->normal[0], t);
v->normal[1] = mixf(v0->normal[1], v1->normal[1], t);
v->normal[2] = mixf(v0->normal[2], v1->normal[2], t);
v->tangent[0] = mixf(v0->tangent[0], v1->tangent[0], t);
v->tangent[1] = mixf(v0->tangent[1], v1->tangent[1], t);
v->tangent[2] = mixf(v0->tangent[2], v1->tangent[2], t);
v->texcoord[0] = mixf(v0->texcoord[0], v1->texcoord[0], t);
v->texcoord[1] = mixf(v0->texcoord[1], v1->texcoord[1], t);
}
void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) { void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
assert(mdl->num_meshes == 1); assert(mdl->num_meshes == 1);
if (array_count(mdl->lod_collapse_map) == 0) { if (array_count(mdl->lod_collapse_map) == 0) {
array(int) permutation = 0; array(int) permutation = 0;
array(float) positions = 0;
array_resize(mdl->lod_collapse_map, mdl->num_verts); array_resize(mdl->lod_collapse_map, mdl->num_verts);
array_resize(permutation, mdl->num_verts); array_resize(permutation, mdl->num_verts);
ProgressiveMesh(mdl->num_verts, mdl->stride, (const float *)mdl->verts, mdl->num_tris, (const int *)mdl->tris, mdl->lod_collapse_map, permutation); array_resize(positions, mdl->num_verts*3);
for (int i = 0; i < mdl->num_verts; i++) {
struct iqm_vertex *v = (struct iqm_vertex *)((char *)mdl->verts + i*mdl->stride);
positions[i*3 + 0] = v->position[0];
positions[i*3 + 1] = v->position[1];
positions[i*3 + 2] = v->position[2];
}
ProgressiveMesh(mdl->num_verts, sizeof(float)*3, (const float *)positions, mdl->num_tris, (const int *)mdl->tris, mdl->lod_collapse_map, permutation);
array_free(positions);
// PermuteVertices { // PermuteVertices {
ASSERT(array_count(permutation) == mdl->num_verts); ASSERT(array_count(permutation) == mdl->num_verts);
// rearrange the vertex Array // rearrange the vertex Array
@ -386052,10 +386079,10 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
} }
int *tris = (int *)mdl->tris; int *tris = (int *)mdl->tris;
// update the changes in the entries in the triangle Array // update the changes in the entries in the triangle Array
for (int i = 0; i < mdl->num_tris*3; i+=3) { for (int i = 0; i < mdl->num_tris; i++) {
tris[i+0] = permutation[tris[i+0]]; tris[i*3 + 0] = permutation[tris[i*3 + 0]];
tris[i+1] = permutation[tris[i+1]]; tris[i*3 + 1] = permutation[tris[i*3 + 1]];
tris[i+2] = permutation[tris[i+2]]; tris[i*3 + 2] = permutation[tris[i*3 + 2]];
} }
// upload modified data // upload modified data
@ -386090,10 +386117,10 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
int max_lod_tris = 0; int max_lod_tris = 0;
//@fixme: optimise //@fixme: optimise
for( unsigned int i = 0; i < mdl->num_tris*3; i+=3 ) { for( unsigned int i = 0; i < mdl->num_tris; i++ ) {
int p0 = MapReduce(mdl->lod_collapse_map, tris[i+0], max_verts_to_render); int p0 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 0], max_verts_to_render);
int p1 = MapReduce(mdl->lod_collapse_map, tris[i+1], max_verts_to_render); int p1 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 1], max_verts_to_render);
int p2 = MapReduce(mdl->lod_collapse_map, tris[i+2], max_verts_to_render); int p2 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 2], max_verts_to_render);
if(p0==p1 || p0==p2 || p1==p2) continue; if(p0==p1 || p0==p2 || p1==p2) continue;
++max_lod_tris; ++max_lod_tris;
} }
@ -386106,48 +386133,46 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
struct iqm_vertex *lod_verts = (struct iqm_vertex *)mdl->lod_verts; struct iqm_vertex *lod_verts = (struct iqm_vertex *)mdl->lod_verts;
int *lod_tris = (int *)mdl->lod_tris; int *lod_tris = (int *)mdl->lod_tris;
for( int i = 0; i < mdl->num_tris*3; i+=3 ) { for( int i = 0; i < mdl->num_tris; i++ ) {
int p0 = MapReduce(mdl->lod_collapse_map, tris[i+0], max_verts_to_render); int p0 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 0], max_verts_to_render);
int p1 = MapReduce(mdl->lod_collapse_map, tris[i+1], max_verts_to_render); int p1 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 1], max_verts_to_render);
int p2 = MapReduce(mdl->lod_collapse_map, tris[i+2], max_verts_to_render); int p2 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 2], max_verts_to_render);
// @fixme: serious optimization opportunity here,
// by sorting the triangles the following "continue"
// could have been made into a "break" statement.
if(p0==p1 || p0==p2 || p1==p2) continue; if(p0==p1 || p0==p2 || p1==p2) continue;
// if we are not currenly morphing between 2 levels of detail
// (i.e. if morph=1.0) then q0,q1, and q2 may not be necessary
int q0 = MapReduce(mdl->lod_collapse_map, p0, min_verts_to_render); int q0 = MapReduce(mdl->lod_collapse_map, p0, min_verts_to_render);
int q1 = MapReduce(mdl->lod_collapse_map, p1, min_verts_to_render); int q1 = MapReduce(mdl->lod_collapse_map, p1, min_verts_to_render);
int q2 = MapReduce(mdl->lod_collapse_map, p2, min_verts_to_render); int q2 = MapReduce(mdl->lod_collapse_map, p2, min_verts_to_render);
// if(q0==q1 || q0==q2 || q1==q2) continue;
struct iqm_vertex v0 = *(struct iqm_vertex *)(verts + (p0*mdl->stride)); struct iqm_vertex v0 = *(struct iqm_vertex *)(verts + (p0*mdl->stride));
struct iqm_vertex v1 = *(struct iqm_vertex *)(verts + (p1*mdl->stride)); struct iqm_vertex v1 = *(struct iqm_vertex *)(verts + (p1*mdl->stride));
struct iqm_vertex v2 = *(struct iqm_vertex *)(verts + (p2*mdl->stride)); struct iqm_vertex v2 = *(struct iqm_vertex *)(verts + (p2*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v0; struct iqm_vertex u0 = *(struct iqm_vertex *)(verts + (q0*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v1; struct iqm_vertex u1 = *(struct iqm_vertex *)(verts + (q1*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v2; struct iqm_vertex u2 = *(struct iqm_vertex *)(verts + (q2*mdl->stride));
struct iqm_vertex f0=v0,f1=v1,f2=v2;
if (morph == 0.0f) {
f0=u0,f1=u1,f2=u2;
}
else if (morph < 1.0f) {
MorphVertex(&f0, &v0, &u0, 1.0f - morph);
MorphVertex(&f1, &v1, &u1, 1.0f - morph);
MorphVertex(&f2, &v2, &u2, 1.0f - morph);
}
lod_verts[mdl->lod_num_verts + 0] = f0;
lod_verts[mdl->lod_num_verts + 1] = f1;
lod_verts[mdl->lod_num_verts + 2] = f2;
int idx = mdl->lod_num_verts; int idx = mdl->lod_num_verts;
lod_tris[mdl->lod_num_tris + 0] = idx-3; lod_tris[mdl->lod_num_tris*3 + 0] = idx+0;
lod_tris[mdl->lod_num_tris + 1] = idx-2; lod_tris[mdl->lod_num_tris*3 + 1] = idx+1;
lod_tris[mdl->lod_num_tris + 2] = idx-1; lod_tris[mdl->lod_num_tris*3 + 2] = idx+2;
mdl->lod_num_verts += 3;
++mdl->lod_num_tris; ++mdl->lod_num_tris;
// vec3 v0, v1, v2;
// v0 = mix3(m->in_vertex3[p0], m->in_vertex3[q0], (1-morph));
// v1 = mix3(m->in_vertex3[p1], m->in_vertex3[q1], (1-morph));
// v2 = mix3(m->in_vertex3[p2], m->in_vertex3[q2], (1-morph));
// vec3 normal = norm3(cross3(sub3(v1,v0),sub3(v2,v1)));
// array_push(m->out_vertex3, v0);
// array_push(m->out_vertex3, normal);
// array_push(m->out_vertex3, v1);
// array_push(m->out_vertex3, normal);
// array_push(m->out_vertex3, v2);
// array_push(m->out_vertex3, normal);
// int idx = array_count(m->out_vertex3) / 2;
// array_push(m->out_index3, vec3i(idx-3,idx-2,idx-1));
} }
// upload modified data // upload modified data

View File

@ -4416,13 +4416,40 @@ static inline int MapReduce(array(int) collapse_map, int n, int mx) {
API void ProgressiveMesh(int vert_n, int vert_stride, const float *v, int tri_n, const int *tri, int *map, int *permutation); API void ProgressiveMesh(int vert_n, int vert_stride, const float *v, int tri_n, const int *tri, int *map, int *permutation);
static inline
void MorphVertex(struct iqm_vertex *v, struct iqm_vertex *v0, struct iqm_vertex *v1, float t) {
v->position[0] = mixf(v0->position[0], v1->position[0], t);
v->position[1] = mixf(v0->position[1], v1->position[1], t);
v->position[2] = mixf(v0->position[2], v1->position[2], t);
v->normal[0] = mixf(v0->normal[0], v1->normal[0], t);
v->normal[1] = mixf(v0->normal[1], v1->normal[1], t);
v->normal[2] = mixf(v0->normal[2], v1->normal[2], t);
v->tangent[0] = mixf(v0->tangent[0], v1->tangent[0], t);
v->tangent[1] = mixf(v0->tangent[1], v1->tangent[1], t);
v->tangent[2] = mixf(v0->tangent[2], v1->tangent[2], t);
v->texcoord[0] = mixf(v0->texcoord[0], v1->texcoord[0], t);
v->texcoord[1] = mixf(v0->texcoord[1], v1->texcoord[1], t);
}
void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) { void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
assert(mdl->num_meshes == 1); assert(mdl->num_meshes == 1);
if (array_count(mdl->lod_collapse_map) == 0) { if (array_count(mdl->lod_collapse_map) == 0) {
array(int) permutation = 0; array(int) permutation = 0;
array(float) positions = 0;
array_resize(mdl->lod_collapse_map, mdl->num_verts); array_resize(mdl->lod_collapse_map, mdl->num_verts);
array_resize(permutation, mdl->num_verts); array_resize(permutation, mdl->num_verts);
ProgressiveMesh(mdl->num_verts, mdl->stride, (const float *)mdl->verts, mdl->num_tris, (const int *)mdl->tris, mdl->lod_collapse_map, permutation); array_resize(positions, mdl->num_verts*3);
for (int i = 0; i < mdl->num_verts; i++) {
struct iqm_vertex *v = (struct iqm_vertex *)((char *)mdl->verts + i*mdl->stride);
positions[i*3 + 0] = v->position[0];
positions[i*3 + 1] = v->position[1];
positions[i*3 + 2] = v->position[2];
}
ProgressiveMesh(mdl->num_verts, sizeof(float)*3, (const float *)positions, mdl->num_tris, (const int *)mdl->tris, mdl->lod_collapse_map, permutation);
array_free(positions);
// PermuteVertices { // PermuteVertices {
ASSERT(array_count(permutation) == mdl->num_verts); ASSERT(array_count(permutation) == mdl->num_verts);
// rearrange the vertex Array // rearrange the vertex Array
@ -4439,10 +4466,10 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
} }
int *tris = (int *)mdl->tris; int *tris = (int *)mdl->tris;
// update the changes in the entries in the triangle Array // update the changes in the entries in the triangle Array
for (int i = 0; i < mdl->num_tris*3; i+=3) { for (int i = 0; i < mdl->num_tris; i++) {
tris[i+0] = permutation[tris[i+0]]; tris[i*3 + 0] = permutation[tris[i*3 + 0]];
tris[i+1] = permutation[tris[i+1]]; tris[i*3 + 1] = permutation[tris[i*3 + 1]];
tris[i+2] = permutation[tris[i+2]]; tris[i*3 + 2] = permutation[tris[i*3 + 2]];
} }
// upload modified data // upload modified data
@ -4477,10 +4504,10 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
int max_lod_tris = 0; int max_lod_tris = 0;
//@fixme: optimise //@fixme: optimise
for( unsigned int i = 0; i < mdl->num_tris*3; i+=3 ) { for( unsigned int i = 0; i < mdl->num_tris; i++ ) {
int p0 = MapReduce(mdl->lod_collapse_map, tris[i+0], max_verts_to_render); int p0 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 0], max_verts_to_render);
int p1 = MapReduce(mdl->lod_collapse_map, tris[i+1], max_verts_to_render); int p1 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 1], max_verts_to_render);
int p2 = MapReduce(mdl->lod_collapse_map, tris[i+2], max_verts_to_render); int p2 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 2], max_verts_to_render);
if(p0==p1 || p0==p2 || p1==p2) continue; if(p0==p1 || p0==p2 || p1==p2) continue;
++max_lod_tris; ++max_lod_tris;
} }
@ -4493,48 +4520,46 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
struct iqm_vertex *lod_verts = (struct iqm_vertex *)mdl->lod_verts; struct iqm_vertex *lod_verts = (struct iqm_vertex *)mdl->lod_verts;
int *lod_tris = (int *)mdl->lod_tris; int *lod_tris = (int *)mdl->lod_tris;
for( int i = 0; i < mdl->num_tris*3; i+=3 ) { for( int i = 0; i < mdl->num_tris; i++ ) {
int p0 = MapReduce(mdl->lod_collapse_map, tris[i+0], max_verts_to_render); int p0 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 0], max_verts_to_render);
int p1 = MapReduce(mdl->lod_collapse_map, tris[i+1], max_verts_to_render); int p1 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 1], max_verts_to_render);
int p2 = MapReduce(mdl->lod_collapse_map, tris[i+2], max_verts_to_render); int p2 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 2], max_verts_to_render);
// @fixme: serious optimization opportunity here,
// by sorting the triangles the following "continue"
// could have been made into a "break" statement.
if(p0==p1 || p0==p2 || p1==p2) continue; if(p0==p1 || p0==p2 || p1==p2) continue;
// if we are not currenly morphing between 2 levels of detail
// (i.e. if morph=1.0) then q0,q1, and q2 may not be necessary
int q0 = MapReduce(mdl->lod_collapse_map, p0, min_verts_to_render); int q0 = MapReduce(mdl->lod_collapse_map, p0, min_verts_to_render);
int q1 = MapReduce(mdl->lod_collapse_map, p1, min_verts_to_render); int q1 = MapReduce(mdl->lod_collapse_map, p1, min_verts_to_render);
int q2 = MapReduce(mdl->lod_collapse_map, p2, min_verts_to_render); int q2 = MapReduce(mdl->lod_collapse_map, p2, min_verts_to_render);
// if(q0==q1 || q0==q2 || q1==q2) continue;
struct iqm_vertex v0 = *(struct iqm_vertex *)(verts + (p0*mdl->stride)); struct iqm_vertex v0 = *(struct iqm_vertex *)(verts + (p0*mdl->stride));
struct iqm_vertex v1 = *(struct iqm_vertex *)(verts + (p1*mdl->stride)); struct iqm_vertex v1 = *(struct iqm_vertex *)(verts + (p1*mdl->stride));
struct iqm_vertex v2 = *(struct iqm_vertex *)(verts + (p2*mdl->stride)); struct iqm_vertex v2 = *(struct iqm_vertex *)(verts + (p2*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v0; struct iqm_vertex u0 = *(struct iqm_vertex *)(verts + (q0*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v1; struct iqm_vertex u1 = *(struct iqm_vertex *)(verts + (q1*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v2; struct iqm_vertex u2 = *(struct iqm_vertex *)(verts + (q2*mdl->stride));
struct iqm_vertex f0=v0,f1=v1,f2=v2;
if (morph == 0.0f) {
f0=u0,f1=u1,f2=u2;
}
else if (morph < 1.0f) {
MorphVertex(&f0, &v0, &u0, 1.0f - morph);
MorphVertex(&f1, &v1, &u1, 1.0f - morph);
MorphVertex(&f2, &v2, &u2, 1.0f - morph);
}
lod_verts[mdl->lod_num_verts + 0] = f0;
lod_verts[mdl->lod_num_verts + 1] = f1;
lod_verts[mdl->lod_num_verts + 2] = f2;
int idx = mdl->lod_num_verts; int idx = mdl->lod_num_verts;
lod_tris[mdl->lod_num_tris + 0] = idx-3; lod_tris[mdl->lod_num_tris*3 + 0] = idx+0;
lod_tris[mdl->lod_num_tris + 1] = idx-2; lod_tris[mdl->lod_num_tris*3 + 1] = idx+1;
lod_tris[mdl->lod_num_tris + 2] = idx-1; lod_tris[mdl->lod_num_tris*3 + 2] = idx+2;
mdl->lod_num_verts += 3;
++mdl->lod_num_tris; ++mdl->lod_num_tris;
// vec3 v0, v1, v2;
// v0 = mix3(m->in_vertex3[p0], m->in_vertex3[q0], (1-morph));
// v1 = mix3(m->in_vertex3[p1], m->in_vertex3[q1], (1-morph));
// v2 = mix3(m->in_vertex3[p2], m->in_vertex3[q2], (1-morph));
// vec3 normal = norm3(cross3(sub3(v1,v0),sub3(v2,v1)));
// array_push(m->out_vertex3, v0);
// array_push(m->out_vertex3, normal);
// array_push(m->out_vertex3, v1);
// array_push(m->out_vertex3, normal);
// array_push(m->out_vertex3, v2);
// array_push(m->out_vertex3, normal);
// int idx = array_count(m->out_vertex3) / 2;
// array_push(m->out_index3, vec3i(idx-3,idx-2,idx-1));
} }
// upload modified data // upload modified data

View File

@ -21201,13 +21201,40 @@ static inline int MapReduce(array(int) collapse_map, int n, int mx) {
API void ProgressiveMesh(int vert_n, int vert_stride, const float *v, int tri_n, const int *tri, int *map, int *permutation); API void ProgressiveMesh(int vert_n, int vert_stride, const float *v, int tri_n, const int *tri, int *map, int *permutation);
static inline
void MorphVertex(struct iqm_vertex *v, struct iqm_vertex *v0, struct iqm_vertex *v1, float t) {
v->position[0] = mixf(v0->position[0], v1->position[0], t);
v->position[1] = mixf(v0->position[1], v1->position[1], t);
v->position[2] = mixf(v0->position[2], v1->position[2], t);
v->normal[0] = mixf(v0->normal[0], v1->normal[0], t);
v->normal[1] = mixf(v0->normal[1], v1->normal[1], t);
v->normal[2] = mixf(v0->normal[2], v1->normal[2], t);
v->tangent[0] = mixf(v0->tangent[0], v1->tangent[0], t);
v->tangent[1] = mixf(v0->tangent[1], v1->tangent[1], t);
v->tangent[2] = mixf(v0->tangent[2], v1->tangent[2], t);
v->texcoord[0] = mixf(v0->texcoord[0], v1->texcoord[0], t);
v->texcoord[1] = mixf(v0->texcoord[1], v1->texcoord[1], t);
}
void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) { void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
assert(mdl->num_meshes == 1); assert(mdl->num_meshes == 1);
if (array_count(mdl->lod_collapse_map) == 0) { if (array_count(mdl->lod_collapse_map) == 0) {
array(int) permutation = 0; array(int) permutation = 0;
array(float) positions = 0;
array_resize(mdl->lod_collapse_map, mdl->num_verts); array_resize(mdl->lod_collapse_map, mdl->num_verts);
array_resize(permutation, mdl->num_verts); array_resize(permutation, mdl->num_verts);
ProgressiveMesh(mdl->num_verts, mdl->stride, (const float *)mdl->verts, mdl->num_tris, (const int *)mdl->tris, mdl->lod_collapse_map, permutation); array_resize(positions, mdl->num_verts*3);
for (int i = 0; i < mdl->num_verts; i++) {
struct iqm_vertex *v = (struct iqm_vertex *)((char *)mdl->verts + i*mdl->stride);
positions[i*3 + 0] = v->position[0];
positions[i*3 + 1] = v->position[1];
positions[i*3 + 2] = v->position[2];
}
ProgressiveMesh(mdl->num_verts, sizeof(float)*3, (const float *)positions, mdl->num_tris, (const int *)mdl->tris, mdl->lod_collapse_map, permutation);
array_free(positions);
// PermuteVertices { // PermuteVertices {
ASSERT(array_count(permutation) == mdl->num_verts); ASSERT(array_count(permutation) == mdl->num_verts);
// rearrange the vertex Array // rearrange the vertex Array
@ -21224,10 +21251,10 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
} }
int *tris = (int *)mdl->tris; int *tris = (int *)mdl->tris;
// update the changes in the entries in the triangle Array // update the changes in the entries in the triangle Array
for (int i = 0; i < mdl->num_tris*3; i+=3) { for (int i = 0; i < mdl->num_tris; i++) {
tris[i+0] = permutation[tris[i+0]]; tris[i*3 + 0] = permutation[tris[i*3 + 0]];
tris[i+1] = permutation[tris[i+1]]; tris[i*3 + 1] = permutation[tris[i*3 + 1]];
tris[i+2] = permutation[tris[i+2]]; tris[i*3 + 2] = permutation[tris[i*3 + 2]];
} }
// upload modified data // upload modified data
@ -21262,10 +21289,10 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
int max_lod_tris = 0; int max_lod_tris = 0;
//@fixme: optimise //@fixme: optimise
for( unsigned int i = 0; i < mdl->num_tris*3; i+=3 ) { for( unsigned int i = 0; i < mdl->num_tris; i++ ) {
int p0 = MapReduce(mdl->lod_collapse_map, tris[i+0], max_verts_to_render); int p0 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 0], max_verts_to_render);
int p1 = MapReduce(mdl->lod_collapse_map, tris[i+1], max_verts_to_render); int p1 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 1], max_verts_to_render);
int p2 = MapReduce(mdl->lod_collapse_map, tris[i+2], max_verts_to_render); int p2 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 2], max_verts_to_render);
if(p0==p1 || p0==p2 || p1==p2) continue; if(p0==p1 || p0==p2 || p1==p2) continue;
++max_lod_tris; ++max_lod_tris;
} }
@ -21278,48 +21305,46 @@ void model_lod(model_t *mdl, float lo_detail, float hi_detail, float morph) {
struct iqm_vertex *lod_verts = (struct iqm_vertex *)mdl->lod_verts; struct iqm_vertex *lod_verts = (struct iqm_vertex *)mdl->lod_verts;
int *lod_tris = (int *)mdl->lod_tris; int *lod_tris = (int *)mdl->lod_tris;
for( int i = 0; i < mdl->num_tris*3; i+=3 ) { for( int i = 0; i < mdl->num_tris; i++ ) {
int p0 = MapReduce(mdl->lod_collapse_map, tris[i+0], max_verts_to_render); int p0 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 0], max_verts_to_render);
int p1 = MapReduce(mdl->lod_collapse_map, tris[i+1], max_verts_to_render); int p1 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 1], max_verts_to_render);
int p2 = MapReduce(mdl->lod_collapse_map, tris[i+2], max_verts_to_render); int p2 = MapReduce(mdl->lod_collapse_map, tris[i*3 + 2], max_verts_to_render);
// @fixme: serious optimization opportunity here,
// by sorting the triangles the following "continue"
// could have been made into a "break" statement.
if(p0==p1 || p0==p2 || p1==p2) continue; if(p0==p1 || p0==p2 || p1==p2) continue;
// if we are not currenly morphing between 2 levels of detail
// (i.e. if morph=1.0) then q0,q1, and q2 may not be necessary
int q0 = MapReduce(mdl->lod_collapse_map, p0, min_verts_to_render); int q0 = MapReduce(mdl->lod_collapse_map, p0, min_verts_to_render);
int q1 = MapReduce(mdl->lod_collapse_map, p1, min_verts_to_render); int q1 = MapReduce(mdl->lod_collapse_map, p1, min_verts_to_render);
int q2 = MapReduce(mdl->lod_collapse_map, p2, min_verts_to_render); int q2 = MapReduce(mdl->lod_collapse_map, p2, min_verts_to_render);
// if(q0==q1 || q0==q2 || q1==q2) continue;
struct iqm_vertex v0 = *(struct iqm_vertex *)(verts + (p0*mdl->stride)); struct iqm_vertex v0 = *(struct iqm_vertex *)(verts + (p0*mdl->stride));
struct iqm_vertex v1 = *(struct iqm_vertex *)(verts + (p1*mdl->stride)); struct iqm_vertex v1 = *(struct iqm_vertex *)(verts + (p1*mdl->stride));
struct iqm_vertex v2 = *(struct iqm_vertex *)(verts + (p2*mdl->stride)); struct iqm_vertex v2 = *(struct iqm_vertex *)(verts + (p2*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v0; struct iqm_vertex u0 = *(struct iqm_vertex *)(verts + (q0*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v1; struct iqm_vertex u1 = *(struct iqm_vertex *)(verts + (q1*mdl->stride));
lod_verts[mdl->lod_num_verts++] = v2; struct iqm_vertex u2 = *(struct iqm_vertex *)(verts + (q2*mdl->stride));
struct iqm_vertex f0=v0,f1=v1,f2=v2;
if (morph == 0.0f) {
f0=u0,f1=u1,f2=u2;
}
else if (morph < 1.0f) {
MorphVertex(&f0, &v0, &u0, 1.0f - morph);
MorphVertex(&f1, &v1, &u1, 1.0f - morph);
MorphVertex(&f2, &v2, &u2, 1.0f - morph);
}
lod_verts[mdl->lod_num_verts + 0] = f0;
lod_verts[mdl->lod_num_verts + 1] = f1;
lod_verts[mdl->lod_num_verts + 2] = f2;
int idx = mdl->lod_num_verts; int idx = mdl->lod_num_verts;
lod_tris[mdl->lod_num_tris + 0] = idx-3; lod_tris[mdl->lod_num_tris*3 + 0] = idx+0;
lod_tris[mdl->lod_num_tris + 1] = idx-2; lod_tris[mdl->lod_num_tris*3 + 1] = idx+1;
lod_tris[mdl->lod_num_tris + 2] = idx-1; lod_tris[mdl->lod_num_tris*3 + 2] = idx+2;
mdl->lod_num_verts += 3;
++mdl->lod_num_tris; ++mdl->lod_num_tris;
// vec3 v0, v1, v2;
// v0 = mix3(m->in_vertex3[p0], m->in_vertex3[q0], (1-morph));
// v1 = mix3(m->in_vertex3[p1], m->in_vertex3[q1], (1-morph));
// v2 = mix3(m->in_vertex3[p2], m->in_vertex3[q2], (1-morph));
// vec3 normal = norm3(cross3(sub3(v1,v0),sub3(v2,v1)));
// array_push(m->out_vertex3, v0);
// array_push(m->out_vertex3, normal);
// array_push(m->out_vertex3, v1);
// array_push(m->out_vertex3, normal);
// array_push(m->out_vertex3, v2);
// array_push(m->out_vertex3, normal);
// int idx = array_count(m->out_vertex3) / 2;
// array_push(m->out_index3, vec3i(idx-3,idx-2,idx-1));
} }
// upload modified data // upload modified data

View File

@ -1,3 +1,3 @@
#!/bin/bash 2>nul #!/bin/bash 2>nul
python tools/join.py --template engine/split/v4k.x.inl --path ./engine/split/ --output ./engine/v4k tools\join.exe --template engine/split/v4k.x.inl --path ./engine/split/ --output ./engine/v4k