+#include "common.h"
+
+static int ray_world( v3f pos, v3f dir, ray_hit *hit );
+
#ifndef WORLD_H
#define WORLD_H
-#define VG_3D
-#include "vg/vg.h"
-
#include "scene.h"
#include "terrain.h"
#include "render.h"
#include "water.h"
+#include "rigidbody.h"
+#include "gate.h"
+#include "bvh.h"
#include "shaders/standard.h"
glmesh skybox;
v3f tutorial;
+
+ teleport_gate gates[64];
+ u32 gate_count;
+
+ rigidbody temp_rbs[128];
+ u32 rb_count;
+
+ bh_tree bhcubes;
}
world;
m4x3f identity_matrix;
m4x3_identity( identity_matrix );
- render_terrain( projection );
+ render_terrain( projection, camera[3] );
scene_bind( &world.geo );
scene_draw( &world.geo );
scene_bind( &world.foliage );
scene_draw( &world.foliage );
glEnable(GL_CULL_FACE);
+
+ vg_line_boxf( world.geo.bbx, 0xff00ff00 );
+}
+
+static void ray_world_get_tri( ray_hit *hit, v3f tri[3] )
+{
+ for( int i=0; i<3; i++ )
+ v3_copy( world.geo.verts[ hit->tri[i] ].co, tri[i] );
}
static int ray_world( v3f pos, v3f dir, ray_hit *hit )
{
- return bvh_raycast( &world.geo, pos, dir, hit );
+ return scene_raycast( &world.geo, pos, dir, hit );
}
static int ray_hit_is_ramp( ray_hit *hit )
return hit->tri[0] < world.sm_road.vertex_count;
}
-static void world_init_default(void)
+static void world_load(void)
{
/* Setup scene */
scene_init( &world.geo );
model *mworld = vg_asset_read( "models/mp_dev.mdl" );
- scene_add_model( &world.geo, mworld, submodel_get( mworld, "mp_dev" ),
- (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
- scene_copy_slice( &world.geo, &world.sm_road );
-
- scene_add_model( &world.geo, mworld, submodel_get( mworld, "terrain" ),
- (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
- scene_copy_slice( &world.geo, &world.sm_terrain );
-
- v3_copy( model_marker_get( mworld, "mp_dev_tutorial" )->co, world.tutorial );
+ for( int i=0; i<mworld->layer_count; i++ )
+ {
+ submodel *sm = model_get_submodel( mworld, i );
+ if( !strcmp( sm->material, "surf" ) )
+ scene_add_model( &world.geo, mworld, sm, sm->pivot, 0.0f, 1.0f );
+ }
+ scene_copy_slice( &world.geo, &world.sm_road );
- /* GATE DEV */
-#if 0
+ for( int i=0; i<mworld->layer_count; i++ )
{
- model_marker *ga = model_marker_get(mworld,"gate_a"),
- *gb = model_marker_get(mworld,"gate_a_recv");
+ submodel *sm = model_get_submodel( mworld, i );
+ if( !strcmp( sm->material, "terrain" ) )
+ scene_add_model( &world.geo, mworld, sm, sm->pivot, 0.0f, 1.0f );
+ }
- v3_copy( ga->co, gate_a.co );
- v3_copy( gb->co, gate_b.co );
- v4_copy( ga->q, gate_a.q );
- v4_copy( gb->q, gate_b.q );
- v2_copy( ga->s, gate_a.dims );
- v2_copy( gb->s, gate_b.dims );
+ scene_copy_slice( &world.geo, &world.sm_terrain );
- gate_a.other = &gate_b;
- gate_b.other = &gate_a;
+ vg_info( "BBX: %.3f %.3f %.3f -> %.3f %.3f %.3f\n",
+ world.geo.bbx[0][0], world.geo.bbx[0][1], world.geo.bbx[0][2],
+ world.geo.bbx[1][0], world.geo.bbx[1][1], world.geo.bbx[1][2] );
+
+ /*
+ * TODO: Parametric marker import
+ */
+ v3_copy( model_marker_get( mworld, "start" )->co, world.tutorial );
+
+ /*
+ * Initialize gates
+ */
+
+ world.gate_count = 0;
+ for( int i=0; i<mworld->marker_count; i++ )
+ {
+ model_marker *ga = model_get_marker( mworld, i );
+
+ if( ga->classtype == k_classtype_gate )
+ {
+ struct classtype_gate *data = get_entdata_raw( mworld, ga );
+
+ if( data->target )
+ {
+ model_marker *gb = model_get_marker( mworld, data->target );
+
+ teleport_gate *gate = &world.gates[ world.gate_count ++ ];
+
+ v3_copy( ga->co, gate->co[0] );
+ v3_copy( gb->co, gate->co[1] );
+ v4_copy( ga->q, gate->q[0] );
+ v4_copy( gb->q, gate->q[1] );
+ v2_copy( ga->s, gate->dims );
- gate_transform_update( &gate_a );
- gate_transform_update( &gate_b );
+ gate_transform_update( gate );
+ }
+ }
}
-#endif
- /* WATER DEV */
+ /*
+ * Load water mesh (1 per world)
+ */
+ for( int i=0; i<mworld->layer_count; i++ )
{
- glmesh surf;
- submodel *sm = submodel_get(mworld,"mp_dev_water");
- model_unpack_submodel( mworld, &surf, sm );
-
- water_init();
- water_set_surface( &surf, sm->pivot[1] );
- }
+ submodel *sm = model_get_submodel( mworld, i );
+ if( !strcmp( sm->material, "water" ) )
+ {
+ glmesh surf;
+ model_unpack_submodel( mworld, &surf, sm );
+
+ water_init();
+ water_set_surface( &surf, sm->pivot[1] );
- free( mworld );
- scene_upload( &world.geo );
- bvh_create( &world.geo );
+ vg_info( "%.3f\n", sm->pivot[1] );
+ break;
+ }
+ }
+ scene_upload( &world.geo );
+ scene_bh_create( &world.geo );
+
+ water_compute_depth( world.geo.bbx );
scene_init( &world.foliage );
model *mfoliage = vg_asset_read("models/rs_foliage.mdl");
+ /*
+ * TODO: Load any other meshes into the foliage scene, and create rbs for
+ * them.
+ *
+ * then compute bvh
+ */
+
+ for( int i=0; i<mworld->layer_count; i++ )
+ {
+ submodel *sm = model_get_submodel( mworld, i );
+ if( !strcmp( sm->material, "surf" ) ||
+ !strcmp( sm->material, "terrain" ) ||
+ !strcmp( sm->material, "water" ) )
+ continue;
+
+ m4x3f transform;
+ q_m3x3( sm->q, transform );
+ v3_copy( sm->pivot, transform[3] );
+ scene_add_foliage( &world.foliage, mworld, sm, transform );
+
+ rigidbody *rb = &world.temp_rbs[ world.rb_count ++ ];
+
+ box_copy( sm->bbx, rb->bbx );
+ v3_copy( sm->pivot, rb->co );
+ rb_init( rb );
+ v4_copy( sm->q, rb->q );
+ rb_update_transform( rb );
+ }
+
+ free( mworld );
+
v3f volume;
v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
volume[1] = 1.0f;
m4x3f transform;
+ submodel *sm_blob = submodel_get( mfoliage, "blob" ),
+ *sm_tree = submodel_get( mfoliage, "tree" );
+
for( int i=0;i<100000;i++ )
{
v3f pos;
v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
+ pos[1] = 1000.0f;
v3_add( pos, world.geo.bbx[0], pos );
ray_hit hit;
if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
{
- if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) )
+ if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) &&
+ hit.pos[1] > water_height()+10.0f )
{
v4f qsurface, qrandom;
v3f axis;
q_m3x3( qsurface, transform );
v3_copy( hit.pos, transform[3] );
-
- scene_add_foliage( &world.foliage, mfoliage,
- model_get_submodel( mfoliage, 0 ), transform );
+
+ if( vg_randf() < 0.0006f )
+ {
+ m3x3_identity( transform );
+ scene_add_foliage( &world.foliage, mfoliage, sm_tree, transform);
+ }
+ else
+ scene_add_foliage( &world.foliage, mfoliage, sm_blob, transform);
}
}
}
free( mfoliage );
scene_upload( &world.foliage );
+
+ bh_create( &world.bhcubes,
+ &bh_system_rigidbodies, world.temp_rbs, world.rb_count );
}
#endif /* WORLD_H */