fixed aabb transform func
[csRadar.git] / vmf.h
diff --git a/vmf.h b/vmf.h
index 887fe849b9da5e684a0286ee7d2b4a754ca8684b..ff3804d8c29691add5a67d82ba4f2eb64305f4e4 100644 (file)
--- a/vmf.h
+++ b/vmf.h
@@ -1,4 +1,7 @@
 #define SOLID_MAX_SIDES 512
+#define VMF_FLAG_IS_PROP 0x1
+#define VMF_FLAG_IS_INSTANCE 0x2
+#define VMF_FLAG_BRUSH_ENT 0x4
 
 typedef struct vmf_solid vmf_solid;
 typedef struct vmf_vert vmf_vert;
@@ -67,12 +70,22 @@ struct vmf_map
                u32     hash;
                
                vdf_node *root;
+               
+               m4x3f transform;
        }
        *cache;
+       
+       m4x3f transform;
 };
 
 // IMPLEMENTATION
 
+void solidgen_ctx_reset( vmf_solid *ctx )
+{
+       csr_sb_clear( ctx->verts );
+       csr_sb_clear( ctx->indices );
+}
+
 void solidgen_ctx_init( vmf_solid *ctx )
 {
        const u32 init_size = 128;
@@ -88,27 +101,20 @@ void solidgen_ctx_free( vmf_solid *ctx )
 }
 
 // Compute bounds of solid gen ctx
-void solidgen_bounds( vmf_solid *ctx, u32 start, u32 end, v3f min, v3f max )
+void solidgen_bounds( vmf_solid *ctx, boxf box )
 {
        v3f mine = { INFINITY, INFINITY, INFINITY };
        v3f maxe = {-INFINITY,-INFINITY,-INFINITY };
 
-       for( int i = start; i < end; i ++ )
+       for( int i = 0; i < csr_sb_count( ctx->verts ); i ++ )
        {
                vmf_vert *vert = ctx->verts + i;
-               float *co = vert->co;
-               
-               mine[0] = fminf( mine[0], co[0] );
-               mine[1] = fminf( mine[1], co[1] );
-               mine[2] = fminf( mine[2], co[2] );
-               
-               maxe[0] = fmaxf( maxe[0], co[0] );
-               maxe[1] = fmaxf( maxe[1], co[1] );
-               maxe[2] = fmaxf( maxe[2], co[2] );
+               v3_minv( mine, vert->co, mine );
+               v3_maxv( maxe, vert->co, maxe );
        }
        
-       v3_copy( mine, min );
-       v3_copy( maxe, max );
+       v3_copy( mine, box[0] );
+       v3_copy( maxe, box[1] );
 }
 
 struct
@@ -282,6 +288,9 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node )
        // TODO: What is this for again? surely it should be the other way around... i think...
        if( solid_has_displacement( node ) )
        {
+               is_displacement = 1;
+               /*
+       
                printf( "solid_has_displacement\n" );
                num_planes = vmf_api.bisectors;
        
@@ -296,6 +305,7 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node )
                }
                
                is_displacement = 1;
+               */
        }
        
        int it = 0; 
@@ -571,12 +581,17 @@ u32 vmf_get_mdl( vmf_map *map, const char *mdl )
        return 0;
 }
 
+int vmf_class_is_prop( vdf_node *ent )
+{
+       return !strncmp( kv_get( ent, "classname", "" ), "prop_", 5 );
+}
+
 void vmf_populate_models( vdf_node *vmf, vmf_map *map )
 {
        vdf_foreach( vmf, "entity", ent )
        {
                // Use any class name with prop_
-               if( !strncmp( kv_get( ent, "classname", "" ), "prop_", 5 ))
+               if( vmf_class_is_prop( ent ) )
                {
                        // Check if it exists
                        const char *model_path = kv_get( ent, "model", "" );
@@ -596,7 +611,8 @@ void vmf_populate_models( vdf_node *vmf, vmf_map *map )
                        }
                        
                        // Assign prop-ID for later use
-                       ent->user = mdl_id;
+                       ent->user = VMF_FLAG_IS_PROP;
+                       ent->user1 = mdl_id;
                }
        }
 }
@@ -619,7 +635,7 @@ void vmf_load_models( vmf_map *map )
                vmf_populate_models( map->cache[i].root, map );
        }
        
-       printf( "Indexed (%u) models\n", csr_sb_count( map->models ) );
+       printf( "Indexed (%u) models\n", csr_sb_count( map->models )-1 );
        
        u32 num_success = 0;
        
@@ -627,20 +643,22 @@ void vmf_load_models( vmf_map *map )
        // TODO: Make nice loading bar
        for( int i = 1; i < csr_sb_count( map->models ); i ++ )
        {
-               printf( "Load model (%d)\n", i );
-               
                struct vmf_model *mdl = &map->models[i];
                
                if( mdl_from_find_files( mdl->str, &mdl->mdl ) )
                {
                        num_success ++;
                }
+               else
+               {
+                       fprintf( stderr, "Failed to load model: %s\n", mdl->str );
+               }
        }
        
