('ent_list', 'Entity List', '', 24 ),
('ent_region', 'Region', '', 25 ),
('ent_glider', 'Glider', '', 26 ),
+ ('ent_npc', 'npc', '', 27 )
]
MDL_VERSION_NR = 105
1: 'equip' }
#}
+class ent_npc(Structure):#{
+ _fields_ = [("transform",mdl_transform),
+ ("id",c_uint32),
+ ("context",c_uint32)]
+#}
+
class ent_water(Structure):
#{
_fields_ = [("transform",mdl_transform),
compile_obj_transform( obj, glider.transform )
sr_ent_push( glider )
#}
+ elif ent_type == 'ent_npc':#{
+ obj_data = obj.SR_data.ent_npc[0]
+ npc = ent_npc()
+ compile_obj_transform( obj, npc.transform )
+ npc.id = obj_data.au
+ npc.context = obj_data.context
+ sr_ent_push( npc )
+ #}
elif ent_type == 'ent_cubemap':#{
cubemap = ent_cubemap()
co = obj.matrix_world @ Vector((0,0,0))
nothing: bpy.props.StringProperty()
#}
+class SR_OBJECT_ENT_NPC(bpy.types.PropertyGroup):#{
+ au: bpy.props.IntProperty()
+ context: bpy.props.IntProperty()
+#}
+
class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{
subtype: bpy.props.EnumProperty(
name="Subtype",
ent_miniworld: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_MINIWORLD)
ent_list: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_LIST)
ent_glider: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_GLIDER)
+ ent_npc: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_NPC)
ent_type: bpy.props.EnumProperty(
name="Type",
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_ENT_GLIDER, \
+ SR_OBJECT_ENT_GLIDER, SR_OBJECT_ENT_NPC, \
\
SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES,
SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \
+#include "vg/vg_engine.h"
#include "entity.h"
#include "input.h"
#include "gui.h"
#include "entity.h"
#include "player_glide.h"
-static void ent_glider_call( world_instance *world, ent_call *call ){
+void ent_glider_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_glider *glider = mdl_arritm( &world->ent_glider, index );
#pragma once
#include "entity.h"
-static void ent_glider_call( world_instance *world, ent_call *call );
+void ent_glider_call( world_instance *world, ent_call *call );
#include "entity.h"
#include "ent_miniworld.h"
#include "world_render.h"
+#include "world_load.h"
#include "input.h"
#include "gui.h"
#include "menu.h"
+#include "audio.h"
struct global_miniworld global_miniworld;
--- /dev/null
+#include "vg/vg_mem.h"
+#include "ent_npc.h"
+#include "shaders/model_character_view.h"
+
+struct npc npc_gumpa;
+static struct skeleton_anim *gumpa_idle;
+
+void npc_load_model( struct npc *npc, const char *path )
+{
+ vg_linear_clear( vg_mem.scratch );
+
+ mdl_context *meta = &npc->meta;
+ mdl_open( meta, path, vg_mem.rtmemory );
+ mdl_load_metadata_block( meta, vg_mem.rtmemory );
+ mdl_load_animation_block( meta, vg_mem.rtmemory );
+
+ struct skeleton *sk = &npc->skeleton;
+ skeleton_setup( sk, vg_mem.rtmemory, meta );
+
+ u32 mtx_size = sizeof(m4x3f)*sk->bone_count;
+ npc->final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size );
+
+ if( !mdl_arrcount( &meta->textures ) )
+ vg_fatal_error( "No texture in model" );
+
+ mdl_texture *tex0 = mdl_arritm( &meta->textures, 0 );
+ void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
+ mdl_fread_pack_file( meta, &tex0->file, data );
+
+ vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
+ VG_TEX2D_NEAREST|VG_TEX2D_CLAMP,
+ &npc->texture );
+
+ mdl_async_load_glmesh( meta, &npc->mesh, NULL );
+ mdl_close( meta );
+}
+
+void npc_init(void)
+{
+ npc_load_model( &npc_gumpa, "models/gumpa.mdl" );
+ gumpa_idle = skeleton_get_anim( &npc_gumpa.skeleton, "gumpa_idle" );
+}
+
+static struct npc *npc_resolve( u32 id )
+{
+ if( id == 1 ) return &npc_gumpa;
+ else return NULL;
+}
+
+void npc_update( ent_npc *ent )
+{
+ struct npc *npc_def = npc_resolve( ent->id );
+ VG_ASSERT( npc_def );
+
+ player_pose pose;
+ struct skeleton *sk = &npc_def->skeleton;
+ pose.type = k_player_pose_type_ik;
+ pose.board.lean = 0.0f;
+
+ skeleton_sample_anim( sk, gumpa_idle, vg.time, pose.keyframes );
+
+ v3_copy( ent->transform.co, pose.root_co );
+ v4_copy( ent->transform.q, pose.root_q );
+ apply_full_skeleton_pose( &npc_def->skeleton, &pose, npc_def->final_mtx );
+}
+
+void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam )
+{
+ struct npc *npc_def = npc_resolve( ent->id );
+ VG_ASSERT( npc_def );
+
+ shader_model_character_view_use();
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, npc_def->texture );
+ shader_model_character_view_uTexMain( 0 );
+ shader_model_character_view_uCamera( cam->transform[3] );
+ shader_model_character_view_uPv( cam->mtx.pv );
+ shader_model_character_view_uDepthCompare( 0 );
+
+ WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_character_view );
+
+ glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms,
+ npc_def->skeleton.bone_count,
+ 0,
+ (const GLfloat *)npc_def->final_mtx );
+
+ mesh_bind( &npc_def->mesh );
+ mesh_draw( &npc_def->mesh );
+}
--- /dev/null
+#pragma once
+#include "player_render.h"
+#include "entity.h"
+
+struct npc
+{
+ glmesh mesh;
+ GLuint texture;
+
+ mdl_context meta;
+ struct skeleton skeleton;
+
+ m4x3f *final_mtx;
+}
+extern npc_gumpa;
+
+enum npc_id
+{
+ k_npc_id_none = 0,
+ k_npc_id_gumpa = 1
+};
+
+void npc_load_model( struct npc *npc, const char *path );
+void npc_update( ent_npc *ent );
+void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam );
+void npc_init(void);
#pragma once
#include "world_entity.h"
+#include "network_common.h"
struct global_ent_region
{
#include "world.h"
-static void ent_traffic_update( world_instance *world, v3f pos ){
+void ent_traffic_update( world_instance *world, v3f pos )
+{
for( u32 i=0; i<mdl_arrcount( &world->ent_traffic ); i++ ){
ent_traffic *traffic = mdl_arritm( &world->ent_traffic, i );
typedef struct ent_region ent_region;
typedef struct ent_list ent_list;
typedef struct ent_glider ent_glider;
+typedef struct ent_npc ent_npc;
enum entity_alias{
k_ent_none = 0,
k_ent_prop = 23,
k_ent_list = 24,
k_ent_region = 25,
- k_ent_glider = 26
+ k_ent_glider = 26,
+ k_ent_npc = 27
};
static inline u32 mdl_entity_id_type( u32 entity_id )
f32 cooldown;
};
+struct ent_npc
+{
+ mdl_transform transform;
+ u32 id, context;
+};
+
#include "world.h"
void entity_call( world_instance *world, ent_call *call );
#include "skaterift.h"
+#include "player.h"
+#include "player_render.h"
#include "player_replay.h"
#include "input.h"
#include "menu.h"
#include "vg/vg_perlin.h"
-static float player_get_heading_yaw(void){
+float player_get_heading_yaw(void)
+{
v3f xz;
q_mulv( localplayer.rb.q, (v3f){ 0.0f,0.0f,1.0f }, xz );
return atan2f( xz[0], xz[2] );
}
-static void player_camera_portal_correction(void){
+static void player_camera_portal_correction(void)
+{
if( localplayer.gate_waiting ){
/* construct plane equation for reciever gate */
v4f plane;
}
}
-static void player__cam_iterate(void){
+void player__cam_iterate(void)
+{
struct player_cam_controller *cc = &localplayer.cam_control;
if( localplayer.subsystem == k_player_subsystem_walk ){
player_camera_portal_correction();
}
-static void player_look( v3f angles, float speed ){
+void player_look( v3f angles, float speed )
+{
if( vg_ui.wants_mouse ) return;
angles[2] = 0.0f;
-#ifndef PLAYER_COMMON_H
-#define PLAYER_COMMON_H
-
+#pragma once
#include "player_api.h"
static float
static i32 k_player_debug_info = 0;
static ui_rect g_player_debugger;
-static void player_look( v3f angles, float speed );
-static void player__cam_iterate(void);
-static struct player_board
- *player_get_player_board( struct player_instance *player );
-static struct player_model
- *player_get_player_model( struct player_instance *player );
-static f32 player_get_heading_yaw(void);
-
-#endif /* PLAYER_COMMON_H */
+void player_look( v3f angles, float speed );
+void player__cam_iterate(void);
+f32 player_get_heading_yaw(void);
+#include "player.h"
#include "player_effects.h"
#include "player_render.h"
#include "particle.h"
#pragma once
#include "vg/vg_platform.h"
+#include "player_render.h"
typedef struct effect_blink effect_blink;
typedef struct effect_spark effect_spark;
#include "skaterift.h"
+#include "player.h"
#include "player_replay.h"
#include "input.h"
#include "gui.h"
-#pragma once
-
#include "vg/vg_rigidbody_collision.h"
#include "skaterift.h"
#include "vg/vg_log.h"
#include "vg/vg_loader.h"
#include "world.h"
+#include "player.h"
static const char *str_skaterift_main_save = "save.bkv";
static f64 last_autosave;
#include "ent_tornado.h"
#include "ent_miniworld.h"
#include "ent_skateshop.h"
+#include "ent_npc.h"
#include "world_map.h"
#include "gui.h"
#include "workshop.h"
vg_loader_step( player_init, NULL );
vg_loader_step( player_ragdoll_init, NULL );
+ vg_loader_step( npc_init, NULL );
/* content stuff */
vg_loader_step( addon_system_init, NULL );
#include "world_sfd.c"
#include "world_volumes.c"
#include "world_water.c"
+#include "ent_npc.c"
#include "render.h"
#include "network_msg.h"
#include "addon.h"
+#include "scene.h"
/* types
*/
ent_miniworld,
ent_prop,
ent_region,
- ent_glider;
+ ent_glider,
+ ent_npc;
enum skybox {
k_skybox_default,
{ k_ent_objective, &world->ent_objective },
{ k_ent_volume, &world->ent_volume },
{ k_ent_challenge, &world->ent_challenge },
- { k_ent_glider, &world->ent_glider }
+ { k_ent_glider, &world->ent_glider },
+ { k_ent_npc, &world->ent_npc }
};
for( u32 i=0; i<vg_list_size(indexables); i++ )
m4x3_expand_aabb_aabb( transform, bound,
(boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} );
}
+ else if( type == k_ent_npc )
+ {
+ ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+ box_addpt( bound, npc->transform.co );
+ }
else{
vg_fatal_error( "Programming error\n" );
}
ent_volume *volume = mdl_arritm( &world->ent_volume, index );
return volume->transform.co[axis];
}
- else if( type == k_ent_challenge ){
+ else if( type == k_ent_challenge )
+ {
ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
return challenge->transform.co[axis];
}
- else if( type == k_ent_glider ){
+ else if( type == k_ent_glider )
+ {
ent_glider *glider = mdl_arritm( &world->ent_glider, index );
return glider->transform.co[axis];
}
- else {
+ else if( type == k_ent_npc )
+ {
+ ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+ return npc->transform.co[axis];
+ }
+ else
+ {
vg_fatal_error( "Programming error\n" );
return INFINITY;
}
#include "vg/vg_camera.h"
#include "world.h"
#include "shaders/model_gate.h"
+#include "entity.h"
struct world_gates
{
/*
* Create the main meshes for the world
*/
-static void world_gen_generate_meshes( world_instance *world ){
+void world_gen_generate_meshes( world_instance *world )
+{
/*
* Compile meshes into the world scenes
*/
/*
* Computes light indices for world
*/
-static void world_gen_compute_light_indices( world_instance *world ){
+void world_gen_compute_light_indices( world_instance *world )
+{
/* light cubes */
v3f cubes_min, cubes_max;
v3_muls( world->scene_geo.bbx[0], 1.0f/k_world_light_cube_size, cubes_min );
/*
* Rendering pass needed to complete the world
*/
-static void async_world_postprocess( void *payload, u32 _size ){
+void async_world_postprocess( void *payload, u32 _size )
+{
/* create scene lighting buffer */
world_instance *world = payload;
}
/* Loads textures from the pack file */
-static void world_gen_load_surfaces( world_instance *world ){
+void world_gen_load_surfaces( world_instance *world )
+{
vg_info( "Loading textures\n" );
world->texture_count = 0;
* create geometry, apply procedural stuff and save that image to files etc.
*/
-#ifndef WORLD_GEN_H
-#define WORLD_GEN_H
-
+#pragma once
#include "world.h"
-static void world_init_blank( world_instance *world );
-static void world_gen_load_surfaces( world_instance *world );
-static void world_gen_generate_meshes( world_instance *world );
-static void world_gen_compute_light_indices( world_instance *world );
-static void async_world_postprocess( void *payload, u32 _size );
-
-#endif /* WORLD_GEN_H */
+void world_init_blank( world_instance *world );
+void world_gen_load_surfaces( world_instance *world );
+void world_gen_generate_meshes( world_instance *world );
+void world_gen_compute_light_indices( world_instance *world );
+void async_world_postprocess( void *payload, u32 _size );
MDL_LOAD_ARRAY( meta, &world->ent_prop, ent_prop, heap );
MDL_LOAD_ARRAY( meta, &world->ent_region, ent_region, heap );
MDL_LOAD_ARRAY( meta, &world->ent_glider, ent_glider, heap );
+ MDL_LOAD_ARRAY( meta, &world->ent_npc, ent_npc, heap );
mdl_array_ptr infos;
MDL_LOAD_ARRAY( meta, &infos, ent_worldinfo, vg_mem.scratch );
* reset the world structure without deallocating persistent buffers
* TODO: Make this a memset(0), and have persistent items live in a static loc
*/
-static void world_init_blank( world_instance *world ){
+void world_init_blank( world_instance *world )
+{
memset( &world->meta, 0, sizeof(mdl_context) );
world->textures = NULL;
#include "world.h"
#include "vg/vg_rigidbody.h"
#include "vg/vg_rigidbody_collision.h"
+#include "vg/vg_bvh.h"
void ray_world_get_tri( world_instance *world,
ray_hit *hit, v3f tri[3] );
#include "ent_miniworld.h"
#include "player_remote.h"
#include "ent_skateshop.h"
+#include "ent_npc.h"
#include "shaders/model_entity.h"
struct world_render world_render;
sizeof(struct ub_world_lighting), &world->ub_lighting );
}
-static void render_other_entities( world_instance *world, vg_camera *cam ){
+static void render_other_entities( world_instance *world, vg_camera *cam )
+{
f32 radius = 40.0f;
bh_iter it;
bh_iter_init_range( 0, &it, cam->pos, radius+10.0f );
u32 glider_list[4],
- glider_count = 0;
+ glider_count = 0,
+ npc_list[4],
+ npc_count = 0;
i32 idx;
while( bh_next( world->entity_bh, &it, &idx ) ){
type = mdl_entity_id_type( id ),
index = mdl_entity_id_id( id );
- if( type == k_ent_glider ) {
+ if( type == k_ent_glider )
+ {
if( glider_count < vg_list_size(glider_list) )
glider_list[ glider_count ++ ] = index;
}
+ else if( type == k_ent_npc )
+ {
+ if( npc_count < vg_list_size(npc_list) )
+ npc_list[ npc_count ++ ] = index;
+ }
}
shader_model_entity_use();
shader_model_entity_uTexMain( 0 );
shader_model_entity_uCamera( cam->transform[3] );
shader_model_entity_uPv( cam->mtx.pv );
-
WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_entity );
- for( u32 j=0; j<glider_count; j ++ ){
+ for( u32 j=0; j<glider_count; j ++ )
+ {
ent_glider *glider = mdl_arritm( &world->ent_glider, glider_list[j] );
if( !(glider->flags & 0x1) )
render_glider_model( cam, world, mdl, k_board_shader_entity );
}
+
+ for( u32 j=0; j<npc_count; j ++ )
+ {
+ u32 index = npc_list[j];
+ ent_npc *npc = mdl_arritm( &world->ent_npc, npc_list[j] );
+ npc_update( npc );
+ npc_render( npc, world, cam );
+ }
}
void render_world( world_instance *world, vg_camera *cam,
#pragma once
#include "vg/vg_camera.h"
+#include "vg/vg_msg.h"
#include "world.h"
#include "network_msg.h"
#include "skaterift.h"
#include "world_routes_ui.h"
#include "world_routes.h"
+#include "player.h"
static u32 v4_rgba( v4f colour ){
u32 r = vg_minf(1.0f,colour[0])*255.0f,