bouncy balls
authorhgn <hgodden00@gmail.com>
Tue, 11 Apr 2023 18:08:25 +0000 (19:08 +0100)
committerhgn <hgodden00@gmail.com>
Tue, 11 Apr 2023 18:08:25 +0000 (19:08 +0100)
font.h
player.c
player_ragdoll.h
rigidbody.h
skaterift.c
world.h
world_routes.h

diff --git a/font.h b/font.h
index 4c7d8f46f1e09ad0a970bf13d34af0b8b22c6b20..75f2573c29f4bd9d292531d605b5529849ec6bab 100644 (file)
--- a/font.h
+++ b/font.h
@@ -86,6 +86,17 @@ VG_STATIC void font3d_bind( font3d *font, camera *cam )
    mesh_bind( &font->mesh );
 }
 
+VG_STATIC ent_glyph *font3d_glyph( font3d *font, u32 variant_id, u32 utf32 )
+{
+   if( utf32 < font->info.glyph_utf32_base ) return NULL;
+   if( utf32 >= font->info.glyph_utf32_base+font->info.glyph_count) return NULL;
+
+   u32 index = utf32 - font->info.glyph_utf32_base;
+       index += font->info.glyph_start;
+       index += font->info.glyph_count * variant_id;
+   return mdl_arritm( &font->glyphs, index );
+}
+
 VG_STATIC 
 void font3d_simple_draw( font3d *font, u32 variant_id, const char *text, 
                          camera *cam, m4x3f transform )
