WIP progressive polygon reduction
parent
fbd958d659
commit
23ee065bc5
4
MAKE.bat
4
MAKE.bat
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
303
demos/99-lod.c
303
demos/99-lod.c
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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
|
@ -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
|
@ -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));
|
||||||
|
|
||||||
|
struct iqm_vertex u0 = *(struct iqm_vertex *)(verts + (q0*mdl->stride));
|
||||||
|
struct iqm_vertex u1 = *(struct iqm_vertex *)(verts + (q1*mdl->stride));
|
||||||
|
struct iqm_vertex u2 = *(struct iqm_vertex *)(verts + (q2*mdl->stride));
|
||||||
|
|
||||||
|
struct iqm_vertex f0=v0,f1=v1,f2=v2;
|
||||||
|
|
||||||
lod_verts[mdl->lod_num_verts++] = v0;
|
if (morph == 0.0f) {
|
||||||
lod_verts[mdl->lod_num_verts++] = v1;
|
f0=u0,f1=u1,f2=u2;
|
||||||
lod_verts[mdl->lod_num_verts++] = v2;
|
}
|
||||||
|
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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
struct iqm_vertex u0 = *(struct iqm_vertex *)(verts + (q0*mdl->stride));
|
||||||
|
struct iqm_vertex u1 = *(struct iqm_vertex *)(verts + (q1*mdl->stride));
|
||||||
|
struct iqm_vertex u2 = *(struct iqm_vertex *)(verts + (q2*mdl->stride));
|
||||||
|
|
||||||
|
struct iqm_vertex f0=v0,f1=v1,f2=v2;
|
||||||
|
|
||||||
lod_verts[mdl->lod_num_verts++] = v0;
|
if (morph == 0.0f) {
|
||||||
lod_verts[mdl->lod_num_verts++] = v1;
|
f0=u0,f1=u1,f2=u2;
|
||||||
lod_verts[mdl->lod_num_verts++] = v2;
|
}
|
||||||
|
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
|
||||||
|
|
103
engine/v4k.c
103
engine/v4k.c
|
@ -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));
|
||||||
|
|
||||||
|
struct iqm_vertex u0 = *(struct iqm_vertex *)(verts + (q0*mdl->stride));
|
||||||
|
struct iqm_vertex u1 = *(struct iqm_vertex *)(verts + (q1*mdl->stride));
|
||||||
|
struct iqm_vertex u2 = *(struct iqm_vertex *)(verts + (q2*mdl->stride));
|
||||||
|
|
||||||
|
struct iqm_vertex f0=v0,f1=v1,f2=v2;
|
||||||
|
|
||||||
lod_verts[mdl->lod_num_verts++] = v0;
|
if (morph == 0.0f) {
|
||||||
lod_verts[mdl->lod_num_verts++] = v1;
|
f0=u0,f1=u1,f2=u2;
|
||||||
lod_verts[mdl->lod_num_verts++] = v2;
|
}
|
||||||
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue