2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
12 #include "shaders/gatelq.h"
13 #include "world_water.h"
16 VG_STATIC
void gate_transform_update( teleport_gate
*gate
)
20 q_m3x3( gate
->q
[0], gate
->to_world
);
21 v3_copy( gate
->co
[0], gate
->to_world
[3] );
23 m4x3_invert_affine( gate
->to_world
, to_local
);
25 q_m3x3( gate
->q
[1], gate
->recv_to_world
);
26 v3_copy( gate
->co
[1], gate
->recv_to_world
[3] );
27 m4x3_mul( gate
->recv_to_world
, to_local
, gate
->transport
);
30 VG_STATIC
void world_gates_init(void)
32 vg_info( "world_gates_init\n" );
34 shader_gatelq_register();
36 vg_linear_clear( vg_mem
.scratch
);
37 mdl_context
*mgate
= mdl_load_full( vg_mem
.scratch
, "models/rs_gate.mdl" );
39 vg_acquire_thread_sync();
41 mdl_unpack_glmesh( mgate
, &world
.mesh_gate_surface
);
43 vg_release_thread_sync();
46 VG_STATIC
int render_gate( teleport_gate
*gate
, v3f viewpos
, m4x3f camera
)
49 m3x3_mulv( camera
, (v3f
){0.0f
,0.0f
,-1.0f
}, viewdir
);
50 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, gatedir
);
53 v3_sub( viewpos
, gate
->co
[0], v0
);
54 if( v3_dot(v0
, gatedir
) >= 0.0f
)
57 if( v3_dist( viewpos
, gate
->co
[0] ) > 100.0f
)
62 float sx
= gate
->dims
[0],
64 m4x3_mulv( gate
->to_world
, (v3f
){-sx
,-sy
,0.0f
}, a
);
65 m4x3_mulv( gate
->to_world
, (v3f
){ sx
,-sy
,0.0f
}, b
);
66 m4x3_mulv( gate
->to_world
, (v3f
){ sx
, sy
,0.0f
}, c
);
67 m4x3_mulv( gate
->to_world
, (v3f
){-sx
, sy
,0.0f
}, d
);
69 vg_line( a
,b
, 0xffffa000 );
70 vg_line( b
,c
, 0xffffa000 );
71 vg_line( c
,d
, 0xffffa000 );
72 vg_line( d
,a
, 0xffffa000 );
74 vg_line2( gate
->co
[0], gate
->co
[1], 0xff0000ff, 0x00000000 );
77 m4x3_mul( gate
->transport
, camera
, cam_new
);
79 vg_line_pt3( cam_new
[3], 0.3f
, 0xff00ff00 );
82 m4x3_copy( gate
->to_world
, gate_xform
);
83 m4x3_scalev( gate_xform
, (v3f
){ gate
->dims
[0], gate
->dims
[1], 1.0f
} );
86 m4x3_invert_affine( cam_new
, inverse
);
89 m4x3_expand( inverse
, view
);
92 m3x3_mulv( gate
->recv_to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
93 surface
[3] = v3_dot( surface
, gate
->co
[1] );
96 pipeline_projection( projection
, 0.1f
, 900.0f
);
98 m4x3_mulp( inverse
, surface
, surface
);
99 surface
[3] = -fabsf(surface
[3]);
100 plane_clip_projection( projection
, surface
);
102 m4x4_mul( projection
, view
, projection
);
106 shader_gatelq_uPv( vg
.pv
);
107 shader_gatelq_uMdl( gate_xform
);
108 shader_gatelq_uCam( viewpos
);
109 shader_gatelq_uTime( vg
.time
*0.25f
);
110 shader_gatelq_uInvRes( (v2f
){
111 1.0f
/ (float)vg
.window_x
,
112 1.0f
/ (float)vg
.window_y
});
114 glEnable( GL_STENCIL_TEST
);
115 glStencilOp( GL_KEEP
, GL_KEEP
, GL_REPLACE
);
116 glStencilFunc( GL_ALWAYS
, 1, 0xFF );
117 glStencilMask( 0xFF );
119 mesh_bind( &world
.mesh_gate_surface
);
120 mesh_draw( &world
.mesh_gate_surface
);
122 glClear( GL_DEPTH_BUFFER_BIT
);
123 glStencilFunc( GL_EQUAL
, 1, 0xFF );
124 glStencilMask( 0x00 );
127 render_world( projection
, cam_new
);
130 glDisable( GL_STENCIL_TEST
);
132 render_water_texture( cam_new
);
134 glEnable( GL_STENCIL_TEST
);
136 render_water_surface( projection
, cam_new
);
138 glStencilMask( 0xFF );
139 glStencilFunc( GL_ALWAYS
, 1, 0xFF );
140 glDisable( GL_STENCIL_TEST
);
146 VG_STATIC
int gate_intersect( teleport_gate
*gate
, v3f pos
, v3f last
)
149 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
150 surface
[3] = v3_dot( surface
, gate
->co
[0] );
152 v3f v0
, c
, delta
, p0
;
153 v3_sub( pos
, last
, v0
);
154 float l
= v3_length( v0
);
155 v3_divs( v0
, l
, v0
);
157 v3_muls( surface
, surface
[3], c
);
158 v3_sub( c
, last
, delta
);
160 float d
= v3_dot(surface
, v0
);
164 float t
= v3_dot(delta
, surface
) / d
;
165 if( t
>= 0.0f
&& t
<= l
)
168 v3_muladds( last
, v0
, t
, local
);
169 v3_sub( gate
->co
[0], local
, rel
);
172 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,1.0f
,0.0f
}, vup
);
173 m3x3_mulv( gate
->to_world
, (v3f
){1.0f
,0.0f
,0.0f
}, vside
);
175 v2f xy
= { v3_dot( rel
, vside
), v3_dot( rel
, vup
) };
177 if( fabsf(xy
[0]) <= gate
->dims
[0] && fabsf(xy
[1]) <= gate
->dims
[1] )
187 #endif /* WORLD_GATE_H */