X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=cxr%2Fcxr.h;h=644c8ed83e39381e88ceb5c3beeb4772e29f3be3;hb=0d0b6bf37c8a9c4494071973103a89b4aa82574a;hp=dd7a8b83092dffc3612042b87aba4216abe6b54f;hpb=dbf8a911ed372acbda6ae7f67b1c3987082d1c9b;p=convexer.git diff --git a/cxr/cxr.h b/cxr/cxr.h index dd7a8b8..644c8ed 100644 --- a/cxr/cxr.h +++ b/cxr/cxr.h @@ -1,11 +1,13 @@ /* - CONVEXER v0.9 + CONVEXER v0.95 A GNU/Linux-first Source1 Hammer replacement built with Blender, for mapmakers Copyright (C) 2022 Harry Godden (hgn) +LICENSE: GPLv3.0, please see COPYING and LICENSE for more information + Features: - Brush decomposition into convex pieces for well defined geometry - Freely form displacements without limits @@ -13,7 +15,8 @@ - Compile models and model groups easily - It runs at an ok speed! - Light patch BSP files; remove unwanted realtime effects - - Fastest VTF compressor (thanks to Richgel999 and stb) + - Bestest VTF compressor (thanks to Richgel999 and stb) + - Pack content automatically Program structure: @@ -45,7 +48,6 @@ IMPLEMENTATION */ -#define CXR_API #define CXR_EPSILON 0.001 #define CXR_PLANE_SIMILARITY_MAX 0.998 #define CXR_BIG_NUMBER 1e300 @@ -57,31 +59,17 @@ #include #include -#include -#include #include #include -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; - -typedef unsigned int uint; - -typedef double v2f[2]; -typedef double v3f[3]; -typedef double v4f[4]; -typedef v3f m3x3f[3]; -typedef v3f m4x3f[4]; -typedef v3f boxf[2]; - +#include "cxr_types.h" #include "cxr_math.h" #include "cxr_mem.h" +#include "cxr_log.h" + +#ifdef CXR_VALVE_BIN + #include "cxr_valve_bin.h" +#endif typedef struct cxr_world cxr_world; typedef struct cxr_solid cxr_solid; @@ -98,6 +86,7 @@ typedef struct cxr_tri_mesh cxr_tri_mesh; #ifdef CXR_VALVE_MAP_FILE typedef struct cxr_vdf cxr_vdf; typedef struct cxr_texinfo cxr_texinfo; + typedef struct cxr_visgroup cxr_visgroup; typedef struct cxr_vmf_context cxr_vmf_context; #endif /* CXR_VALVE_MAP_FILE */ @@ -155,6 +144,7 @@ struct cxr_static_mesh i32 index, edge_index; v2f uv; + double alpha; } *loops; @@ -188,6 +178,7 @@ struct cxr_loop edge_index, index; v2f uv; + float alpha; }; struct cxr_solid @@ -226,8 +217,11 @@ struct cxr_mesh /* Simple mesh type mainly for debugging */ struct cxr_tri_mesh { - v3f *vertices; + v3f *vertices, + *normals; + v2f *uvs; v4f *colours; + i32 *indices, indices_count, vertex_count; @@ -241,6 +235,11 @@ struct cxr_texinfo double winding; }; +struct cxr_visgroup +{ + const char *name; +}; + /* * Simplified VDF writing interface. No allocations or nodes, just write to file */ @@ -258,10 +257,14 @@ struct cxr_vmf_context *detailvbsp, *detailmaterial; + cxr_visgroup *visgroups; + i32 visgroup_count; + /* Transform settings */ double scale; v3f offset; - i32 lightmap_scale; + i32 lightmap_scale, + visgroupid; /* Current stats */ i32 brush_count, @@ -279,7 +282,8 @@ enum cxr_soliderr k_soliderr_degenerate_implicit, k_soliderr_non_coplanar_vertices, k_soliderr_non_convex_poly, - k_soliderr_bad_result + k_soliderr_bad_result, + k_soliderr_invalid_input }; /* @@ -291,8 +295,12 @@ enum cxr_soliderr const char *cxr_build_time = __DATE__ " @" __TIME__; #endif -static void (*cxr_log_func)(const char *str); -static void (*cxr_line_func)( v3f p0, v3f p1, v4f colour ); +#if _WIN32 || _WIN64 +#if _WIN64 +#else +#warning 32 bit is not supported in blender 3.0 +#endif +#endif static int cxr_range(int x, int bound) { @@ -368,21 +376,6 @@ static void colour_random_brush(int n, v4f colour) #ifdef CXR_DEBUG -static void cxr_log( const char *fmt, ... ) -{ - char buf[512]; - - va_list args; - va_start( args, fmt ); - vsnprintf( buf, sizeof(buf)-1, fmt, args ); - va_end(args); - - if( cxr_log_func ) - cxr_log_func( buf ); - - fputs(buf,stdout); -} - static void cxr_debug_line( v3f p0, v3f p1, v4f colour ) { if( cxr_line_func ) @@ -493,9 +486,12 @@ CXR_API void cxr_write_test_data( cxr_static_mesh *src ) fprintf( fp, "cxr_static_loop test_loops[] = {\n" ); for( int i=0; iloop_count; i ++ ) { - fprintf( fp, " {%d, %d},\n", + fprintf( fp, " {%d, %d, {%f, %f}, %f},\n", src->loops[i].index, - src->loops[i].edge_index); + src->loops[i].edge_index, + src->loops[i].uv[0], + src->loops[i].uv[1], + src->loops[i].alpha ); } fprintf( fp, "};\n" ); @@ -2063,6 +2059,7 @@ static cxr_mesh *cxr_to_internal_format( lp->index = src->loops[i].index; lp->edge_index = src->loops[i].edge_index; v2_copy( src->loops[i].uv, lp->uv ); + lp->alpha = src->loops[i].alpha; } abverts->count = src->vertex_count; @@ -2191,6 +2188,8 @@ CXR_API cxr_tri_mesh *cxr_world_preview( cxr_world *world ) out->colours = malloc( sizeof(v4f)*out->vertex_count ); out->vertices = malloc( sizeof(v3f)*out->vertex_count ); out->indices = malloc( sizeof(i32)*out->indices_count ); + out->uvs = NULL; + out->normals = NULL; v3f *overts = out->vertices; v4f *colours = out->colours; @@ -2272,11 +2271,23 @@ CXR_API void cxr_free_tri_mesh( cxr_tri_mesh *mesh ) free( mesh->colours ); free( mesh->indices ); free( mesh->vertices ); + free( mesh->normals ); + free( mesh->uvs ); free( mesh ); } CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src, i32 *perrcode ) { + /* Make sure data is in the mesh and isn't empty */ + if( !src->edge_count || !src->loop_count || !src->poly_count ) + { + cxr_log( "Error %d\n", k_soliderr_invalid_input ); + if( perrcode ) + *perrcode = k_soliderr_invalid_input; + + return NULL; + } + u32 error = 0x00; cxr_world *world = malloc( sizeof(*world) ); @@ -2746,6 +2757,13 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, } } + /* Collect alphas from loops. This discards hard blend information */ + for( int i=0; iabloops.count; i++ ) + { + cxr_loop *loop = &mesh->loops[i]; + vertinfo[loop->index].alpha = loop->alpha * 255.0; + } + v3f refv, refu, refn; v3_zero(refv); v3_zero(refu); v3_zero(refn); @@ -2948,6 +2966,8 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, if( !newvert ) { + free( graph ); + free( vertinfo ); return 0; } } @@ -3010,9 +3030,6 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, } } -#ifdef CXR_DEBUG - cxr_log( "Broken displacement!\n" ); -#endif free( graph ); free( vertinfo ); return 0; @@ -3064,6 +3081,8 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, v3_muladds( face_center, refn, 1.5, pn ); v3_muladds( face_center, refv, 1.5, pv ); v3_muladds( face_center, refu, 1.5, pu ); + + v3_muladds( face_center, refn, 2.0, face_center ); } /* Create world coordinates */ @@ -3113,6 +3132,7 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, v3f normals[25]; double distances[25]; + double alphas[25]; v3f lside0, lside1, lref, vdelta, vworld; double tx, ty; @@ -3137,6 +3157,8 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, v3_copy( vdelta, normals[index] ); v3_normalize( normals[index] ); distances[index] = v3_dot( vdelta, normals[index] ); + + alphas[index] = vertinfo[grid[index]].alpha; } } @@ -3183,6 +3205,11 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, cxr_vdf_karrdouble( output, "row", k, &distances[k*5], 5 ); cxr_vdf_edon( output ); + cxr_vdf_node( output, "alphas" ); + for( int k=0; k<5; k++ ) + cxr_vdf_karrdouble( output, "row", k, &alphas[k*5], 5 ); + cxr_vdf_edon( output ); + /* * TODO: This might be needed for the compilers. Opens fine in * hammer @@ -3201,11 +3228,6 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, "\"row%d\" \"0 0 1 0 0 1 0 0 1 0 0 1 0 0 1\"\n", k ); cxr_vdf_edon( output ); - cxr_vdf_node( output, "alphas" ); - for( int k=0; k<5; k++ ) - cxr_vdf_printf( output, "\"row%d\" \"0 0 0 0 0\"\n", k ); - cxr_vdf_edon( output ); - cxr_vdf_node( output, "triangle_tags" ); for( int k=0; k<5-1; k++ ) cxr_vdf_printf( output, @@ -3227,7 +3249,8 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world, cxr_vdf_node( output, "editor"); cxr_vdf_colour255( output, "color", colours_random[cxr_range(ctx->brush_count,8)]); - + + cxr_vdf_ki32( output, "visgroupid", ctx->visgroupid ); cxr_vdf_ki32( output, "visgroupshown",1); cxr_vdf_ki32( output, "visgroupautoshown",1); cxr_vdf_edon( output ); @@ -3257,6 +3280,15 @@ CXR_API void cxr_begin_vmf( cxr_vmf_context *ctx, cxr_vdf *output ) cxr_vdf_edon( output ); cxr_vdf_node( output, "visgroups" ); + + for( int i=0; ivisgroup_count; i++ ) + { + cxr_vdf_node( output, "visgroup" ); + cxr_vdf_kv( output, "name", ctx->visgroups[i].name ); + cxr_vdf_ki32( output, "visgroupid", i+1 ); + cxr_vdf_edon( output ); + } + cxr_vdf_edon( output ); cxr_vdf_node( output, "viewsettings" ); @@ -3302,7 +3334,10 @@ CXR_API void cxr_push_world_vmf( cxr_world *world, cxr_vmf_context *ctx, if( solid->displacement ) { - cxr_write_disp( solid->pmesh, world, ctx, output ); + if( !cxr_write_disp( solid->pmesh, world, ctx, output ) ) + { + cxr_log( "Warning: Invalid displacement\n" ); + } continue; } @@ -3361,6 +3396,7 @@ CXR_API void cxr_push_world_vmf( cxr_world *world, cxr_vmf_context *ctx, cxr_vdf_colour255( output, "color", colours_random[cxr_range(ctx->brush_count,8)]); + cxr_vdf_ki32( output, "visgroupid", ctx->visgroupid ); cxr_vdf_ki32( output, "visgroupshown", 1 ); cxr_vdf_ki32( output, "visgroupautoshown", 1 ); cxr_vdf_edon( output ); @@ -3473,5 +3509,6 @@ CXR_API int cxr_lightpatch_bsp( const char *path ) return 1; } + #endif /* CXR_VALVE_MAP_FILE */ #endif /* CXR_IMPLEMENTATION */