fixed instance loading forget to append basepath.. other path fixes (windows)
[csRadar.git] / vmf.h
diff --git a/vmf.h b/vmf.h
index 4829d48174599bb6906c802e0cfeef0446d3a20c..740a3749da0af94070dabd7da5077aaae7ac8197 100644 (file)
--- a/vmf.h
+++ b/vmf.h
@@ -1,7 +1,8 @@
-#define SOLID_MAX_SIDES 512
-#define VMF_FLAG_IS_PROP 0x1
-#define VMF_FLAG_IS_INSTANCE 0x2
-#define VMF_FLAG_BRUSH_ENT 0x4
+// This software is not affiliated with Valve Corporation
+//   We are not affiliated, associated, authorized, endorsed by, or in any way officially 
+//   connected with Valve Corporation, or any of its subsidiaries or its affiliates. 
+// 
+//   All trademarks are property of their respective owners
 
 typedef struct vmf_solid vmf_solid;
 typedef struct vmf_vert vmf_vert;
@@ -12,6 +13,53 @@ typedef struct vmf_map vmf_map;
 
 typedef enum ESolidResult ESolidResult;
 
+// API
+//=======================================================================================================================
+
+// Load vmf from disk
+vmf_map *vmf_init( const char *path );
+void vmf_free( vmf_map *map );
+
+// Solidgen API ~ Converting brushes into meshes
+// ---------------------------------------------
+void solidgen_ctx_init( vmf_solid *ctx );
+void solidgen_ctx_reset( vmf_solid *ctx );
+void solidgen_ctx_free( vmf_solid *ctx );
+void solidgen_bounds( vmf_solid *ctx, boxf box );
+
+ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node );
+
+// General VMF
+// -----------
+int solid_has_displacement( vdf_node *node );
+int vmf_class_is_prop( vdf_node *ent );
+
+// Build the list of all models used in this map, including instances
+void vmf_index_models( vmf_map *map );
+
+// Loads all models that have the resource flagged with need_load
+void vmf_load_models( vmf_map *map );
+
+// Create matrix describing this entities transform
+void vmf_entity_transform( vdf_node *ent, m4x3f mat );
+
+int vmf_visgroup_id( vdf_node *root, const char *name );
+int vmf_visgroup_match( vdf_node *ent, u32 target );
+
+// Currently unused
+//void vmf_addbisector( double p[4] );
+//void vmf_clearbisectors( void );
+//void vmf_ignore_mat( const char *material );
+//void vmf_clearignore( void );
+
+// Implementation
+//=======================================================================================================================
+
+#define SOLID_MAX_SIDES 512
+#define VMF_FLAG_IS_PROP 0x1
+#define VMF_FLAG_IS_INSTANCE 0x2
+#define VMF_FLAG_BRUSH_ENT 0x4
+
 enum ESolidResult
 {
        k_ESolidResult_valid,
@@ -26,7 +74,7 @@ struct vmf_vert
 {
        v3f     co;
        v3f     nrm;
-       v2f     xy;
+       v3f     origin;
 };
 
 struct vmf_face
@@ -80,7 +128,7 @@ struct vmf_map
        m4x3f transform;
 };
 
-// IMPLEMENTATION
+#ifdef VALVE_IMPLEMENTATION
 
 void solidgen_ctx_reset( vmf_solid *ctx )
 {
@@ -374,7 +422,7 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node )
        v3_divs( center, (float)numpoints, center );
        for( ; vert_start < csr_sb_count( ctx->verts ); vert_start ++ )
        {
-               v2_copy( center, ctx->verts[ vert_start ].xy );
+               v3_copy( center, ctx->verts[ vert_start ].origin );
        }
        
        // Sort each faces and trianglulalate them
@@ -474,6 +522,9 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node )
                                                
                                                // Todo, put correct normal
                                                v3_copy( (v3f){ 0.f, 0.f, 1.f }, vert->nrm );
+                                               
+                                               // Todo: use real bounds of displaced vertices
+                                               v3_copy( center, vert->origin );
                                        }
                                }
                                
@@ -644,15 +695,24 @@ u32 vmf_init_subvmf( vmf_map *map, const char *subvmf );
 
 void vmf_load_all_instances( vmf_map *map, vdf_node *vmf )
 {
+       char nextvmf[ 512 ];
+       const char *base = kv_get( vmf, "csr_path", "" );
+
        vdf_foreach( vmf, "entity", ent )
        {
                if( !strcmp( kv_get( ent, "classname", "" ), "func_instance" ))
                {
                        // Entity is in use if file is specified, if not just ignore the entity.
-                       const char *path = kv_get( ent, "file", "" );
-                       if( strcmp( path, "" ) )
+                       const char *path = kv_get( ent, "file", NULL );
+                       
+                       if( path )
                        {
-                               if( (ent->user1 = vmf_init_subvmf( map, path )))
+                               // Make relative path real
+                               strcpy( nextvmf, base );
+                               csr_downlvl( nextvmf );
+                               strcat( nextvmf, path );
+                               
+                               if( (ent->user1 = vmf_init_subvmf( map, nextvmf )))
                                {
                                        ent->user1 --;
                                        ent->user = VMF_FLAG_IS_INSTANCE;
@@ -693,7 +753,9 @@ u32 vmf_init_subvmf( vmf_map *map, const char *subvmf )
        strcpy( inst->name, subvmf );
        
        if( (inst->root = vdf_open_file( subvmf )) )
-       {               
+       {
+               vdf_kv_append( inst->root, "csr_path", subvmf );
+               
                // Recursive load other instances
                vmf_load_all_instances( map, inst->root );      
                return id+1;
@@ -716,6 +778,8 @@ vmf_map *vmf_init( const char *path )
                return NULL;
        }
        
+       vdf_kv_append( map->root, "csr_path", path );
+       
        // Prepare instances
        vmf_load_all_instances( map, map->root );
        
@@ -769,7 +833,7 @@ void vmf_entity_transform( vdf_node *ent, m4x3f mat )
        m4x3_scale( mat, scale );
 }
 
-u32 vmf_visgroup_id( vdf_node *root, const char *name )
+int vmf_visgroup_id( vdf_node *root, const char *name )
 {
        vdf_node *dict = vdf_next( root, "visgroups", NULL );
        
@@ -784,7 +848,7 @@ u32 vmf_visgroup_id( vdf_node *root, const char *name )
                }
        }
        
-       return 0;
+       return -1;
 }
 
 int vmf_visgroup_match( vdf_node *ent, u32 target )
@@ -802,3 +866,5 @@ int vmf_visgroup_match( vdf_node *ent, u32 target )
        
        return 0;
 }
+
+#endif