@@ -105,13 +116,8 @@ void font3d_simple_draw( font3d *font, u32 variant_id, const char *text,
       u32 c = text[i];
       if(!c) break;
 
-      if( c < font->info.glyph_utf32_base ) continue;
-      if( c >= font->info.glyph_utf32_base+font->info.glyph_count) continue;
-
-      u32 index = c - font->info.glyph_utf32_base;
-          index += font->info.glyph_start;
-          index += font->info.glyph_count * variant_id;
-      ent_glyph *glyph = mdl_arritm( &font->glyphs, index );
+      ent_glyph *glyph = font3d_glyph( font, variant_id, c );
+      if( !glyph ) continue;
 
       if( glyph->indice_count ){
          shader_model_font_uOffset( offset );
@@ -129,13 +135,8 @@ float font3d_string_width( font3d *font, u32 variant_id, const char *text )
       u32 c = text[i];
       if(!c) break;
 
-      if( c < font->info.glyph_utf32_base ) continue;
-      if( c >= font->info.glyph_utf32_base+font->info.glyph_count) continue;
-
-      u32 index = c - font->info.glyph_utf32_base;
-          index += font->info.glyph_start;
-          index += font->info.glyph_count * variant_id;
-      ent_glyph *glyph = mdl_arritm( &font->glyphs, index );
+      ent_glyph *glyph = font3d_glyph( font, variant_id, c );
+      if( !glyph ) continue;
 
       width += glyph->size[0];
    }
index 01a0b526bed5eac40cc619d48c83235029ddb075..51353b9a7e8492f70f803cd45463a0ce5d93fc9f 100644 (file)
--- a/player.c
+++ b/player.c
@@ -291,6 +291,9 @@ VG_STATIC void gate_rotate_angles( ent_gate *gate, v3f angles, v3f d )
 PLAYER_API
 void player__pass_gate( player_instance *player, ent_gate *gate )
 {
+   world_routes_fracture( get_active_world(), gate, 
+                          player->rb.co, player->rb.v );
+
    player->gate_waiting = gate;
    world_routes_activate_entry_gate( get_active_world(), gate );
 
index c44060a248382e61591c287a24ac40ee124daa18..101d8f9c5850f488a5d7fe06162dfd7dca5b97db 100644 (file)
@@ -435,7 +435,7 @@ VG_STATIC void player_ragdoll_iter( struct player_ragdoll *rd )
       v3_sub( ct->co, ct->rba->co, ra );
       v3_sub( ct->co, ct->rbb->co, rb );
       rb_rcv( ct->rba, ct->rbb, ra, rb, rv );
-      float     vn = v3_dot( rv, ct->n );
+      float vn = v3_dot( rv, ct->n );
 
       float s = fabsf(vn - contact_velocities[i]);
       if( s > max_stress ){
index f2f36cb2ba063f2aa0ee061b2a0686117ebd1cd6..60fc88ce59a18275f59c6b36aba67ed88f9fbb89 100644 (file)
@@ -1659,6 +1659,20 @@ VG_STATIC void rb_rcv( rigidbody *rba, rigidbody *rbb, v3f ra, v3f rb, v3f rv )
    v3_sub( rva, rvb, rv );
 }
 
+VG_STATIC void rb_contact_restitution( rb_ct *ct, float cr )
+{
+   v3f rv, ra, rb;
+   v3_sub( ct->co, ct->rba->co, ra );
+   v3_sub( ct->co, ct->rbb->co, rb );
+   rb_rcv( ct->rba, ct->rbb, ra, rb, rv );
+
+   float v = v3_dot( rv, ct->n );
+
+   if( v < -1.0f ){
+      ct->bias += -cr * v;
+   }
+}
+
 /*
  * Apply impulse to object
  */
index 9c83a88f4caccb02bea424f7304ff097687e1b09..8b909d2e2450fb83b053d7f73c2f40dcf99ec6b1 100644 (file)
@@ -275,8 +275,7 @@ VG_STATIC void vg_update(void)
 {
    steam_update();
 
-   if( vg.is_loaded )
-   {
+   if( vg.is_loaded ){
       draw_origin_axis();
       network_update();
       
@@ -294,15 +293,14 @@ VG_STATIC void vg_update(void)
 
 VG_STATIC void vg_update_fixed(void)
 {
-   if( vg.is_loaded )
-   {
+   if( vg.is_loaded ){
 #if 0
       if( !gzoomer.inside )
          player_update_fixed();
 
       vehicle_update_fixed();
 #endif
-
+      world_routes_fixedupdate( get_active_world() );
       player__update( &localplayer );
    }
 }
diff --git a/world.h b/world.h
index c99cfdc1807ca6a752c5121ce0ff71156f3f1657..ab663d005e4ffadacb32956e34c3e503c9287679 100644 (file)
--- a/world.h
+++ b/world.h
@@ -239,8 +239,12 @@ VG_STATIC struct world_global{
    u32 timer_text_count;
 
    struct text_particle{
-      rigidbody *rb;
+      rb_object obj;
+      m4x3f mlocal;
       ent_glyph *glyph;
+      v4f colour;
+
+      m4x3f mdl;
    }
    text_particles[6*4];
    u32 text_particle_count;
index 792b7e8dc89ccdbe8a1bf1aa7476101291d106d4..e47ebe2739f6b0dabc6744fbd3864788b600d95a 100644 (file)
@@ -592,6 +592,55 @@ VG_STATIC void world_routes_update( world_instance *world )
       int target = route->active_checkpoint == 0xffff? 0: 1;
       route->factive = vg_lerpf( route->factive, target, 0.6f*vg.time_delta );
    }
+
+   for( u32 i=0; i<world_global.text_particle_count; i++ ){
+      struct text_particle *particle = &world_global.text_particles[i];
+      rb_object_debug( &particle->obj, VG__RED );
+   }
+}
+
+VG_STATIC void world_routes_fixedupdate( world_instance *world )
+{
+   rb_solver_reset();
+
+   for( u32 i=0; i<world_global.text_particle_count; i++ ){
+      struct text_particle *particle = &world_global.text_particles[i];
+
+      if( rb_global_has_space() ){
+         rb_ct *buf = rb_global_buffer();
+
+         int l = rb_sphere__scene( particle->obj.rb.to_world,
+                                   &particle->obj.inf.sphere,
+                                   NULL, &world->rb_geo.inf.scene, buf );
+
+         for( int j=0; j<l; j++ ){
+            buf[j].rba = &particle->obj.rb;
+            buf[j].rbb = &world->rb_geo.rb;
+         }
+
+         rb_contact_count += l;
+      }
+   }
+
+   rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
+
+   for( int i=0; i<rb_contact_count; i++ ){
+      rb_contact_restitution( rb_contact_buffer+i, vg_randf() );
+   }
+
+   for( int i=0; i<6; i++ ){
+      rb_solve_contacts( rb_contact_buffer, rb_contact_count );
+   }
+
+   for( u32 i=0; i<world_global.text_particle_count; i++ ){
+      struct text_particle *particle = &world_global.text_particles[i];
+      rb_iter( &particle->obj.rb );
+   }
+
+   for( u32 i=0; i<world_global.text_particle_count; i++ ){
+      struct text_particle *particle = &world_global.text_particles[i];
+      rb_update_transform( &particle->obj.rb );
+   }
 }
 
 VG_STATIC void bind_terrain_noise(void);
@@ -702,28 +751,76 @@ VG_STATIC void world_routes_update_timer_texts( world_instance *world )
    }
 }
 
-VG_STATIC void world_routes_fracture( world_instance *world, ent_gate *gate )
+VG_STATIC void world_routes_fracture( world_instance *world, ent_gate *gate,
+                                      v3f imp_co, v3f imp_v )
 {
    world_global.text_particle_count = 0;
    
    for( u32 i=0; i<world_global.timer_text_count; i++ ){
       struct timer_text *text = &world_global.timer_texts[i];
 
-      if( text->gate == gate ){
-         v3f co, s;
-         v4f q;
-         m4x3_decompose( text->transform, co, q, s );
+      if( text->gate != gate ) continue;
 
-         for( u32 j=0;; j++ ){
-            char c = text->text[j];
-            if( !c ) break;
+      m4x3f transform;
+      m4x3_mul( gate->transport, text->transform, transform );
 
-            if( c < '0' || c > '9' ) continue;
-            
+      v3f co, s;
+      v4f q;
+      m4x3_decompose( transform, co, q, s );
+
+      v3f offset;
+      v3_zero( offset );
+
+      v4f colour;
+      float brightness = 0.3f + world->ub_lighting.g_day_phase;
+      v3_muls( text->route->colour, brightness, colour );
+      colour[3] = 1.0f-text->route->factive;
+
+      for( u32 j=0;; j++ ){
+         char c = text->text[j];
+         if( !c ) break;
+
+         ent_glyph *glyph = font3d_glyph( &world_global.font, 0, c );
+         if( !glyph ) continue;
+
+         if( c >= (u32)'0' && c <= (u32)'9' && glyph->indice_count ){
             struct text_particle *particle = 
                &world_global.text_particles[world_global.text_particle_count++];
 
+            particle->glyph = glyph;
+            v4_copy( colour, particle->colour );
+
+            v3f origin;
+            v2_muls( glyph->size, 0.5f, origin );
+            origin[2] = -0.5f;
+
+            v3f world_co;
+
+            v3_add( offset, origin, world_co );
+            m4x3_mulv( transform, world_co, world_co );
+
+            float r = vg_maxf( s[0]*glyph->size[0], s[1]*glyph->size[1] )*0.5f;
+
+            m3x3_identity( particle->mlocal );
+            m3x3_scale( particle->mlocal, s );
+            origin[2] *= s[2];
+            v3_muls( origin, -1.0f, particle->mlocal[3] );
+
+            v3_copy( world_co, particle->obj.rb.co );
+            v3_muls( imp_v, 1.0f+vg_randf(), particle->obj.rb.v );
+            particle->obj.rb.v[1] += 2.0f;
+
+            v4_copy( q, particle->obj.rb.q );
+            particle->obj.rb.w[0] = vg_randf()*2.0f-1.0f;
+            particle->obj.rb.w[1] = vg_randf()*2.0f-1.0f;
+            particle->obj.rb.w[2] = vg_randf()*2.0f-1.0f;
+
+            particle->obj.type = k_rb_shape_sphere;
+            particle->obj.inf.sphere.radius = r*0.6f;
+
+            rb_init_object( &particle->obj );
          }
+         offset[0] += glyph->size[0];
       }
    }
 }
@@ -782,6 +879,31 @@ VG_STATIC void render_world_routes( world_instance *world, camera *cam,
          font3d_simple_draw( &world_global.font, 0, text->text, 
                              cam, text->transform );
       }
+
+      shader_model_font_uOffset( (v3f){0.0f,0.0f,0.0f} );
+
+      for( u32 i=0; i<world_global.text_particle_count; i++ ){
+         struct text_particle *particle = &world_global.text_particles[i];
+
+         m4x4f prev_mtx;
+
+         m4x3_expand( particle->mdl, prev_mtx );
+         m4x4_mul( cam->mtx_prev.pv, prev_mtx, prev_mtx );
+
+         shader_model_font_uPvmPrev( prev_mtx );
+
+         v4f q;
+         m4x3f model;
+         rb_extrapolate( &particle->obj.rb, model[3], q );
+         q_m3x3( q, model );
+
+         m4x3_mul( model, particle->mlocal, particle->mdl );
+         shader_model_font_uMdl( particle->mdl );
+         shader_model_font_uColour( particle->colour );
+
+         mesh_drawn( particle->glyph->indice_start, 
+                     particle->glyph->indice_count );
+      }
    }
 
    /* gate markers