f83cd87a24dd0455a8fea06bf667ba571c896921
2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
13 #include "shaders/gatelq.h"
14 #include "world_water.h"
17 VG_STATIC
void gate_transform_update( teleport_gate
*gate
)
21 q_m3x3( gate
->q
[0], gate
->to_world
);
22 v3_copy( gate
->co
[0], gate
->to_world
[3] );
24 m4x3_invert_affine( gate
->to_world
, to_local
);
26 q_m3x3( gate
->q
[1], gate
->recv_to_world
);
27 v3_copy( gate
->co
[1], gate
->recv_to_world
[3] );
28 m4x3_mul( gate
->recv_to_world
, to_local
, gate
->transport
);
31 VG_STATIC
void world_gates_init(void)
33 vg_info( "world_gates_init\n" );
35 shader_gatelq_register();
37 vg_linear_clear( vg_mem
.scratch
);
38 mdl_context
*mgate
= mdl_load_full( vg_mem
.scratch
, "models/rs_gate.mdl" );
40 vg_acquire_thread_sync();
42 mdl_unpack_glmesh( mgate
, &world
.mesh_gate_surface
);
44 vg_release_thread_sync();
47 VG_STATIC
int render_gate( teleport_gate
*gate
, camera
*cam
)
50 m3x3_mulv( cam
->transform
, (v3f
){0.0f
,0.0f
,-1.0f
}, viewdir
);
51 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, gatedir
);
54 v3_sub( cam
->pos
, gate
->co
[0], v0
);
56 float dist
= v3_dot(v0
, gatedir
);
62 if( v3_dist( cam
->pos
, gate
->co
[0] ) > 100.0f
)
68 float sx
= gate
->dims
[0],
70 m4x3_mulv( gate
->to_world
, (v3f
){-sx
,-sy
,0.0f
}, a
);
71 m4x3_mulv( gate
->to_world
, (v3f
){ sx
,-sy
,0.0f
}, b
);
72 m4x3_mulv( gate
->to_world
, (v3f
){ sx
, sy
,0.0f
}, c
);
73 m4x3_mulv( gate
->to_world
, (v3f
){-sx
, sy
,0.0f
}, d
);
75 vg_line( a
,b
, 0xffffa000 );
76 vg_line( b
,c
, 0xffffa000 );
77 vg_line( c
,d
, 0xffffa000 );
78 vg_line( d
,a
, 0xffffa000 );
80 vg_line2( gate
->co
[0], gate
->co
[1], 0xff0000ff, 0x00000000 );
83 /* update gate camera */
84 static camera gate_view
;
85 gate_view
.fov
= cam
->fov
;
86 gate_view
.nearz
= 0.1f
;
87 gate_view
.farz
= 2000.0f
;
89 m4x3_mul( gate
->transport
, cam
->transform
, gate_view
.transform
);
90 camera_update_view( &gate_view
);
91 camera_update_projection( &gate_view
);
93 /* Add special clipping plane to projection */
95 m3x3_mulv( gate
->recv_to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
96 surface
[3] = v3_dot( surface
, gate
->co
[1] );
98 m4x3_mulp( gate_view
.transform_inverse
, surface
, surface
);
99 surface
[3] = -fabsf(surface
[3]);
102 m4x4_clip_projection( gate_view
.mtx
.p
, surface
);
104 /* Ready to draw with new camrea */
105 camera_finalize( &gate_view
);
107 vg_line_pt3( gate_view
.transform
[3], 0.3f
, 0xff00ff00 );
110 m4x3_copy( gate
->to_world
, gate_xform
);
111 m4x3_scalev( gate_xform
, (v3f
){ gate
->dims
[0], gate
->dims
[1], 1.0f
} );
114 shader_gatelq_uPv( cam
->mtx
.pv
);
115 shader_gatelq_uMdl( gate_xform
);
116 shader_gatelq_uCam( cam
->pos
);
117 shader_gatelq_uTime( vg
.time
*0.25f
);
118 shader_gatelq_uInvRes( (v2f
){
119 1.0f
/ (float)vg
.window_x
,
120 1.0f
/ (float)vg
.window_y
});
122 glEnable( GL_STENCIL_TEST
);
123 glStencilOp( GL_KEEP
, GL_KEEP
, GL_REPLACE
);
124 glStencilFunc( GL_ALWAYS
, 1, 0xFF );
125 glStencilMask( 0xFF );
127 mesh_bind( &world
.mesh_gate_surface
);
128 mesh_draw( &world
.mesh_gate_surface
);
130 glClear( GL_DEPTH_BUFFER_BIT
);
131 glStencilFunc( GL_EQUAL
, 1, 0xFF );
132 glStencilMask( 0x00 );
135 render_world( &gate_view
);
138 glDisable( GL_STENCIL_TEST
);
140 render_water_texture( &gate_view
);
141 render_fb_bind( gpipeline
.fb_main
);
143 glEnable( GL_STENCIL_TEST
);
145 render_water_surface( &gate_view
);
147 glStencilMask( 0xFF );
148 glStencilFunc( GL_ALWAYS
, 1, 0xFF );
149 glDisable( GL_STENCIL_TEST
);
155 VG_STATIC
int gate_intersect_plane( teleport_gate
*gate
, v3f pos
, v3f last
,
159 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
160 surface
[3] = v3_dot( surface
, gate
->co
[0] );
162 v3f v0
, c
, delta
, p0
;
163 v3_sub( pos
, last
, v0
);
164 float l
= v3_length( v0
);
169 v3_divs( v0
, l
, v0
);
171 v3_muls( surface
, surface
[3], c
);
172 v3_sub( c
, last
, delta
);
174 float d
= v3_dot( surface
, v0
);
178 float t
= v3_dot(delta
, surface
) / d
;
179 if( t
>= 0.0f
&& t
<= l
)
182 v3_muladds( last
, v0
, t
, local
);
183 v3_sub( gate
->co
[0], local
, rel
);
186 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,1.0f
,0.0f
}, vup
);
187 m3x3_mulv( gate
->to_world
, (v3f
){1.0f
,0.0f
,0.0f
}, vside
);
189 where
[0] = v3_dot( rel
, vside
);
190 where
[1] = v3_dot( rel
, vup
);
199 VG_STATIC
int gate_intersect( teleport_gate
*gate
, v3f pos
, v3f last
)
203 if( gate_intersect_plane( gate
, pos
, last
, xy
) )
205 if( fabsf(xy
[0]) <= gate
->dims
[0] && fabsf(xy
[1]) <= gate
->dims
[1] )
214 #endif /* WORLD_GATE_H */