world regions
authorhgn <hgodden00@gmail.com>
Sat, 25 Nov 2023 05:13:26 +0000 (05:13 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 25 Nov 2023 05:13:26 +0000 (05:13 +0000)
15 files changed:
blender_export.py
ent_miniworld.c
ent_region.c [new file with mode: 0644]
ent_region.h [new file with mode: 0644]
entity.c
entity.h
maps_src/mp_mtzero/main.mdl
world.h
world_entity.c
world_gen.c
world_load.c
world_render.c
world_routes.c
world_routes_ui.c
world_routes_ui.h

index 8b0bd104b88aef9a9ab0a9b747423b6a0810181d..b49bf48553a6886d58ab57dc7dc3876aba21d699 100644 (file)
@@ -41,13 +41,15 @@ sr_entity_list = [
    ('ent_challenge',    'Challenge',      '', 19 ),
    ('ent_relay',        'Relay',          '', 20 ),
    ('ent_miniworld',    'Mini World',     '', 22 ),
-   ('ent_prop',         'Prop',           '', 23 )
+   ('ent_prop',         'Prop',           '', 23 ),
+   ('ent_list',         'Entity List',    '', 24 ),
+   ('ent_region',       'Region',         '', 25 )
 ]
 
 MDL_VERSION_NR = 104
 SR_TRIGGERABLE = [ 'ent_audio', 'ent_ccmd', 'ent_gate', 'ent_challenge', \
                    'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route',\
-                   'ent_miniworld' ]
+                   'ent_miniworld', 'ent_region' ]
 
 def get_entity_enum_id( alias ):
 #{
@@ -273,6 +275,10 @@ class ent_route(Structure):
    sr_functions = { 0: 'view' }
 #}
 
+class ent_list(Structure):#{
+   _fields_ = [("start",c_uint16),("count",c_uint16)]
+#}
+
 class ent_water(Structure):
 #{
    _fields_ = [("transform",mdl_transform),
@@ -516,6 +522,15 @@ class ent_challenge(Structure):#{
                     1: 'view/reset' }
 #}
 
+class ent_region(Structure):#{
+   _fields_ = [("transform",mdl_transform),
+               ("submesh_start",c_uint32), ("submesh_count",c_uint32),
+               ("pstr_title",c_uint32),
+               ("flags",c_uint32),
+               ("zone_volume",c_uint32)]
+   sr_functions = { 0: 'enter', 1: 'leave' }
+#}
+
 class ent_relay(Structure):#{
    _fields_ = [("targets",(c_uint32*2)*4),
                ("targets_events",c_uint32*4)]
@@ -1690,6 +1705,7 @@ def sr_compile( collection ):
          if ent_type == 'ent_font_variant': continue
          if ent_type == 'ent_menuitem': continue
          if ent_type == 'ent_objective': continue
+         if ent_type == 'ent_region': continue
 
          #TODO: This is messy.
          if ent_type == 'ent_gate':#{
@@ -1960,6 +1976,16 @@ def sr_compile( collection ):
             challenge.status = 0
             sr_ent_push( challenge )
          #}
+         elif ent_type == 'ent_region':#{
+            region = ent_region()
+            obj_data = obj.SR_data.ent_region[0]
+            compile_obj_transform( obj, region.transform )
+            region.submesh_start, region.submesh_count, _ = \
+                  sr_compile_mesh_internal( obj )
+            region.pstr_title = sr_compile_string( obj_data.title )
+            region.zone_volume = sr_entity_id( obj_data.zone_volume )
+            sr_ent_push( region )
+         #}
          elif ent_type == 'ent_relay':#{
             relay = ent_relay()
             obj_data = obj.SR_data.ent_relay[0]
@@ -2986,6 +3012,66 @@ class SR_OBJECT_ENT_ROUTE(bpy.types.PropertyGroup):
    #}
 #}
 