-       printf( "Done (%u of %u loaded)\n", num_success, csr_sb_count( map->models ) );
+       printf( "Done (%u of %u loaded)\n", num_success, csr_sb_count( map->models )-1 );
 }
 
-void vmf_init_subvmf( vmf_map *map, const char *subvmf );
+u32 vmf_init_subvmf( vmf_map *map, const char *subvmf );
 
 void vmf_load_all_instances( vmf_map *map, vdf_node *vmf )
 {
@@ -652,32 +670,39 @@ void vmf_load_all_instances( vmf_map *map, vdf_node *vmf )
                        const char *path = kv_get( ent, "file", "" );
                        if( strcmp( path, "" ) )
                        {
-                               vmf_init_subvmf( map, path );
+                               if( (ent->user1 = vmf_init_subvmf( map, path )))
+                               {
+                                       ent->user1 --;
+                                       ent->user = VMF_FLAG_IS_INSTANCE;
+                               }
                        }
                }
        }
 }
 
-void vmf_init_subvmf( vmf_map *map, const char *subvmf )
+// TODO: Merge this into above function.. doesnt need to be seperated
+u32 vmf_init_subvmf( vmf_map *map, const char *subvmf )
 {
-       printf( "Loading subvmf: %s\n", subvmf );
-       
+       u32 id;
        u32 hash = djb2( (const unsigned char *)subvmf );
        
        // Check if present
-       for( int i = 0; i < csr_sb_count( map->cache ); i ++ )
+       for( u32 i = 0; i < csr_sb_count( map->cache ); i ++ )
        {
                if( hash == map->cache[i].hash )
                {
                        if( !strcmp( map->cache[i].name, subvmf ) )
                        {
-                               return;
+                               return i+1;
                        }
                }
        }
        
+       printf( "Loading subvmf: %s\n", subvmf );
+       
+       id = csr_sb_count( map->cache );
        map->cache = csr_sb_reserve( map->cache, 1, sizeof( struct vmf_instance ));
-       struct vmf_instance *inst = &map->cache[ csr_sb_count( map->cache ) ];
+       struct vmf_instance *inst = &map->cache[ id ];
        
        if( (inst->root = vdf_open_file( subvmf )) )
        {
@@ -689,12 +714,13 @@ void vmf_init_subvmf( vmf_map *map, const char *subvmf )
                
                // Recursive load other instances
                vmf_load_all_instances( map, inst->root );
+               
+               return id+1;
        }
        else
        {
-               // TODO: Don't die here?
                fprintf( stderr, "Failed to load instance file\n" );
-               exit(0);
+               return 0;
        }
 }
 
@@ -703,6 +729,12 @@ vmf_map *vmf_init( const char *path, int load_models )
        vmf_map *map = csr_calloc( sizeof( vmf_map ) );
        map->root = vdf_open_file( path );
        
+       if( !map->root )
+       {
+               free( map );
+               return NULL;
+       }
+       
        // Prepare instances
        vmf_load_all_instances( map, map->root );
        
@@ -779,3 +811,60 @@ void solidgen_to_obj( vmf_solid *ctx, const char *path )
                fprintf( stderr, "Could not open %s for writing\n", path );
        }
 }
+
+void vmf_entity_transform( vdf_node *ent, m4x3f mat )
+{
+       v3f angles = {0.f,0.f,0.f};
+       v3f offset = {0.f,0.f,0.f};
+       float scale;
+       
+       // Parse
+       scale = kv_get_float( ent, "uniformscale", 1.f );
+       kv_float_array( ent, "angles", 3, angles );
+       kv_float_array( ent, "origin", 3, offset );
+       
+       // Translation
+       m4x3_translate( mat, offset );
+       
+       // Make rotation ( Pitch yaw roll // YZX. Source->OpenGL ordering a lil messed up )
+       m4x3_rotate_z( mat, csr_rad( angles[1] ) );
+       m4x3_rotate_y( mat, csr_rad( angles[0] ) );
+       m4x3_rotate_x( mat, csr_rad( angles[2] ) );
+       
+       // Scale
+       m4x3_scale( mat, scale );
+}
+
+u32 vmf_visgroup_id( vdf_node *root, const char *name )
+{
+       vdf_node *dict = vdf_next( root, "visgroups", NULL );
+       
+       if( dict )
+       {
+               vdf_foreach( dict, "visgroup", group )
+               {
+                       if( !strcmp( kv_get( group, "name", "" ), name ) )
+                       {
+                               return kv_get_int( group, "visgroupid", 0 );
+                       }
+               }
+       }
+       
+       return 0;
+}
+
+int vmf_visgroup_match( vdf_node *ent, u32 target )
+{
+       vdf_node *editor = vdf_next( ent, "editor", NULL );
+       
+       if( editor )
+       {
+               kv_foreach( editor, "visgroupid", groupe )
+               {
+                       if( target == atoi( groupe ) )
+                               return 1;
+               }
+       }
+       
+       return 0;
+}