the asumptions were of course, incorrect
[convexer.git] / cxr / cxr.h
index 1f1c649d88b533e95e32c895d1f1be6d76bca4b2..644c8ed83e39381e88ceb5c3beeb4772e29f3be3 100644 (file)
--- a/cxr/cxr.h
+++ b/cxr/cxr.h
@@ -1,11 +1,13 @@
 /*
-                              CONVEXER v0.91
+                              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
@@ -46,7 +48,6 @@
    IMPLEMENTATION
 */
 
-#define CXR_API
 #define CXR_EPSILON 0.001
 #define CXR_PLANE_SIMILARITY_MAX 0.998
 #define CXR_BIG_NUMBER 1e300
 
 #include <stdio.h>
 #include <math.h>
-#include <stdint.h>
-#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 
-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;
@@ -157,6 +144,7 @@ struct cxr_static_mesh
       i32 index,
           edge_index;
       v2f uv;
+      double alpha;
    }
    *loops;
 
@@ -190,6 +178,7 @@ struct cxr_loop
        edge_index,
        index;
    v2f uv;
+   float alpha;
 };
 
 struct cxr_solid
@@ -228,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;
@@ -303,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)
 {
@@ -380,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 )
@@ -505,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; i<src->loop_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" );
 
@@ -2075,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;
@@ -2203,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;
@@ -2284,6 +2271,8 @@ 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 );
 }
 
@@ -2768,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; i<mesh->abloops.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);
    
@@ -2970,6 +2966,8 @@ static int cxr_write_disp( cxr_mesh *mesh, cxr_world *world,
 
             if( !newvert )
             {
+               free( graph );
+               free( vertinfo );
                return 0;
             }
          }
@@ -3032,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;
@@ -3137,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;
@@ -3161,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;
             }
          }
 
@@ -3207,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
@@ -3225,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, 
@@ -3336,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;
       }
       
@@ -3508,5 +3509,6 @@ CXR_API int cxr_lightpatch_bsp( const char *path )
 
    return 1;
 }
+
 #endif /* CXR_VALVE_MAP_FILE */
 #endif /* CXR_IMPLEMENTATION */