+
+class SR_OT_ENT_LIST_NEW_ITEM(bpy.types.Operator):#{
+   bl_idname = "skaterift.ent_list_new_entry"
+   bl_label = "Add entity"
+   
+   def execute(self, context):#{
+      return internal_listadd_execute(self,context,'ent_list','entities')
+   #}
+#}
+
+class SR_OT_ENT_LIST_DEL_ITEM(bpy.types.Operator):#{
+   bl_idname = "skaterift.ent_list_del_entry"
+   bl_label = "Remove entity"
+
+   @classmethod 
+   def poll(cls, context):#{
+      active_object = context.active_object
+      if obj_ent_type(active_object) == 'ent_list':#{
+         return active_object.SR_data.ent_list[0].entities
+      #}
+      else: return False
+   #}
+   
+   def execute(self, context):#{
+      return internal_listdel_execute(self,context,'ent_list','entities')
+   #}
+#}
+
+class SR_OBJECT_ENT_LIST_ENTRY(bpy.types.PropertyGroup):
+#{
+   target: bpy.props.PointerProperty( \
+               type=bpy.types.Object, name='target' )
+#}
+
+class SR_UL_ENT_LIST(bpy.types.UIList):#{
+   bl_idname = 'SR_UL_ENT_LIST'
+
+   def draw_item(_,context,layout,data,item,icon,active_data,active_propname):#{
+      layout.prop( item, 'target', text='', emboss=False )
+   #}
+#}
+
+class SR_OBJECT_ENT_LIST(bpy.types.PropertyGroup):#{
+   entities: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_LIST_ENTRY)
+   entities_index: bpy.props.IntProperty()
+
+   @staticmethod
+   def sr_inspector( layout, data ):#{
+      layout.label( text='Entities' )
+      layout.template_list('SR_UL_ENT_LIST', 'Entities', \
+                            data[0], 'entities', data[0], \
+                            'entities_index', rows=5)
+
+      row = layout.row()
+      row.operator( 'skaterift.ent_list_new_entry', text='Add' )
+      row.operator( 'skaterift.ent_list_del_entry', text='Remove' )
+   #}
+#}
+
+
 class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{
    subtype: bpy.props.EnumProperty(
       name="Subtype",
@@ -3400,6 +3486,13 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{
    #}
 #}
 
+class SR_OBJECT_ENT_REGION(bpy.types.PropertyGroup):#{
+   title: bpy.props.StringProperty( name="Title" )
+   zone_volume: bpy.props.PointerProperty(
+            type=bpy.types.Object, name="Zone Volume", \
+            poll=lambda self,obj: sr_filter_ent_type(obj,['ent_volume']))
+#}
+
 class SR_OBJECT_ENT_RELAY(bpy.types.PropertyGroup):#{
    target0: bpy.props.PointerProperty( \
             type=bpy.types.Object, name="Target 0", \
@@ -3447,8 +3540,10 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup):
    ent_ccmd: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CCMD)
    ent_objective: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_OBJECTIVE)
    ent_challenge: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CHALLENGE)
+   ent_region: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_REGION)
    ent_relay: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_RELAY)
    ent_miniworld: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_MINIWORLD)
