Quake II RTX doxygen  1.0 dev
freecam.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 2019, NVIDIA CORPORATION. All rights reserved.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 
19 #include "vkpt.h"
20 #include "../../client/client.h"
21 
22 /*
23 The FreeCam system activates when the user pauses the game.
24 In that case, all game input is redirected into this subsystem,
25 which processes certain keys and mouse movement to control the
26 camera position, orientation, zoom, focus, and aperture.
27 
28 When the camera is moved for the first time after activating
29 the freecam mode, the gun is removed from the view, and the
30 player model is switched to third person.
31 */
32 
33 
34 static vec3_t freecam_vieworg = { 0.f };
35 static vec3_t freecam_viewangles = { 0.f };
36 static float freecam_zoom = 1.f;
37 static qboolean freecam_keystate[6] = { 0 };
38 static qboolean freecam_active = qfalse;
39 static int freecam_player_model = 0;
40 
41 extern float autosens_x;
42 extern float autosens_y;
43 extern cvar_t *m_accel;
44 extern cvar_t *m_autosens;
45 extern cvar_t *m_pitch;
46 extern cvar_t *m_invert;
47 extern cvar_t *m_yaw;
48 extern cvar_t *sensitivity;
49 extern cvar_t *cvar_pt_dof;
50 extern cvar_t *cvar_pt_aperture;
51 extern cvar_t *cvar_pt_focus;
52 extern cvar_t *cvar_pt_freecam;
53 
54 
56 {
57  if (!freecam_active)
58  return;
59 
61  freecam_active = qfalse;
62 }
63 
65 {
66  int dx, dy;
67  float mx, my;
68  float speed;
69 
70  const inputAPI_t* api = IN_GetAPI();
71 
72  if (!api->GetMotion)
73  return;
74 
75  if (!api->GetMotion(&dx, &dy))
76  return;
77 
78  mx = dx;
79  my = dy;
80 
81  if (!mx && !my) {
82  return;
83  }
84 
85  if (Key_IsDown(K_MOUSE1) && Key_IsDown(K_MOUSE2))
86  {
87  mx *= sensitivity->value;
88  freecam_viewangles[ROLL] += m_yaw->value * mx;
89  }
90  else if (Key_IsDown(K_MOUSE1))
91  {
92  Cvar_ClampValue(m_accel, 0, 1);
93 
94  speed = sqrt(mx * mx + my * my);
95  speed = sensitivity->value + speed * m_accel->value;
96 
97  mx *= speed;
98  my *= speed;
99 
100  if (m_autosens->integer) {
101  mx *= cl.fov_x * autosens_x;
102  my *= cl.fov_y * autosens_y;
103  }
104 
105  mx /= freecam_zoom;
106  my /= freecam_zoom;
107 
108  freecam_viewangles[YAW] -= m_yaw->value * mx;
109  freecam_viewangles[PITCH] += m_pitch->value * my * (m_invert->integer ? -1.f : 1.f);
110 
111  freecam_viewangles[PITCH] = max(-90.f, min(90.f, freecam_viewangles[PITCH]));
112  }
113  else if (Key_IsDown(K_MOUSE2))
114  {
115  freecam_zoom *= powf(0.5f, my * m_pitch->value * 0.1f);
116  freecam_zoom = max(0.5f, min(20.f, freecam_zoom));
117  }
118 }
119 
120 void vkpt_freecam_update(float frame_time)
121 {
122  if (cl_paused->integer != 2 || !sv_paused->integer || !cvar_pt_freecam->integer)
123  {
125  return;
126  }
127 
128  if (!freecam_active)
129  {
130  VectorCopy(vkpt_refdef.fd->vieworg, freecam_vieworg);
131  VectorCopy(vkpt_refdef.fd->viewangles, freecam_viewangles);
132  freecam_zoom = 1.f;
134  freecam_active = qtrue;
135  }
136 
137  vec3_t prev_vieworg;
138  vec3_t prev_viewangles;
139  VectorCopy(freecam_vieworg, prev_vieworg);
140  VectorCopy(freecam_viewangles, prev_viewangles);
141  float prev_zoom = freecam_zoom;
142 
143  vec3_t velocity = { 0.f };
144  if (freecam_keystate[0]) velocity[0] += 1.f;
145  if (freecam_keystate[1]) velocity[0] -= 1.f;
146  if (freecam_keystate[2]) velocity[1] += 1.f;
147  if (freecam_keystate[3]) velocity[1] -= 1.f;
148  if (freecam_keystate[4]) velocity[2] += 1.f;
149  if (freecam_keystate[5]) velocity[2] -= 1.f;
150 
151  if (Key_IsDown(K_SHIFT))
152  VectorScale(velocity, 5.f, velocity);
153  else if (Key_IsDown(K_CTRL))
154  VectorScale(velocity, 0.1f, velocity);
155 
156  vec3_t forward, right, up;
158  float speed = 100.f;
159  VectorMA(freecam_vieworg, velocity[0] * frame_time * speed, forward, freecam_vieworg);
160  VectorMA(freecam_vieworg, velocity[1] * frame_time * speed, right, freecam_vieworg);
161  VectorMA(freecam_vieworg, velocity[2] * frame_time * speed, up, freecam_vieworg);
162 
164 
165  VectorCopy(freecam_vieworg, vkpt_refdef.fd->vieworg);
166  VectorCopy(freecam_viewangles, vkpt_refdef.fd->viewangles);
167  vkpt_refdef.fd->fov_x = RAD2DEG(atanf(tanf(DEG2RAD(vkpt_refdef.fd->fov_x) * 0.5f) / freecam_zoom)) * 2.f;
168  vkpt_refdef.fd->fov_y = RAD2DEG(atanf(tanf(DEG2RAD(vkpt_refdef.fd->fov_y) * 0.5f) / freecam_zoom)) * 2.f;
169 
170  if (!VectorCompare(freecam_vieworg, prev_vieworg) || !VectorCompare(freecam_viewangles, prev_viewangles))
171  {
174 
176  }
177 
178  if (freecam_zoom != prev_zoom)
179  {
180  // zoom doesn't reset the player model, but does reset the accumulation
182  }
183 }
184 
185 qboolean R_InterceptKey_RTX(unsigned key, qboolean down)
186 {
187  if (cl_paused->integer != 2 || !sv_paused->integer)
188  return qfalse;
189 
190  const char* kb = Key_GetBindingForKey(key);
191  if (kb && strstr(kb, "pause"))
192  return qfalse;
193 
194  if (cvar_pt_dof->integer != 0 && down && (key == K_MWHEELUP || key == K_MWHEELDOWN))
195  {
196  cvar_t* var;
197  float minvalue;
198  float maxvalue;
199 
200  if (Key_IsDown(K_SHIFT))
201  {
202  var = cvar_pt_aperture;
203  minvalue = 0.01f;
204  maxvalue = 10.f;
205  }
206  else
207  {
208  var = cvar_pt_focus;
209  minvalue = 1.f;
210  maxvalue = 10000.f;
211  }
212 
213  float factor = Key_IsDown(K_CTRL) ? 1.01f : 1.1f;
214 
215  if (key == K_MWHEELDOWN)
216  factor = 1.f / factor;
217 
218  float value = var->value;
219  value *= factor;
220  value = max(minvalue, min(maxvalue, value));
221  Cvar_SetByVar(var, va("%f", value), FROM_CONSOLE);
222 
223  return qtrue;
224  }
225 
226  switch (key)
227  {
228  case 'w': freecam_keystate[0] = down; return qtrue;
229  case 's': freecam_keystate[1] = down; return qtrue;
230  case 'd': freecam_keystate[2] = down; return qtrue;
231  case 'a': freecam_keystate[3] = down; return qtrue;
232  case 'e': freecam_keystate[4] = down; return qtrue;
233  case 'q': freecam_keystate[5] = down; return qtrue;
234 
235  // make sure that other keys that control the freecam mode don't
236  // interfere with the game, for example MOUSE1 usually maps to fire
237  case K_CTRL:
238  case K_SHIFT:
239  case K_MWHEELDOWN:
240  case K_MWHEELUP:
241  case K_MOUSE1:
242  case K_MOUSE2:
243  return qtrue;
244  }
245 
246  return qfalse;
247 }
Key_GetBindingForKey
char * Key_GetBindingForKey(int keynum)
Definition: keys.c:310
m_yaw
cvar_t * m_yaw
Definition: input.c:52
sensitivity
cvar_t * sensitivity
Definition: input.c:48
vkpt_freecam_mousemove
static void vkpt_freecam_mousemove()
Definition: freecam.c:64
freecam_keystate
static qboolean freecam_keystate[6]
Definition: freecam.c:37
vkpt_refdef
vkpt_refdef_t vkpt_refdef
Definition: main.c:372
m_accel
cvar_t * m_accel
Definition: input.c:34
m_invert
cvar_t * m_invert
Definition: input.c:51
m_pitch
cvar_t * m_pitch
Definition: input.c:50
vkpt.h
sv_paused
cvar_t * sv_paused
Definition: common.c:96
freecam_active
static qboolean freecam_active
Definition: freecam.c:38
autosens_x
float autosens_x
Definition: input.c:492
cvar_pt_aperture
cvar_t * cvar_pt_aperture
freecam_zoom
static float freecam_zoom
Definition: freecam.c:36
cvar_pt_dof
cvar_t * cvar_pt_dof
Definition: main.c:57
CL_PLAYER_MODEL_DISABLED
#define CL_PLAYER_MODEL_DISABLED
Definition: client.h:553
vkpt_refdef_s::fd
refdef_t * fd
Definition: vkpt.h:396
forward
static vec3_t forward
Definition: p_view.c:27
cl_player_model
cvar_t * cl_player_model
Definition: main.c:47
Cvar_ClampValue
float Cvar_ClampValue(cvar_t *var, float min, float max)
Definition: cvar.c:571
cvar_pt_freecam
cvar_t * cvar_pt_freecam
Definition: main.c:58
va
char * va(const char *format,...)
Definition: shared.c:429
m_autosens
cvar_t * m_autosens
Definition: input.c:35
cvar_pt_focus
cvar_t * cvar_pt_focus
freecam_vieworg
static vec3_t freecam_vieworg
Definition: freecam.c:34
Key_IsDown
int Key_IsDown(int key)
Definition: keys.c:204
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: shared.c:23
freecam_viewangles
static vec3_t freecam_viewangles
Definition: freecam.c:35
IN_GetAPI
const inputAPI_t * IN_GetAPI()
Definition: input.c:79
Cvar_SetByVar
void Cvar_SetByVar(cvar_t *var, const char *value, from_t from)
Definition: cvar.c:345
freecam_player_model
static int freecam_player_model
Definition: freecam.c:39
R_InterceptKey_RTX
qboolean R_InterceptKey_RTX(unsigned key, qboolean down)
Definition: freecam.c:185
cl
client_state_t cl
Definition: main.c:99
up
static vec3_t up
Definition: p_view.c:27
client_state_s::fov_x
float fov_x
Definition: client.h:254
right
static vec3_t right
Definition: p_view.c:27
vkpt_reset_accumulation
void vkpt_reset_accumulation()
Definition: main.c:219
autosens_y
float autosens_y
Definition: input.c:493
vkpt_freecam_reset
void vkpt_freecam_reset()
Definition: freecam.c:55
client_state_s::fov_y
float fov_y
Definition: client.h:255
vkpt_freecam_update
void vkpt_freecam_update(float frame_time)
Definition: freecam.c:120
CL_PLAYER_MODEL_THIRD_PERSON
#define CL_PLAYER_MODEL_THIRD_PERSON
Definition: client.h:556