X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_gate.h;h=a071e4bb20ee575e59c5f1722ade8b4da0ac0dab;hb=HEAD;hp=ad87ed1d106cdf8c484071c3fc1603805ddc8a55;hpb=b888cce683d95cc01d0b4be9bbe92a0dd47452ac;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_gate.h b/world_gate.h index ad87ed1..a071e4b 100644 --- a/world_gate.h +++ b/world_gate.h @@ -1,245 +1,36 @@ /* - * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved + * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved */ -#ifndef WORLD_GATE_H -#define WORLD_GATE_H - -#include "common.h" -#include "model.h" -#include "entity.h" -#include "render.h" -#include "camera.h" +#pragma once +#include "vg/vg_camera.h" +#include "world.h" #include "shaders/model_gate.h" -#include "world_water.h" - -VG_STATIC void gate_transform_update( ent_gate *gate ) -{ - m4x3f to_local, recv_to_world; - - q_m3x3( gate->q[0], gate->to_world ); - v3_copy( gate->co[0], gate->to_world[3] ); - - m4x3_invert_affine( gate->to_world, to_local ); - - q_m3x3( gate->q[1], recv_to_world ); - v3_copy( gate->co[1], recv_to_world[3] ); - m4x3_mul( recv_to_world, to_local, gate->transport ); - - m4x3_scalev( gate->to_world, (v3f){ gate->dimensions[0], - gate->dimensions[1], 1.0f } ); -} - -VG_STATIC void world_gates_init(void) -{ - vg_info( "world_gates_init\n" ); - - shader_model_gate_register(); - - vg_linear_clear( vg_mem.scratch ); - - mdl_context mgate; - mdl_open( &mgate, "models/rs_gate.mdl", vg_mem.scratch ); - mdl_load_metadata_block( &mgate, vg_mem.scratch ); - mdl_load_mesh_block( &mgate, vg_mem.scratch ); - - mdl_mesh *surface = mdl_find_mesh( &mgate, "rs_gate" ); - mdl_submesh *sm = mdl_arritm(&mgate.submeshs,surface->submesh_start); - world_global.sm_gate_surface = *sm; - - const char *names[] = { "rs_gate_marker", "rs_gate_marker.001", - "rs_gate_marker.002", "rs_gate_marker.003" }; - - for( int i=0; i<4; i++ ){ - mdl_mesh *marker = mdl_find_mesh( &mgate, names[i] ); - sm = mdl_arritm( &mgate.submeshs, marker->submesh_start ); - world_global.sm_gate_marker[i] = *sm; - } - - mdl_close( &mgate ); - - vg_acquire_thread_sync(); - { - mdl_unpack_glmesh( &mgate, &world_global.mesh_gate ); - } - vg_release_thread_sync(); -} - -VG_STATIC int render_gate( world_instance *world_inside, - ent_gate *gate, camera *cam, int layer_depth ) -{ - v3f viewdir, gatedir; - m3x3_mulv( cam->transform, (v3f){0.0f,0.0f,-1.0f}, viewdir ); - q_mulv( gate->q[0], (v3f){0.0f,0.0f,-1.0f}, gatedir ); - - v3f v0; - v3_sub( cam->pos, gate->co[0], v0 ); - - float dist = v3_dot(v0, gatedir); - - /* Hard cutoff */ - if( dist > 3.0f ) - return 0; - - if( v3_dist( cam->pos, gate->co[0] ) > 100.0f ) - return 0; - - { - v3f a,b,c,d; - - m4x3_mulv( gate->to_world, (v3f){-1.0f,-1.0f,0.0f}, a ); - m4x3_mulv( gate->to_world, (v3f){ 1.0f,-1.0f,0.0f}, b ); - m4x3_mulv( gate->to_world, (v3f){ 1.0f, 1.0f,0.0f}, c ); - m4x3_mulv( gate->to_world, (v3f){-1.0f, 1.0f,0.0f}, d ); - - vg_line( a,b, 0xffffa000 ); - vg_line( b,c, 0xffffa000 ); - vg_line( c,d, 0xffffa000 ); - vg_line( d,a, 0xffffa000 ); - - vg_line2( gate->co[0], gate->co[1], 0xff0000ff, 0x00000000 ); - } - - /* update gate camera */ - gate_camera.fov = cam->fov; - gate_camera.nearz = 0.1f; - gate_camera.farz = 2000.0f; - - m4x3_mul( gate->transport, cam->transform, gate_camera.transform ); - camera_update_view( &gate_camera ); - camera_update_projection( &gate_camera ); - - /* Add special clipping plane to projection */ - v4f surface; - q_mulv( gate->q[1], (v3f){0.0f,0.0f,-1.0f}, surface ); - surface[3] = v3_dot( surface, gate->co[1] ); - - m4x3_mulp( gate_camera.transform_inverse, surface, surface ); - surface[3] = -fabsf(surface[3]); - - if( dist < -0.5f ) - m4x4_clip_projection( gate_camera.mtx.p, surface ); - - /* Ready to draw with new camrea */ - camera_finalize( &gate_camera ); - - vg_line_pt3( gate_camera.transform[3], 0.3f, 0xff00ff00 ); - { - shader_model_gate_use(); - shader_model_gate_uPv( cam->mtx.pv ); - shader_model_gate_uMdl( gate->to_world ); - shader_model_gate_uCam( cam->pos ); - shader_model_gate_uColour( (v4f){0.0f,1.0f,0.0f,0.0f} ); - shader_model_gate_uTime( vg.time*0.25f ); - shader_model_gate_uInvRes( (v2f){ - 1.0f / (float)vg.window_x, - 1.0f / (float)vg.window_y }); - - glEnable( GL_STENCIL_TEST ); - glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); - glStencilFunc( GL_ALWAYS, 1, 0xFF ); - glStencilMask( 0xFF ); - - mesh_bind( &world_global.mesh_gate ); - mdl_draw_submesh( &world_global.sm_gate_surface ); - - glClear( GL_DEPTH_BUFFER_BIT ); - glStencilFunc( GL_EQUAL, 1, 0xFF ); - glStencilMask( 0x00 ); - } - - render_world( world_inside, &gate_camera, layer_depth ); - - { - glDisable( GL_STENCIL_TEST ); - - render_water_texture( world_inside, &gate_camera, layer_depth ); - render_fb_bind( gpipeline.fb_main, 1 ); - - glEnable( GL_STENCIL_TEST ); - - render_water_surface( world_inside, &gate_camera ); - - glStencilMask( 0xFF ); - glStencilFunc( GL_ALWAYS, 1, 0xFF ); - glDisable( GL_STENCIL_TEST ); - } - - return 1; -} - -VG_STATIC int gate_intersect_plane( ent_gate *gate, - v3f pos, v3f last, v2f where ) -{ - v4f surface; - q_mulv( gate->q[0], (v3f){0.0f,0.0f,-1.0f}, surface ); - surface[3] = v3_dot( surface, gate->co[0] ); - - v3f v0, c, delta, p0; - v3_sub( pos, last, v0 ); - float l = v3_length( v0 ); - - if( l == 0.0f ) - return 0; - - v3_divs( v0, l, v0 ); - - v3_muls( surface, surface[3], c ); - v3_sub( c, last, delta ); - - float d = v3_dot( surface, v0 ); - - if( d > 0.00001f ){ - float t = v3_dot(delta, surface) / d; - if( t >= 0.0f && t <= l ){ - v3f local, rel; - v3_muladds( last, v0, t, local ); - v3_sub( gate->co[0], local, rel ); - - where[0] = v3_dot( rel, gate->to_world[0] ); - where[1] = v3_dot( rel, gate->to_world[1] ); - - where[0] /= v3_dot( gate->to_world[0], gate->to_world[0] ); - where[1] /= v3_dot( gate->to_world[1], gate->to_world[1] ); - - return 1; - } - } - - return 0; -} +#include "entity.h" -VG_STATIC int gate_intersect( ent_gate *gate, v3f pos, v3f last ) +struct world_gates { - v2f xy; + glmesh mesh; + mdl_submesh sm_surface, sm_marker[4]; + vg_camera cam; - if( gate_intersect_plane( gate, pos, last, xy ) ){ - if( fabsf(xy[0]) <= 1.0f && fabsf(xy[1]) <= 1.0f ){ - return 1; - } - } - - return 0; + v3f userportal_co; } +extern world_gates; -/* - * Intersect all gates in the world - */ -VG_STATIC ent_gate *world_intersect_gates( world_instance *world, - v3f pos, v3f last ) -{ - for( u32 i=0; ient_gate); i++ ){ - ent_gate *gate = mdl_arritm( &world->ent_gate, i ); - if( gate->type == k_gate_type_unlinked ) - continue; +void world_gates_init(void); +void gate_transform_update( ent_gate *gate ); +int render_gate( world_instance *world, world_instance *world_inside, + ent_gate *gate, vg_camera *cam ); - if( gate_intersect( gate, pos, last ) ){ - return gate; - } - } +int gate_intersect( ent_gate *gate, v3f pos, v3f last ); +u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ); - return NULL; -} +entity_call_result ent_gate_call( world_instance *world, ent_call *call ); +void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl ); -#endif /* WORLD_GATE_H */ +void world_link_gates_async( void *payload, u32 size ); +void world_unlink_nonlocal( world_instance *world ); +void render_gate_unlinked( world_instance *world, + ent_gate *gate, vg_camera *cam );