+   ent_list: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_LIST)
 
    ent_type: bpy.props.EnumProperty(
       name="Type",
@@ -4683,7 +4778,10 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\
             SR_OBJECT_ENT_WORKSHOP_PREVIEW,SR_OBJECT_ENT_MENU_ITEM,\
             SR_OBJECT_ENT_WORLD_INFO,SR_OBJECT_ENT_CCMD,\
             SR_OBJECT_ENT_OBJECTIVE,SR_OBJECT_ENT_CHALLENGE,\
+            SR_OBJECT_ENT_REGION,\
             SR_OBJECT_ENT_RELAY,SR_OBJECT_ENT_MINIWORLD,\
+            SR_OBJECT_ENT_LIST_ENTRY, SR_UL_ENT_LIST, SR_OBJECT_ENT_LIST, \
+            SR_OT_ENT_LIST_NEW_ITEM, SR_OT_ENT_LIST_DEL_ITEM,\
             \
             SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, 
             SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \
index 497e9d04f9da65652edd4e370cc26ad31c95713d..024fa6c0bc9153ad76d2075d7453efea57d74cd9 100644 (file)
@@ -117,11 +117,11 @@ static void ent_miniworld_render( world_instance *host_world, camera *cam ){
    for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
       ent_route *route = mdl_arritm( &dest_world->ent_route, i );
 
-      if( route->achievment_status & 0x2 ){
+      if( route->flags & k_ent_route_flag_achieve_gold ){
          miniworld_icon( cam, k_gui_icon_rift_run_gold, 
                          route->board_transform[3],1.0f);
       }
-      else if( route->achievment_status & 0x1 ){
+      else if( route->flags & k_ent_route_flag_achieve_silver ){
          miniworld_icon( cam, k_gui_icon_rift_run_silver, 
                          route->board_transform[3],1.0f);
       }
diff --git a/ent_region.c b/ent_region.c
new file mode 100644 (file)
index 0000000..720cb3c
--- /dev/null
@@ -0,0 +1,75 @@
+#include "ent_region.h"
+#include "gui.h"
+
+static void ent_region_call( world_instance *world, ent_call *call ){
+   ent_region *region = 
+      mdl_arritm( &world->ent_region, mdl_entity_id_id(call->id) );
+
+   if( !region->zone_volume )
+      return;
+
+   ent_volume *volume = 
+      mdl_arritm( &world->ent_volume, mdl_entity_id_id(region->zone_volume) );
+
+   if( call->function == 0 ){ /* enter */
+      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i ++ ){
+         ent_route *route = mdl_arritm( &world->ent_route, i );
+
+         v3f local;
+         m4x3_mulv( volume->to_local, route->board_transform[3], local );
+         if( (fabsf(local[0]) <= 1.0f) &&
+             (fabsf(local[1]) <= 1.0f) &&
+             (fabsf(local[2]) <= 1.0f) ){
+            route->flags &= ~k_ent_route_flag_out_of_zone;
+         }
+         else {
+            route->flags |= k_ent_route_flag_out_of_zone;
+         }
+      }
+
+      gui_location_print_ccmd( 1, (const char *[]){
+            mdl_pstr(&world->meta,region->pstr_title)} );
+   }
+   else if( call->function == 1 ){ /* leave */
+      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i ++ ){
+         ent_route *route = mdl_arritm( &world->ent_route, i );
+         route->flags |= k_ent_route_flag_out_of_zone;
+      }
+   }
+}
+
+/* 
+ * reevaluate all achievements to calculate the compiled achievement
+ */
+static void ent_region_re_eval( world_instance *world ){
+   for( u32 i=0; i<mdl_arrcount(&world->ent_region); i ++ ){
+      ent_region *region = mdl_arritm(&world->ent_region, i);
+
+      if( !region->zone_volume )
+         continue;
+
+      ent_volume *volume = mdl_arritm(&world->ent_volume,
+            mdl_entity_id_id(region->zone_volume));
+
+      u32 combined = k_ent_route_flag_achieve_gold | 
+                     k_ent_route_flag_achieve_silver;
+
+      for( u32 j=0; j<mdl_arrcount(&world->ent_route); j ++ ){
+         ent_route *route = mdl_arritm(&world->ent_route, j );
+
+         v3f local;
+         m4x3_mulv( volume->to_local, route->board_transform[3], local );
+         if( !((fabsf(local[0]) <= 1.0f) &&
+               (fabsf(local[1]) <= 1.0f) &&
+               (fabsf(local[2]) <= 1.0f)) ){
+            continue;
+         }
+
+         combined &= route->flags;
+      }
+
+      region->flags = combined;
+
+      /* TODO: Challenges */
+   }
+}
diff --git a/ent_region.h b/ent_region.h
new file mode 100644 (file)
index 0000000..9a1fb3c
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef ENT_REGION_H
+#define ENT_REGION_H
+
+#include "world_entity.h"
+
+#endif /* ENT_REGION_H */
index 85557b1763f72d009bc2ce3327e8b9ac9e6e7e26..59e9219abcfe58a7baaab9a574b19c5b83091b16 100644 (file)
--- a/entity.c
+++ b/entity.c
@@ -12,6 +12,7 @@
 #include "ent_route.c"
 #include "ent_portal.c"
 #include "ent_miniworld.c"
+#include "ent_region.c"
 
 typedef void (*fn_entity_call_handler)( world_instance *, ent_call *);
 
@@ -28,7 +29,8 @@ static void entity_call( world_instance *world, ent_call *call ){
       [k_ent_relay]     = ent_relay_call,
       [k_ent_challenge] = ent_challenge_call,
       [k_ent_route]     = ent_route_call,
-      [k_ent_miniworld] = ent_miniworld_call
+      [k_ent_miniworld] = ent_miniworld_call,
+      [k_ent_region]    = ent_region_call
    };
 
    if( type >= vg_list_size(table) ){
index 3fd3508eef3358ff47766b73ef2ad11cc0dddbc0..0e65c268a6c81f71ac05bb306f688532e2318ffe 100644 (file)
--- a/entity.h
+++ b/entity.h
@@ -32,6 +32,7 @@ typedef struct ent_relay ent_relay;
 typedef struct ent_cubemap ent_cubemap;
 typedef struct ent_miniworld ent_miniworld;
 typedef struct ent_prop ent_prop;
+typedef struct ent_region ent_region;
 
 enum entity_alias{
    k_ent_none        = 0,
@@ -56,7 +57,10 @@ enum entity_alias{
    k_ent_challenge   = 19,
    k_ent_relay       = 20,
    k_ent_cubemap     = 21,
-   k_ent_miniworld   = 22
+   k_ent_miniworld   = 22,
+   k_ent_prop        = 23,
+   k_ent_list        = 24,
+   k_ent_region      = 25
 };
 
 static u32 mdl_entity_id_type( u32 entity_id ){
@@ -166,10 +170,17 @@ struct ent_checkpoint{
        path_count;
 };
 
+enum ent_route_flag {
+   k_ent_route_flag_achieve_silver = 0x1,
+   k_ent_route_flag_achieve_gold   = 0x2,
+
+   k_ent_route_flag_out_of_zone    = 0x10
+};
+
 struct ent_route{
    union{
       mdl_transform transform;
-      u32 official_track_id;
+      u32 official_track_id;   /* TODO: remove this */
    }
    anon;
 
@@ -191,7 +202,7 @@ struct ent_route{
    u32 id_camera; /* v103+ */
 
    /* v104+, but always accessible */
-   u32 achievment_status;
+   u32 flags;
    f64 best_laptime;
 };
 
@@ -526,6 +537,11 @@ struct ent_prop {
    u32 submesh_start, submesh_count, flags;
 };
 
+struct ent_region {
+   mdl_transform transform;
+   u32 submesh_start, submesh_count, pstr_title, flags, zone_volume;
+};
+
 #include "world.h"
 static void entity_call( world_instance *world, ent_call *call );
 
index 40e488eaa5fe885e69f04add5e3b2a8c28c43624..3f7148dbc438e24b8c983bfad031f552ef4e7b7c 100644 (file)
Binary files a/maps_src/mp_mtzero/main.mdl and b/maps_src/mp_mtzero/main.mdl differ
diff --git a/world.h b/world.h
index ebf18c6a503d37e4c9cddbee202b82b112794d97..9d8cd4970dc8c037d98b30eb03ce5f4d48e844ff 100644 (file)
--- a/world.h
+++ b/world.h
@@ -183,7 +183,8 @@ struct world_instance {
                  ent_relay,
                  ent_cubemap,
                  ent_miniworld,
-                 ent_prop;
+                 ent_prop,
+                 ent_region;
 
    enum skybox {
       k_skybox_default,
index 0e484ed019b2a21fd0983f23812097ca3280b3ee..3fd7ac63473459781b85ed7a348038247eb545a7 100644 (file)
@@ -618,12 +618,6 @@ static void world_entity_start( world_instance *world, vg_msg *sav ){
       }
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, i );
-      route->achievment_status = 0;
-      route->best_laptime = 0.0;
-   }
-
    vg_msg routes_block = *sav;
    if( vg_msg_seekframe( &routes_block, "routes" ) ){
       for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
@@ -632,13 +626,14 @@ static void world_entity_start( world_instance *world, vg_msg *sav ){
          vg_msg route_info = routes_block;
          if( vg_msg_seekframe( &route_info, 
                                mdl_pstr(&world->meta,route->pstr_name) ) ){
-            route->achievment_status = 
-               vg_msg_getkvu32( &route_info, "achivement_status", 0 );
+            route->flags |= vg_msg_getkvu32( &route_info, "flags", 0 );
             route->best_laptime =
                vg_msg_getkvf64( &route_info, "best_laptime", 0.0 );
          }
       }
    }
+
+   ent_region_re_eval( world );
 }
 
 static void world_entity_serialize( world_instance *world, vg_msg *sav ){
@@ -656,7 +651,7 @@ static void world_entity_serialize( world_instance *world, vg_msg *sav ){
          
          vg_msg_frame( sav, mdl_pstr( &world->meta, route->pstr_name ) );
          {
-            vg_msg_wkvu32( sav, "achivement_status", route->achievment_status );
+            vg_msg_wkvu32( sav, "flags", route->flags );
             vg_msg_wkvf64( sav, "best_laptime", route->best_laptime );
          }
          vg_msg_end_frame( sav );
index 51d0302badbeba28a6a7a7d5581f6b426df0348a..4e01de338cfbd70e5e9b4c4319535702825be504 100644 (file)
@@ -287,6 +287,17 @@ static void world_gen_generate_meshes( world_instance *world ){
       }
    }
 
+   /* unpack region models */
+   for( u32 i=0; i<mdl_arrcount( &world->ent_region ); i++ ){
+      ent_region *region = mdl_arritm( &world->ent_region, i );
+
+      for( u32 j=0; j<region->submesh_count; j ++ ){
+         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                       region->submesh_start+j );
+         world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+      }
+   }
+
    /* unpack gate models */
    for( u32 i=0; i<mdl_arrcount( &world->ent_gate ); i++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, i );
index 379a7de3ee60049999f69401b65af7819a44df5b..586b804bdab166092747c428bbfd0c78ac3e331f 100644 (file)
@@ -68,6 +68,7 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    MDL_LOAD_ARRAY( meta, &world->ent_cubemap,   ent_cubemap,    heap );
    MDL_LOAD_ARRAY( meta, &world->ent_miniworld, ent_miniworld,  heap );
    MDL_LOAD_ARRAY( meta, &world->ent_prop,      ent_prop,       heap );
+   MDL_LOAD_ARRAY( meta, &world->ent_region,    ent_region,     heap );
 
    mdl_array_ptr infos;
    MDL_LOAD_ARRAY( meta, &infos, ent_worldinfo, vg_mem.scratch );
index 096de9a99a624717425a5383061430b3d1f273e2..4d5321bc2a2db50a019b8b141845b093a4603c56 100644 (file)
@@ -453,9 +453,8 @@ static void render_world_alphatest( world_instance *world, camera *cam ){
    glEnable(GL_CULL_FACE);
 }
 
-static
-void world_render_challenges( world_instance *world, struct world_pass *pass,
-                              v3f pos ){
+static void world_render_challenges( world_instance *world, 
+                                     struct world_pass *pass, v3f pos ){
    if( !world ) return;
    if( skaterift.activity == k_skaterift_replay ) return;
    if( world != world_current_instance() ) return;
@@ -615,18 +614,21 @@ void world_render_challenges( world_instance *world, struct world_pass *pass,
    }
 }
 
-static void render_world_fxglow( world_instance *world, camera *cam ){
+static void render_world_fxglow( world_instance *host_world, 
+                                 world_instance *world, camera *cam,
+                                 m4x3f world_mmdl,
+                                 int generic, int challenges, int regions ){
    shader_scene_fxglow_use();
    shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } );
    shader_scene_fxglow_uTexMain(1);
    shader_scene_fxglow_uPv( cam->mtx.pv );
 
-   world_link_lighting_ub( world, _shader_scene_fxglow.id );
-   world_bind_position_texture( world, _shader_scene_fxglow.id, 
+   world_link_lighting_ub( host_world, _shader_scene_fxglow.id );
+   world_bind_position_texture( host_world, _shader_scene_fxglow.id, 
                         _uniform_scene_fxglow_g_world_depth, 2 );
-   world_bind_light_array( world, _shader_scene_fxglow.id,
+   world_bind_light_array( host_world, _shader_scene_fxglow.id,
                         _uniform_scene_fxglow_uLightsArray, 3 );
-   world_bind_light_index( world, _shader_scene_fxglow.id,
+   world_bind_light_index( host_world, _shader_scene_fxglow.id,
                            _uniform_scene_fxglow_uLightsIndex, 4 );
 
    shader_scene_fxglow_uCamera( cam->transform[3] );
@@ -640,8 +642,45 @@ static void render_world_fxglow( world_instance *world, camera *cam ){
       .fn_set_uPvmPrev = shader_scene_fxglow_uPvmPrev,
    };
 
-   world_render_both_stages( world, &pass );
-   world_render_challenges( world, &pass, cam->pos );
+   if( generic )
+      world_render_both_stages( world, &pass );
+
+   if( regions ){
+      mesh_bind( &world->mesh_no_collide );
+
+      u32 last_material = 0;
+      for( u32 i=0; i<mdl_arrcount(&world->ent_region); i ++ ){
+         shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } );
+         ent_region *region = mdl_arritm( &world->ent_region, i );
+
+         f32 offset = 0.0f;
+         if( region->flags & k_ent_route_flag_achieve_gold )
+            offset = 2.0f;
+         else if( region->flags & k_ent_route_flag_achieve_silver )
+            offset = 1.0f;
+
+         shader_scene_fxglow_uUvOffset( (v2f){ (8.0f/256.0f)*offset, 0.0f } );
+
+         m4x3f mmdl;
+         mdl_transform_m4x3( &region->transform, mmdl );
+         m4x3_mul( world_mmdl, mmdl, mmdl );
+         shader_scene_fxglow_uMdl( mmdl );
+
+         for( u32 j=0; j<region->submesh_count; j++ ){
+            mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                          region->submesh_start + j );
+
+            if( sm->material_id != last_material ){
+               last_material = sm->material_id;
+               pass.fn_bind_textures(world,&world->surfaces[sm->material_id]);
+            }
+            mdl_draw_submesh( sm );
+         }
+      }
+   }
+
+   if( challenges )
+      world_render_challenges( world, &pass, cam->pos );
 
    glEnable(GL_CULL_FACE);
 }
@@ -922,7 +961,7 @@ static void render_world( world_instance *world, camera *cam,
                                        GL_COLOR_ATTACHMENT1 } );
       }
 
-      render_world_fxglow( world, cam );
+      render_world_fxglow( world, world, cam, NULL, 1, 1, 0 );
    }
    
    if( with_water ){
@@ -1040,6 +1079,8 @@ static void render_world_override( world_instance *world,
    pass.geo_type = k_world_geo_type_nonsolid;
    render_world_override_pass( world, &pass, mmdl, mnormal, mpvm_prev );
    glEnable( GL_CULL_FACE );
+
+   render_world_fxglow( world, world, cam, mmdl, 0, 0, 1 );
 }
 
 static void render_cubemap_side( world_instance *world, ent_cubemap *cm, 
index 4deccaa754308cbc8566123243b05ee3c0e32d6e..d81419f252852de5e4c575efc41a2656b4f2936e 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "shaders/scene_route.h"
 #include "shaders/routeui.h"
+#include "ent_region.h"
 
 static void world_routes_clear( world_instance *world )
 {
@@ -96,12 +97,12 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ){
 
       if( (route->best_laptime == 0.0) || (lap_time < route->best_laptime) ){
          route->best_laptime = lap_time;
-         route->achievment_status |= 0x1;
-
-         if( clean )
-            route->achievment_status |= 0x2;
       }
 
+      route->flags |= k_ent_route_flag_achieve_silver;
+      if( clean ) route->flags |= k_ent_route_flag_achieve_gold;
+      ent_region_re_eval( world );
+
       /* for steam achievements. */
       if( route->anon.official_track_id != 0xffffffff ){
          struct track_info *ti = &track_infos[ route->anon.official_track_id ];
@@ -542,6 +543,12 @@ static void world_gen_routes_ent_init( world_instance *world ){
       ent_route *route = mdl_arritm(&world->ent_route,i);
       mdl_transform_m4x3( &route->anon.transform, route->board_transform );
 
+      route->flags = 0x00;
+      route->best_laptime = 0.0;
+      
+      if( mdl_arrcount(&world->ent_region) )
+         route->flags |= k_ent_route_flag_out_of_zone;
+
       route->anon.official_track_id = 0xffffffff;
       for( u32 j=0; j<vg_list_size(track_infos); j ++ ){
          if( !strcmp(track_infos[j].name, 
index 7becb73dec665e210f7f5ffb89df1e9c5a5eacb4..9ccad800ec2a7f3ceb5fe7804b110366607d0650 100644 (file)
@@ -13,6 +13,9 @@ static u32 v4_rgba( v4f colour ){
 
 static void ent_route_imgui( world_instance *world, ent_route *route, 
                              ui_point inout_cursor ){
+   if( route->flags & k_ent_route_flag_out_of_zone )
+      return;
+
    u32 last_version=0;
    f64 last_time = 0.0;
 
@@ -59,7 +62,7 @@ static void ent_route_imgui( world_instance *world, ent_route *route,
 
    for( u32 i=0; i<valid_sections; i ++ ){
       struct time_block *block = &blocks[ i ];
-      ui_px w = block->length * 2.0f;
+      ui_px w = block->length * 6.0f;
       ui_rect rect = { x, inout_cursor[1], w, h };
       ui_fill( rect, colour );
    
index 318e12414d84c22d1b039c9e25540c8bd7877532..00bfe421c209ee5afa477f77acde740930119ae8 100644 (file)
@@ -6,4 +6,5 @@
 struct route_ui{
 };
 
+static void ent_region_re_eval( world_instance *world );
 #endif /* WORLD_ROUTES_UI_H */