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
);
55 if( v3_dot(v0
, gatedir
) >= 0.0f
)
58 if( v3_dist( cam
->pos
, gate
->co
[0] ) > 100.0f
)
64 float sx
= gate
->dims
[0],
66 m4x3_mulv( gate
->to_world
, (v3f
){-sx
,-sy
,0.0f
}, a
);
67 m4x3_mulv( gate
->to_world
, (v3f
){ sx
,-sy
,0.0f
}, b
);
68 m4x3_mulv( gate
->to_world
, (v3f
){ sx
, sy
,0.0f
}, c
);
69 m4x3_mulv( gate
->to_world
, (v3f
){-sx
, sy
,0.0f
}, d
);
71 vg_line( a
,b
, 0xffffa000 );
72 vg_line( b
,c
, 0xffffa000 );
73 vg_line( c
,d
, 0xffffa000 );
74 vg_line( d
,a
, 0xffffa000 );
76 vg_line2( gate
->co
[0], gate
->co
[1], 0xff0000ff, 0x00000000 );
79 /* update gate camera */
80 static camera gate_view
;
81 gate_view
.fov
= cam
->fov
;
82 gate_view
.nearz
= 0.1f
;
83 gate_view
.farz
= 900.0f
;
85 m4x3_mul( gate
->transport
, cam
->transform
, gate_view
.transform
);
86 camera_update_view( &gate_view
);
87 camera_update_projection( &gate_view
);
89 /* Add special clipping plane to projection */
91 m3x3_mulv( gate
->recv_to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
92 surface
[3] = v3_dot( surface
, gate
->co
[1] );
94 m4x3_mulp( gate_view
.transform_inverse
, surface
, surface
);
95 surface
[3] = -fabsf(surface
[3]);
96 m4x4_clip_projection( gate_view
.mtx
.p
, surface
);
98 /* Ready to draw with new camrea */
99 camera_finalize( &gate_view
);
101 vg_line_pt3( gate_view
.transform
[3], 0.3f
, 0xff00ff00 );
104 m4x3_copy( gate
->to_world
, gate_xform
);
105 m4x3_scalev( gate_xform
, (v3f
){ gate
->dims
[0], gate
->dims
[1], 1.0f
} );
108 shader_gatelq_uPv( cam
->mtx
.pv
);
109 shader_gatelq_uMdl( gate_xform
);
110 shader_gatelq_uCam( cam
->pos
);
111 shader_gatelq_uTime( vg
.time
*0.25f
);
112 shader_gatelq_uInvRes( (v2f
){
113 1.0f
/ (float)vg
.window_x
,
114 1.0f
/ (float)vg
.window_y
});
116 glEnable( GL_STENCIL_TEST
);
117 glStencilOp( GL_KEEP
, GL_KEEP
, GL_REPLACE
);
118 glStencilFunc( GL_ALWAYS
, 1, 0xFF );
119 glStencilMask( 0xFF );
121 mesh_bind( &world
.mesh_gate_surface
);
122 mesh_draw( &world
.mesh_gate_surface
);
124 glClear( GL_DEPTH_BUFFER_BIT
);
125 glStencilFunc( GL_EQUAL
, 1, 0xFF );
126 glStencilMask( 0x00 );
129 render_world( &gate_view
);
132 glDisable( GL_STENCIL_TEST
);
134 render_water_texture( &gate_view
);
136 glEnable( GL_STENCIL_TEST
);
138 render_water_surface( &gate_view
);
140 glStencilMask( 0xFF );
141 glStencilFunc( GL_ALWAYS
, 1, 0xFF );
142 glDisable( GL_STENCIL_TEST
);
148 VG_STATIC
int gate_intersect( teleport_gate
*gate
, v3f pos
, v3f last
)
151 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,0.0f
,-1.0f
}, surface
);
152 surface
[3] = v3_dot( surface
, gate
->co
[0] );
154 v3f v0
, c
, delta
, p0
;
155 v3_sub( pos
, last
, v0
);
156 float l
= v3_length( v0
);
161 v3_divs( v0
, l
, v0
);
163 v3_muls( surface
, surface
[3], c
);
164 v3_sub( c
, last
, delta
);
166 float d
= v3_dot( surface
, v0
);
170 float t
= v3_dot(delta
, surface
) / d
;
171 if( t
>= 0.0f
&& t
<= l
)
174 v3_muladds( last
, v0
, t
, local
);
175 v3_sub( gate
->co
[0], local
, rel
);
178 m3x3_mulv( gate
->to_world
, (v3f
){0.0f
,1.0f
,0.0f
}, vup
);
179 m3x3_mulv( gate
->to_world
, (v3f
){1.0f
,0.0f
,0.0f
}, vside
);
181 v2f xy
= { v3_dot( rel
, vside
), v3_dot( rel
, vup
) };
183 if( fabsf(xy
[0]) <= gate
->dims
[0] && fabsf(xy
[1]) <= gate
->dims
[1] )
193 #endif /* WORLD_GATE_H */