X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=world_gate.h;h=a071e4bb20ee575e59c5f1722ade8b4da0ac0dab;hb=5fa590f62aa7e62a8b6b07e10556c2ecc54cdca6;hp=15c4a486f62052c9d78808690134cd3592701bc1;hpb=192990d6d24e53749ca046fef808a63cf162ab8a;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/world_gate.h b/world_gate.h index 15c4a48..a071e4b 100644 --- a/world_gate.h +++ b/world_gate.h @@ -1,253 +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 "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( teleport_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 ); +#include "entity.h" - 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->dims[0], gate->dims[1], 1.0f } ); -} - -VG_STATIC void world_gates_init(void) +struct world_gates { - vg_info( "world_gates_init\n" ); - - shader_model_gate_register(); + glmesh mesh; + mdl_submesh sm_surface, sm_marker[4]; + vg_camera cam; - vg_linear_clear( vg_mem.scratch ); - mdl_context *mgate = mdl_load_full( vg_mem.scratch, "models/rs_gate.mdl" ); - - vg_acquire_thread_sync(); - { - mdl_unpack_glmesh( mgate, &world_global.mesh_gate_surface ); - } - vg_release_thread_sync(); + v3f userportal_co; } +extern world_gates; -VG_STATIC int render_gate( world_instance *world_inside, - teleport_gate *gate, camera *cam ) -{ - 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_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_surface ); - mesh_draw( &world_global.mesh_gate_surface ); - - glClear( GL_DEPTH_BUFFER_BIT ); - glStencilFunc( GL_EQUAL, 1, 0xFF ); - glStencilMask( 0x00 ); - } - - render_world( world_inside, &gate_camera ); - - { - glDisable( GL_STENCIL_TEST ); - - render_water_texture( world_inside, &gate_camera ); - render_fb_bind( gpipeline.fb_main ); - - glEnable( GL_STENCIL_TEST ); +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 ); - render_water_surface( world_inside, &gate_camera ); +int gate_intersect( ent_gate *gate, v3f pos, v3f last ); +u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ); - glStencilMask( 0xFF ); - glStencilFunc( GL_ALWAYS, 1, 0xFF ); - glDisable( GL_STENCIL_TEST ); - } - - return 1; -} - -VG_STATIC int gate_intersect_plane( teleport_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; -} - -VG_STATIC int gate_intersect( teleport_gate *gate, v3f pos, v3f last ) -{ - v2f xy; - - if( gate_intersect_plane( gate, pos, last, xy ) ) - { - vg_info( "%f %f\n", xy[0], xy[1] ); - if( fabsf(xy[0]) <= 1.0f && fabsf(xy[1]) <= 1.0f ) - { - return 1; - } - } - - return 0; -} - -struct gate_hit -{ - struct nonlocal_gate *nonlocal; - struct route_gate *route; - teleport_gate *gate; -}; - -/* - * Intersect all gates in the world - */ -VG_STATIC int world_intersect_gates( world_instance *world, - v3f pos, v3f last, struct gate_hit *hit ) -{ - for( int i=0; igate_count; i++ ) - { - struct route_gate *rg = &world->gates[i]; - teleport_gate *gate = &rg->gate; - - if( gate_intersect( gate, pos, last ) ) - { - hit->gate = gate; - hit->nonlocal = NULL; - hit->route = rg; - return 1; - } - } - - for( int i=0; inonlocalgate_count; i++ ) - { - struct nonlocal_gate *nlg = &world->nonlocal_gates[i]; - teleport_gate *gate = &nlg->gate; - - if( gate_intersect( gate, pos, last ) ) - { - hit->gate = gate; - hit->nonlocal = nlg; - hit->route = NULL; - return 1; - } - } - - return 0; -} +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 );