+ 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 ) continue;
+
+ m4x3f transform;
+ m4x3_mul( gate->transport, text->transform, transform );
+
+ 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];
+ }
+ }
+}