diff options
Diffstat (limited to 'linden/indra/newview/llviewerjoystick.cpp')
-rw-r--r-- | linden/indra/newview/llviewerjoystick.cpp | 993 |
1 files changed, 859 insertions, 134 deletions
diff --git a/linden/indra/newview/llviewerjoystick.cpp b/linden/indra/newview/llviewerjoystick.cpp index e3db0f2..e9690f8 100644 --- a/linden/indra/newview/llviewerjoystick.cpp +++ b/linden/indra/newview/llviewerjoystick.cpp | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /** |
2 | * @file llviewerjoystick.cpp | 2 | * @file llviewerjoystick.cpp |
3 | * @brief Joystick functionality. | 3 | * @brief Joystick / NDOF device functionality. |
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2002&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2002&license=viewergpl$ |
6 | * | 6 | * |
@@ -30,39 +30,701 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include "llviewerprecompiledheaders.h" | 32 | #include "llviewerprecompiledheaders.h" |
33 | |||
34 | #include "llviewerjoystick.h" | ||
35 | |||
33 | #include "llviewercontrol.h" | 36 | #include "llviewercontrol.h" |
34 | #include "llviewerwindow.h" | 37 | #include "llviewerwindow.h" |
35 | #include "llviewercamera.h" | 38 | #include "llviewercamera.h" |
36 | #include "llviewerjoystick.h" | ||
37 | #include "llappviewer.h" | 39 | #include "llappviewer.h" |
38 | #include "llkeyboard.h" | 40 | #include "llkeyboard.h" |
41 | #include "lltoolmgr.h" | ||
42 | #include "llselectmgr.h" | ||
43 | #include "llviewermenu.h" | ||
44 | #include "llagent.h" | ||
45 | #include "llfocusmgr.h" | ||
46 | |||
47 | |||
48 | // ---------------------------------------------------------------------------- | ||
49 | // Constants | ||
50 | |||
51 | #define X_I 1 | ||
52 | #define Y_I 2 | ||
53 | #define Z_I 0 | ||
54 | #define RX_I 4 | ||
55 | #define RY_I 5 | ||
56 | #define RZ_I 3 | ||
39 | 57 | ||
40 | static LLQuaternion sFlycamRotation; | 58 | // flycam translations in build mode should be reduced |
41 | static LLVector3 sFlycamPosition; | 59 | const F32 BUILDMODE_FLYCAM_T_SCALE = 3.f; |
42 | static F32 sFlycamZoom; | ||
43 | 60 | ||
44 | BOOL LLViewerJoystick::sOverrideCamera = FALSE; | 61 | F32 LLViewerJoystick::sLastDelta[] = {0,0,0,0,0,0,0}; |
62 | F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0}; | ||
45 | 63 | ||
46 | void LLViewerJoystick::updateCamera(BOOL reset) | 64 | // These constants specify the maximum absolute value coming in from the device. |
65 | // HACK ALERT! the value of MAX_JOYSTICK_INPUT_VALUE is not arbitrary as it | ||
66 | // should be. It has to be equal to 3000 because the SpaceNavigator on Windows | ||
67 | // refuses to respond to the DirectInput SetProperty call; it always returns | ||
68 | // values in the [-3000, 3000] range. | ||
69 | #define MAX_SPACENAVIGATOR_INPUT 3000.0f | ||
70 | #define MAX_JOYSTICK_INPUT_VALUE MAX_SPACENAVIGATOR_INPUT | ||
71 | |||
72 | // ----------------------------------------------------------------------------- | ||
73 | void LLViewerJoystick::updateEnabled(bool autoenable) | ||
47 | { | 74 | { |
48 | static F32 last_delta[] = {0,0,0,0,0,0,0}; | 75 | if (mDriverState == JDS_UNINITIALIZED) |
49 | static F32 delta[] = { 0,0,0,0,0,0,0 }; | 76 | { |
77 | gSavedSettings.setBOOL("JoystickEnabled", FALSE ); | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | if (isLikeSpaceNavigator() && autoenable) | ||
82 | { | ||
83 | gSavedSettings.setBOOL("JoystickEnabled", TRUE ); | ||
84 | } | ||
85 | } | ||
86 | if (!gSavedSettings.getBOOL("JoystickEnabled")) | ||
87 | { | ||
88 | mOverrideCamera = FALSE; | ||
89 | } | ||
90 | } | ||
50 | 91 | ||
51 | LLWindow* window = gViewerWindow->getWindow(); | 92 | void LLViewerJoystick::setOverrideCamera(bool val) |
93 | { | ||
94 | if (!gSavedSettings.getBOOL("JoystickEnabled")) | ||
95 | { | ||
96 | mOverrideCamera = FALSE; | ||
97 | } | ||
98 | else | ||
99 | { | ||
100 | mOverrideCamera = val; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | // ----------------------------------------------------------------------------- | ||
105 | #if LIB_NDOF | ||
106 | NDOF_HotPlugResult LLViewerJoystick::HotPlugAddCallback(NDOF_Device *dev) | ||
107 | { | ||
108 | NDOF_HotPlugResult res = NDOF_DISCARD_HOTPLUGGED; | ||
109 | LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); | ||
110 | if (joystick->mDriverState == JDS_UNINITIALIZED) | ||
111 | { | ||
112 | llinfos << "HotPlugAddCallback: will use device:" << llendl; | ||
113 | ndof_dump(dev); | ||
114 | joystick->mNdofDev = dev; | ||
115 | joystick->mDriverState = JDS_INITIALIZED; | ||
116 | res = NDOF_KEEP_HOTPLUGGED; | ||
117 | } | ||
118 | joystick->updateEnabled(true); | ||
119 | return res; | ||
120 | } | ||
121 | #endif | ||
122 | |||
123 | // ----------------------------------------------------------------------------- | ||
124 | #if LIB_NDOF | ||
125 | void LLViewerJoystick::HotPlugRemovalCallback(NDOF_Device *dev) | ||
126 | { | ||
127 | LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); | ||
128 | if (joystick->mNdofDev == dev) | ||
129 | { | ||
130 | llinfos << "HotPlugRemovalCallback: joystick->mNdofDev=" | ||
131 | << joystick->mNdofDev << "; removed device:" << llendl; | ||
132 | ndof_dump(dev); | ||
133 | joystick->mDriverState = JDS_UNINITIALIZED; | ||
134 | } | ||
135 | joystick->updateEnabled(true); | ||
136 | } | ||
137 | #endif | ||
138 | |||
139 | // ----------------------------------------------------------------------------- | ||
140 | LLViewerJoystick::LLViewerJoystick() | ||
141 | : mDriverState(JDS_UNINITIALIZED), | ||
142 | mNdofDev(NULL), | ||
143 | mResetFlag(false), | ||
144 | mCameraUpdated(true), | ||
145 | mOverrideCamera(false) | ||
146 | { | ||
147 | for (int i = 0; i < 6; i++) | ||
148 | { | ||
149 | mAxes[i] = sDelta[i] = sLastDelta[i] = 0.0f; | ||
150 | } | ||
151 | |||
152 | memset(mBtn, 0, sizeof(mBtn)); | ||
153 | |||
154 | // factor in bandwidth? bandwidth = gViewerStats->mKBitStat | ||
155 | mPerfScale = 4000.f / gSysCPU.getMhz(); | ||
156 | } | ||
157 | |||
158 | // ----------------------------------------------------------------------------- | ||
159 | LLViewerJoystick::~LLViewerJoystick() | ||
160 | { | ||
161 | if (mDriverState == JDS_INITIALIZED) | ||
162 | { | ||
163 | terminate(); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | // ----------------------------------------------------------------------------- | ||
168 | void LLViewerJoystick::init(bool autoenable) | ||
169 | { | ||
170 | #if LIB_NDOF | ||
171 | static bool libinit = false; | ||
172 | mDriverState = JDS_INITIALIZING; | ||
52 | 173 | ||
174 | if (libinit == false) | ||
175 | { | ||
176 | // Note: The HotPlug callbacks are not actually getting called on Windows | ||
177 | if (ndof_libinit(HotPlugAddCallback, | ||
178 | HotPlugRemovalCallback, | ||
179 | NULL)) | ||
180 | { | ||
181 | mDriverState = JDS_UNINITIALIZED; | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | // NB: ndof_libinit succeeds when there's no device | ||
186 | libinit = true; | ||
187 | |||
188 | // allocate memory once for an eventual device | ||
189 | mNdofDev = ndof_create(); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | if (libinit) | ||
194 | { | ||
195 | if (mNdofDev) | ||
196 | { | ||
197 | // Different joysticks will return different ranges of raw values. | ||
198 | // Since we want to handle every device in the same uniform way, | ||
199 | // we initialize the mNdofDev struct and we set the range | ||
200 | // of values we would like to receive. | ||
201 | // | ||
202 | // HACK: On Windows, libndofdev passes our range to DI with a | ||
203 | // SetProperty call. This works but with one notable exception, the | ||
204 | // SpaceNavigator, who doesn't seem to care about the SetProperty | ||
205 | // call. In theory, we should handle this case inside libndofdev. | ||
206 | // However, the range we're setting here is arbitrary anyway, | ||
207 | // so let's just use the SpaceNavigator range for our purposes. | ||
208 | mNdofDev->axes_min = (long)-MAX_JOYSTICK_INPUT_VALUE; | ||
209 | mNdofDev->axes_max = (long)+MAX_JOYSTICK_INPUT_VALUE; | ||
210 | |||
211 | // libndofdev could be used to return deltas. Here we choose to | ||
212 | // just have the absolute values instead. | ||
213 | mNdofDev->absolute = 1; | ||
214 | |||
215 | // init & use the first suitable NDOF device found on the USB chain | ||
216 | if (ndof_init_first(mNdofDev, NULL)) | ||
217 | { | ||
218 | mDriverState = JDS_UNINITIALIZED; | ||
219 | llwarns << "ndof_init_first FAILED" << llendl; | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | mDriverState = JDS_INITIALIZED; | ||
224 | } | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | mDriverState = JDS_UNINITIALIZED; | ||
229 | } | ||
230 | } | ||
231 | updateEnabled(autoenable); | ||
232 | |||
233 | llinfos << "ndof: mDriverState=" << mDriverState << "; mNdofDev=" | ||
234 | << mNdofDev << "; libinit=" << libinit << llendl; | ||
235 | #endif | ||
236 | } | ||
237 | |||
238 | // ----------------------------------------------------------------------------- | ||
239 | void LLViewerJoystick::terminate() | ||
240 | { | ||
241 | #if LIB_NDOF | ||
242 | |||
243 | ndof_libcleanup(); | ||
244 | llinfos << "Terminated connection with NDOF device." << llendl; | ||
245 | |||
246 | #endif | ||
247 | } | ||
248 | |||
249 | // ----------------------------------------------------------------------------- | ||
250 | void LLViewerJoystick::updateStatus() | ||
251 | { | ||
252 | #if LIB_NDOF | ||
253 | |||
254 | ndof_update(mNdofDev); | ||
255 | |||
256 | for (int i=0; i<6; i++) | ||
257 | { | ||
258 | mAxes[i] = (F32) mNdofDev->axes[i] / mNdofDev->axes_max; | ||
259 | } | ||
260 | |||
261 | for (int i=0; i<16; i++) | ||
262 | { | ||
263 | mBtn[i] = mNdofDev->buttons[i]; | ||
264 | } | ||
265 | |||
266 | #endif | ||
267 | } | ||
268 | |||
269 | // ----------------------------------------------------------------------------- | ||
270 | F32 LLViewerJoystick::getJoystickAxis(U32 axis) const | ||
271 | { | ||
272 | if (axis < 6) | ||
273 | { | ||
274 | return mAxes[axis]; | ||
275 | } | ||
276 | return 0.f; | ||
277 | } | ||
278 | |||
279 | // ----------------------------------------------------------------------------- | ||
280 | U32 LLViewerJoystick::getJoystickButton(U32 button) const | ||
281 | { | ||
282 | if (button < 16) | ||
283 | { | ||
284 | return mBtn[button]; | ||
285 | } | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | // ----------------------------------------------------------------------------- | ||
290 | void LLViewerJoystick::agentJump() | ||
291 | { | ||
292 | gAgent.moveUp(1); | ||
293 | } | ||
294 | |||
295 | // ----------------------------------------------------------------------------- | ||
296 | void LLViewerJoystick::agentSlide(F32 inc) | ||
297 | { | ||
298 | if (inc < 0) | ||
299 | { | ||
300 | gAgent.moveLeft(1); | ||
301 | } | ||
302 | else if (inc > 0) | ||
303 | { | ||
304 | gAgent.moveLeft(-1); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | // ----------------------------------------------------------------------------- | ||
309 | void LLViewerJoystick::agentPush(F32 inc) | ||
310 | { | ||
311 | if (inc < 0) // forward | ||
312 | { | ||
313 | gAgent.moveAt(1, false); | ||
314 | } | ||
315 | else if (inc > 0) // backward | ||
316 | { | ||
317 | gAgent.moveAt(-1, false); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | // ----------------------------------------------------------------------------- | ||
322 | void LLViewerJoystick::agentFly(F32 inc) | ||
323 | { | ||
324 | if (inc < 0) | ||
325 | { | ||
326 | if (gAgent.getFlying()) | ||
327 | { | ||
328 | gAgent.moveUp(1); | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | gAgent.setFlying(true); | ||
333 | } | ||
334 | } | ||
335 | else if (inc > 0) | ||
336 | { | ||
337 | // crouch | ||
338 | gAgent.moveUp(-1); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | // ----------------------------------------------------------------------------- | ||
343 | void LLViewerJoystick::agentRotate(F32 pitch_inc, F32 yaw_inc) | ||
344 | { | ||
345 | LLQuaternion new_rot; | ||
346 | pitch_inc = gAgent.clampPitchToLimits(-pitch_inc); | ||
347 | const LLQuaternion qx(pitch_inc, gAgent.getLeftAxis()); | ||
348 | const LLQuaternion qy(-yaw_inc, gAgent.getReferenceUpVector()); | ||
349 | new_rot.setQuat(qx * qy); | ||
350 | gAgent.rotate(new_rot); | ||
351 | } | ||
352 | |||
353 | // ----------------------------------------------------------------------------- | ||
354 | void LLViewerJoystick::resetDeltas(S32 axis[], bool flycam_and_build_mode) | ||
355 | { | ||
356 | for (U32 i = 0; i < 6; i++) | ||
357 | { | ||
358 | sLastDelta[i] = -mAxes[axis[i]]; | ||
359 | sDelta[i] = 0.f; | ||
360 | } | ||
361 | |||
362 | if (flycam_and_build_mode) | ||
363 | { | ||
364 | sLastDelta[X_I] /= BUILDMODE_FLYCAM_T_SCALE; | ||
365 | sLastDelta[Y_I] /= BUILDMODE_FLYCAM_T_SCALE; | ||
366 | sLastDelta[Z_I] /= BUILDMODE_FLYCAM_T_SCALE; | ||
367 | } | ||
368 | |||
369 | sLastDelta[6] = sDelta[6] = 0.f; | ||
370 | mResetFlag = false; | ||
371 | } | ||
372 | |||
373 | // ----------------------------------------------------------------------------- | ||
374 | void LLViewerJoystick::moveObjects(bool reset) | ||
375 | { | ||
376 | static bool toggle_send_to_sim = false; | ||
377 | |||
378 | if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED | ||
379 | || !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickBuildEnabled")) | ||
380 | { | ||
381 | return; | ||
382 | } | ||
383 | |||
384 | S32 axis[] = | ||
385 | { | ||
386 | gSavedSettings.getS32("JoystickAxis0"), | ||
387 | gSavedSettings.getS32("JoystickAxis1"), | ||
388 | gSavedSettings.getS32("JoystickAxis2"), | ||
389 | gSavedSettings.getS32("JoystickAxis3"), | ||
390 | gSavedSettings.getS32("JoystickAxis4"), | ||
391 | gSavedSettings.getS32("JoystickAxis5"), | ||
392 | }; | ||
393 | |||
394 | if (reset || mResetFlag) | ||
395 | { | ||
396 | resetDeltas(axis); | ||
397 | return; | ||
398 | } | ||
399 | |||
400 | F32 axis_scale[] = | ||
401 | { | ||
402 | gSavedSettings.getF32("BuildAxisScale0"), | ||
403 | gSavedSettings.getF32("BuildAxisScale1"), | ||
404 | gSavedSettings.getF32("BuildAxisScale2"), | ||
405 | gSavedSettings.getF32("BuildAxisScale3"), | ||
406 | gSavedSettings.getF32("BuildAxisScale4"), | ||
407 | gSavedSettings.getF32("BuildAxisScale5"), | ||
408 | }; | ||
409 | |||
410 | F32 dead_zone[] = | ||
411 | { | ||
412 | gSavedSettings.getF32("BuildAxisDeadZone0"), | ||
413 | gSavedSettings.getF32("BuildAxisDeadZone1"), | ||
414 | gSavedSettings.getF32("BuildAxisDeadZone2"), | ||
415 | gSavedSettings.getF32("BuildAxisDeadZone3"), | ||
416 | gSavedSettings.getF32("BuildAxisDeadZone4"), | ||
417 | gSavedSettings.getF32("BuildAxisDeadZone5"), | ||
418 | }; | ||
419 | |||
420 | F32 cur_delta[6]; | ||
53 | F32 time = gFrameIntervalSeconds; | 421 | F32 time = gFrameIntervalSeconds; |
54 | 422 | ||
423 | // avoid making ridicously big movements if there's a big drop in fps | ||
424 | if (time > .2f) | ||
425 | { | ||
426 | time = .2f; | ||
427 | } | ||
428 | |||
429 | // max feather is 32 | ||
430 | F32 feather = gSavedSettings.getF32("BuildFeathering"); | ||
431 | bool is_zero = true, absolute = gSavedSettings.getBOOL("Cursor3D"); | ||
432 | |||
433 | for (U32 i = 0; i < 6; i++) | ||
434 | { | ||
435 | cur_delta[i] = -mAxes[axis[i]]; | ||
436 | F32 tmp = cur_delta[i]; | ||
437 | if (absolute) | ||
438 | { | ||
439 | cur_delta[i] = cur_delta[i] - sLastDelta[i]; | ||
440 | } | ||
441 | sLastDelta[i] = tmp; | ||
442 | is_zero = is_zero && (cur_delta[i] == 0.f); | ||
443 | |||
444 | if (cur_delta[i] > 0) | ||
445 | { | ||
446 | cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f); | ||
447 | } | ||
448 | else | ||
449 | { | ||
450 | cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f); | ||
451 | } | ||
452 | cur_delta[i] *= axis_scale[i]; | ||
453 | |||
454 | if (!absolute) | ||
455 | { | ||
456 | cur_delta[i] *= time; | ||
457 | } | ||
458 | |||
459 | sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather; | ||
460 | } | ||
461 | |||
462 | U32 upd_type = UPD_NONE; | ||
463 | LLVector3 v; | ||
464 | |||
465 | if (!is_zero) | ||
466 | { | ||
467 | if (sDelta[0] || sDelta[1] || sDelta[2]) | ||
468 | { | ||
469 | upd_type |= UPD_POSITION; | ||
470 | v.setVec(sDelta[0], sDelta[1], sDelta[2]); | ||
471 | } | ||
472 | |||
473 | if (sDelta[3] || sDelta[4] || sDelta[5]) | ||
474 | { | ||
475 | upd_type |= UPD_ROTATION; | ||
476 | } | ||
477 | |||
478 | // the selection update could fail, so we won't send | ||
479 | if (LLSelectMgr::getInstance()->selectionMove(v, sDelta[3],sDelta[4],sDelta[5], upd_type)) | ||
480 | { | ||
481 | toggle_send_to_sim = true; | ||
482 | } | ||
483 | } | ||
484 | else if (toggle_send_to_sim) | ||
485 | { | ||
486 | LLSelectMgr::getInstance()->sendSelectionMove(); | ||
487 | toggle_send_to_sim = false; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | // ----------------------------------------------------------------------------- | ||
492 | void LLViewerJoystick::moveAvatar(bool reset) | ||
493 | { | ||
494 | if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED | ||
495 | || !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickAvatarEnabled")) | ||
496 | { | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | S32 axis[] = | ||
501 | { | ||
502 | // [1 0 2 4 3 5] | ||
503 | // [Z X Y RZ RX RY] | ||
504 | gSavedSettings.getS32("JoystickAxis0"), | ||
505 | gSavedSettings.getS32("JoystickAxis1"), | ||
506 | gSavedSettings.getS32("JoystickAxis2"), | ||
507 | gSavedSettings.getS32("JoystickAxis3"), | ||
508 | gSavedSettings.getS32("JoystickAxis4"), | ||
509 | gSavedSettings.getS32("JoystickAxis5") | ||
510 | }; | ||
511 | |||
512 | if (reset || mResetFlag) | ||
513 | { | ||
514 | resetDeltas(axis); | ||
515 | if (reset) | ||
516 | { | ||
517 | // Note: moving the agent triggers agent camera mode; | ||
518 | // don't do this every time we set mResetFlag (e.g. because we gained focus) | ||
519 | gAgent.moveAt(0, true); | ||
520 | } | ||
521 | return; | ||
522 | } | ||
523 | |||
524 | if (mBtn[1] == 1) | ||
525 | { | ||
526 | agentJump(); | ||
527 | return; | ||
528 | } | ||
529 | |||
530 | F32 axis_scale[] = | ||
531 | { | ||
532 | gSavedSettings.getF32("AvatarAxisScale0"), | ||
533 | gSavedSettings.getF32("AvatarAxisScale1"), | ||
534 | gSavedSettings.getF32("AvatarAxisScale2"), | ||
535 | gSavedSettings.getF32("AvatarAxisScale3"), | ||
536 | gSavedSettings.getF32("AvatarAxisScale4"), | ||
537 | gSavedSettings.getF32("AvatarAxisScale5") | ||
538 | }; | ||
539 | |||
540 | F32 dead_zone[] = | ||
541 | { | ||
542 | gSavedSettings.getF32("AvatarAxisDeadZone0"), | ||
543 | gSavedSettings.getF32("AvatarAxisDeadZone1"), | ||
544 | gSavedSettings.getF32("AvatarAxisDeadZone2"), | ||
545 | gSavedSettings.getF32("AvatarAxisDeadZone3"), | ||
546 | gSavedSettings.getF32("AvatarAxisDeadZone4"), | ||
547 | gSavedSettings.getF32("AvatarAxisDeadZone5") | ||
548 | }; | ||
549 | |||
550 | // time interval in seconds between this frame and the previous | ||
551 | F32 time = gFrameIntervalSeconds; | ||
552 | |||
553 | // avoid making ridicously big movements if there's a big drop in fps | ||
554 | if (time > .2f) | ||
555 | { | ||
556 | time = .2f; | ||
557 | } | ||
558 | |||
559 | // note: max feather is 32.0 | ||
560 | F32 feather = gSavedSettings.getF32("AvatarFeathering"); | ||
561 | |||
562 | F32 cur_delta[6]; | ||
563 | F32 val, dom_mov = 0.f; | ||
564 | U32 dom_axis = Z_I; | ||
565 | #if LIB_NDOF | ||
566 | bool absolute = (gSavedSettings.getBOOL("Cursor3D") && mNdofDev->absolute); | ||
567 | #else | ||
568 | bool absolute = false; | ||
569 | #endif | ||
570 | // remove dead zones and determine biggest movement on the joystick | ||
571 | for (U32 i = 0; i < 6; i++) | ||
572 | { | ||
573 | cur_delta[i] = -mAxes[axis[i]]; | ||
574 | if (absolute) | ||
575 | { | ||
576 | F32 tmp = cur_delta[i]; | ||
577 | cur_delta[i] = cur_delta[i] - sLastDelta[i]; | ||
578 | sLastDelta[i] = tmp; | ||
579 | } | ||
580 | |||
581 | if (cur_delta[i] > 0) | ||
582 | { | ||
583 | cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f); | ||
584 | } | ||
585 | else | ||
586 | { | ||
587 | cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f); | ||
588 | } | ||
589 | |||
590 | // we don't care about Roll (RZ) and Z is calculated after the loop | ||
591 | if (i != Z_I && i != RZ_I) | ||
592 | { | ||
593 | // find out the axis with the biggest joystick motion | ||
594 | val = fabs(cur_delta[i]); | ||
595 | if (val > dom_mov) | ||
596 | { | ||
597 | dom_axis = i; | ||
598 | dom_mov = val; | ||
599 | } | ||
600 | } | ||
601 | } | ||
602 | |||
603 | // forward|backward movements overrule the real dominant movement if | ||
604 | // they're bigger than its 20%. This is what you want cos moving forward | ||
605 | // is what you do most. We also added a special (even more lenient) case | ||
606 | // for RX|RY to allow walking while pitching n' turning | ||
607 | if (fabs(cur_delta[Z_I]) > .2f * dom_mov | ||
608 | || ((dom_axis == RX_I || dom_axis == RY_I) | ||
609 | && fabs(cur_delta[Z_I]) > .05f * dom_mov)) | ||
610 | { | ||
611 | dom_axis = Z_I; | ||
612 | } | ||
613 | |||
614 | sDelta[X_I] = -cur_delta[X_I] * axis_scale[X_I]; | ||
615 | sDelta[Y_I] = -cur_delta[Y_I] * axis_scale[Y_I]; | ||
616 | sDelta[Z_I] = -cur_delta[Z_I] * axis_scale[Z_I]; | ||
617 | cur_delta[RX_I] *= -axis_scale[RX_I] * mPerfScale; | ||
618 | cur_delta[RY_I] *= -axis_scale[RY_I] * mPerfScale; | ||
619 | |||
620 | if (!absolute) | ||
621 | { | ||
622 | cur_delta[RX_I] *= time; | ||
623 | cur_delta[RY_I] *= time; | ||
624 | } | ||
625 | sDelta[RX_I] += (cur_delta[RX_I] - sDelta[RX_I]) * time * feather; | ||
626 | sDelta[RY_I] += (cur_delta[RY_I] - sDelta[RY_I]) * time * feather; | ||
627 | |||
628 | switch (dom_axis) | ||
629 | { | ||
630 | case X_I: // move sideways | ||
631 | agentSlide(sDelta[X_I]); | ||
632 | break; | ||
633 | |||
634 | case Z_I: // forward/back | ||
635 | { | ||
636 | agentPush(sDelta[Z_I]); | ||
637 | |||
638 | if (fabs(sDelta[Y_I]) > .1f) | ||
639 | { | ||
640 | agentFly(sDelta[Y_I]); | ||
641 | } | ||
642 | |||
643 | // too many rotations during walking can be confusing, so apply | ||
644 | // the deadzones one more time (quick & dirty), at 50%|30% power | ||
645 | F32 eff_rx = .3f * dead_zone[RX_I]; | ||
646 | F32 eff_ry = .3f * dead_zone[RY_I]; | ||
647 | |||
648 | if (sDelta[RX_I] > 0) | ||
649 | { | ||
650 | eff_rx = llmax(sDelta[RX_I] - eff_rx, 0.f); | ||
651 | } | ||
652 | else | ||
653 | { | ||
654 | eff_rx = llmin(sDelta[RX_I] + eff_rx, 0.f); | ||
655 | } | ||
656 | |||
657 | if (sDelta[RY_I] > 0) | ||
658 | { | ||
659 | eff_ry = llmax(sDelta[RY_I] - eff_ry, 0.f); | ||
660 | } | ||
661 | else | ||
662 | { | ||
663 | eff_ry = llmin(sDelta[RY_I] + eff_ry, 0.f); | ||
664 | } | ||
665 | |||
666 | |||
667 | if (fabs(eff_rx) > 0.f || fabs(eff_ry) > 0.f) | ||
668 | { | ||
669 | if (gAgent.getFlying()) | ||
670 | { | ||
671 | agentRotate(eff_rx, eff_ry); | ||
672 | } | ||
673 | else | ||
674 | { | ||
675 | agentRotate(eff_rx, 2.f * eff_ry); | ||
676 | } | ||
677 | } | ||
678 | break; | ||
679 | } | ||
680 | case Y_I: // up/crouch | ||
681 | agentFly(sDelta[Y_I]); | ||
682 | break; | ||
683 | |||
684 | case RX_I: // pitch | ||
685 | case RY_I: // turn | ||
686 | agentRotate(sDelta[RX_I], sDelta[RY_I]); | ||
687 | break; | ||
688 | // case RZ_I: roll is unused in avatar mode | ||
689 | }// switch | ||
690 | } | ||
691 | |||
692 | // ----------------------------------------------------------------------------- | ||
693 | void LLViewerJoystick::moveFlycam(bool reset) | ||
694 | { | ||
695 | static LLQuaternion sFlycamRotation; | ||
696 | static LLVector3 sFlycamPosition; | ||
697 | static F32 sFlycamZoom; | ||
698 | |||
699 | if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED | ||
700 | || !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickFlycamEnabled")) | ||
701 | { | ||
702 | return; | ||
703 | } | ||
704 | |||
55 | S32 axis[] = | 705 | S32 axis[] = |
56 | { | 706 | { |
57 | gSavedSettings.getS32("FlycamAxis0"), | 707 | gSavedSettings.getS32("JoystickAxis0"), |
58 | gSavedSettings.getS32("FlycamAxis1"), | 708 | gSavedSettings.getS32("JoystickAxis1"), |
59 | gSavedSettings.getS32("FlycamAxis2"), | 709 | gSavedSettings.getS32("JoystickAxis2"), |
60 | gSavedSettings.getS32("FlycamAxis3"), | 710 | gSavedSettings.getS32("JoystickAxis3"), |
61 | gSavedSettings.getS32("FlycamAxis4"), | 711 | gSavedSettings.getS32("JoystickAxis4"), |
62 | gSavedSettings.getS32("FlycamAxis5"), | 712 | gSavedSettings.getS32("JoystickAxis5"), |
63 | gSavedSettings.getS32("FlycamAxis6") | 713 | gSavedSettings.getS32("JoystickAxis6") |
64 | }; | 714 | }; |
65 | 715 | ||
716 | bool in_build_mode = LLToolMgr::getInstance()->inBuildMode(); | ||
717 | if (reset || mResetFlag) | ||
718 | { | ||
719 | sFlycamPosition = LLViewerCamera::getInstance()->getOrigin(); | ||
720 | sFlycamRotation = LLViewerCamera::getInstance()->getQuaternion(); | ||
721 | sFlycamZoom = LLViewerCamera::getInstance()->getView(); | ||
722 | |||
723 | resetDeltas(axis, in_build_mode); | ||
724 | |||
725 | return; | ||
726 | } | ||
727 | |||
66 | F32 axis_scale[] = | 728 | F32 axis_scale[] = |
67 | { | 729 | { |
68 | gSavedSettings.getF32("FlycamAxisScale0"), | 730 | gSavedSettings.getF32("FlycamAxisScale0"), |
@@ -85,33 +747,37 @@ void LLViewerJoystick::updateCamera(BOOL reset) | |||
85 | gSavedSettings.getF32("FlycamAxisDeadZone6") | 747 | gSavedSettings.getF32("FlycamAxisDeadZone6") |
86 | }; | 748 | }; |
87 | 749 | ||
88 | if (reset) | 750 | F32 time = gFrameIntervalSeconds; |
89 | { | ||
90 | sFlycamPosition = gCamera->getOrigin(); | ||
91 | sFlycamRotation = gCamera->getQuaternion(); | ||
92 | sFlycamZoom = gCamera->getView(); | ||
93 | 751 | ||
94 | for (U32 i = 0; i < 7; i++) | 752 | // avoid making ridicously big movements if there's a big drop in fps |
95 | { | 753 | if (time > .2f) |
96 | last_delta[i] = -window->getJoystickAxis(axis[i]); | 754 | { |
97 | delta[i] = 0.f; | 755 | time = .2f; |
98 | } | ||
99 | return; | ||
100 | } | 756 | } |
101 | 757 | ||
102 | F32 cur_delta[7]; | 758 | F32 cur_delta[7]; |
103 | F32 feather = gSavedSettings.getF32("FlycamFeathering"); | 759 | F32 feather = gSavedSettings.getF32("FlycamFeathering"); |
104 | BOOL absolute = gSavedSettings.getBOOL("FlycamAbsolute"); | 760 | bool absolute = gSavedSettings.getBOOL("Cursor3D"); |
105 | 761 | ||
106 | for (U32 i = 0; i < 7; i++) | 762 | for (U32 i = 0; i < 7; i++) |
107 | { | 763 | { |
108 | cur_delta[i] = -window->getJoystickAxis(axis[i]); | 764 | cur_delta[i] = -getJoystickAxis(axis[i]); |
765 | |||
766 | // we need smaller camera movements in build mode | ||
767 | if (in_build_mode) | ||
768 | { | ||
769 | if (i == X_I || i == Y_I || i == Z_I) | ||
770 | { | ||
771 | cur_delta[i] /= BUILDMODE_FLYCAM_T_SCALE; | ||
772 | } | ||
773 | } | ||
774 | |||
109 | F32 tmp = cur_delta[i]; | 775 | F32 tmp = cur_delta[i]; |
110 | if (absolute) | 776 | if (absolute) |
111 | { | 777 | { |
112 | cur_delta[i] = cur_delta[i] - last_delta[i]; | 778 | cur_delta[i] = cur_delta[i] - sLastDelta[i]; |
113 | } | 779 | } |
114 | last_delta[i] = tmp; | 780 | sLastDelta[i] = tmp; |
115 | 781 | ||
116 | if (cur_delta[i] > 0) | 782 | if (cur_delta[i] > 0) |
117 | { | 783 | { |
@@ -128,18 +794,15 @@ void LLViewerJoystick::updateCamera(BOOL reset) | |||
128 | cur_delta[i] *= time; | 794 | cur_delta[i] *= time; |
129 | } | 795 | } |
130 | 796 | ||
131 | delta[i] = delta[i] + (cur_delta[i]-delta[i])*time*feather; | 797 | sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather; |
132 | } | 798 | } |
133 | 799 | ||
134 | sFlycamPosition += LLVector3(delta) * sFlycamRotation; | 800 | sFlycamPosition += LLVector3(sDelta) * sFlycamRotation; |
135 | 801 | ||
136 | LLMatrix3 rot_mat(delta[3], | 802 | LLMatrix3 rot_mat(sDelta[3], sDelta[4], sDelta[5]); |
137 | delta[4], | ||
138 | delta[5]); | ||
139 | |||
140 | sFlycamRotation = LLQuaternion(rot_mat)*sFlycamRotation; | 803 | sFlycamRotation = LLQuaternion(rot_mat)*sFlycamRotation; |
141 | 804 | ||
142 | if (gSavedSettings.getBOOL("FlycamAutoLeveling")) | 805 | if (gSavedSettings.getBOOL("AutoLeveling")) |
143 | { | 806 | { |
144 | LLMatrix3 level(sFlycamRotation); | 807 | LLMatrix3 level(sFlycamRotation); |
145 | 808 | ||
@@ -153,123 +816,185 @@ void LLViewerJoystick::updateCamera(BOOL reset) | |||
153 | level.setRows(x,y,z); | 816 | level.setRows(x,y,z); |
154 | level.orthogonalize(); | 817 | level.orthogonalize(); |
155 | 818 | ||
156 | LLQuaternion quat = LLQuaternion(level); | 819 | LLQuaternion quat(level); |
157 | sFlycamRotation = nlerp(llmin(feather*time,1.f), sFlycamRotation, quat); | 820 | sFlycamRotation = nlerp(llmin(feather*time,1.f), sFlycamRotation, quat); |
158 | } | 821 | } |
159 | 822 | ||
160 | if (gSavedSettings.getBOOL("FlycamZoomDirect")) | 823 | if (gSavedSettings.getBOOL("ZoomDirect")) |
161 | { | 824 | { |
162 | sFlycamZoom = last_delta[6]*axis_scale[6]+dead_zone[6]; | 825 | sFlycamZoom = sLastDelta[6]*axis_scale[6]+dead_zone[6]; |
163 | } | 826 | } |
164 | else | 827 | else |
165 | { | 828 | { |
166 | sFlycamZoom += delta[6]; | 829 | sFlycamZoom += sDelta[6]; |
167 | } | 830 | } |
168 | 831 | ||
169 | LLMatrix3 mat(sFlycamRotation); | 832 | LLMatrix3 mat(sFlycamRotation); |
170 | 833 | ||
171 | gCamera->setView(sFlycamZoom); | 834 | LLViewerCamera::getInstance()->setView(sFlycamZoom); |
172 | gCamera->setOrigin(sFlycamPosition); | 835 | LLViewerCamera::getInstance()->setOrigin(sFlycamPosition); |
173 | gCamera->mXAxis = LLVector3(mat.mMatrix[0]); | 836 | LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]); |
174 | gCamera->mYAxis = LLVector3(mat.mMatrix[1]); | 837 | LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]); |
175 | gCamera->mZAxis = LLVector3(mat.mMatrix[2]); | 838 | LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]); |
176 | } | 839 | } |
177 | 840 | ||
841 | // ----------------------------------------------------------------------------- | ||
842 | bool LLViewerJoystick::toggleFlycam() | ||
843 | { | ||
844 | if (!gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickFlycamEnabled")) | ||
845 | { | ||
846 | return false; | ||
847 | } | ||
848 | mOverrideCamera = !mOverrideCamera; | ||
849 | if (mOverrideCamera) | ||
850 | { | ||
851 | moveFlycam(true); | ||
852 | } | ||
853 | else if (!LLToolMgr::getInstance()->inBuildMode()) | ||
854 | { | ||
855 | moveAvatar(true); | ||
856 | } | ||
857 | else | ||
858 | { | ||
859 | // we are in build mode, exiting from the flycam mode: since we are | ||
860 | // going to keep the flycam POV for the main camera until the avatar | ||
861 | // moves, we need to track this situation. | ||
862 | setCameraNeedsUpdate(false); | ||
863 | setNeedsReset(true); | ||
864 | } | ||
865 | return true; | ||
866 | } | ||
178 | 867 | ||
179 | void LLViewerJoystick::scanJoystick() | 868 | void LLViewerJoystick::scanJoystick() |
180 | { | 869 | { |
181 | if (!sOverrideCamera) | 870 | if (mDriverState != JDS_INITIALIZED || !gSavedSettings.getBOOL("JoystickEnabled")) |
182 | { | 871 | { |
183 | static U32 joystick_state = 0; | 872 | return; |
184 | static U32 button_state = 0; | 873 | } |
185 | 874 | ||
186 | F32 xval = gViewerWindow->getWindow()->getJoystickAxis(0); | 875 | #if LL_WINDOWS |
187 | F32 yval = gViewerWindow->getWindow()->getJoystickAxis(1); | 876 | // On windows, the flycam is updated syncronously with a timer, so there is |
877 | // no need to update the status of the joystick here. | ||
878 | if (!mOverrideCamera) | ||
879 | #endif | ||
880 | updateStatus(); | ||
188 | 881 | ||
189 | if (xval <= -0.5f) | 882 | static long toggle_flycam = 0; |
190 | { | ||
191 | if (!(joystick_state & 0x1)) | ||
192 | { | ||
193 | gKeyboard->handleTranslatedKeyDown(KEY_PAD_LEFT, 0); | ||
194 | joystick_state |= 0x1; | ||
195 | } | ||
196 | } | ||
197 | else | ||
198 | { | ||
199 | if (joystick_state & 0x1) | ||
200 | { | ||
201 | gKeyboard->handleTranslatedKeyUp(KEY_PAD_LEFT, 0); | ||
202 | joystick_state &= ~0x1; | ||
203 | } | ||
204 | } | ||
205 | if (xval >= 0.5f) | ||
206 | { | ||
207 | if (!(joystick_state & 0x2)) | ||
208 | { | ||
209 | gKeyboard->handleTranslatedKeyDown(KEY_PAD_RIGHT, 0); | ||
210 | joystick_state |= 0x2; | ||
211 | } | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | if (joystick_state & 0x2) | ||
216 | { | ||
217 | gKeyboard->handleTranslatedKeyUp(KEY_PAD_RIGHT, 0); | ||
218 | joystick_state &= ~0x2; | ||
219 | } | ||
220 | } | ||
221 | if (yval <= -0.5f) | ||
222 | { | ||
223 | if (!(joystick_state & 0x4)) | ||
224 | { | ||
225 | gKeyboard->handleTranslatedKeyDown(KEY_PAD_UP, 0); | ||
226 | joystick_state |= 0x4; | ||
227 | } | ||
228 | } | ||
229 | else | ||
230 | { | ||
231 | if (joystick_state & 0x4) | ||
232 | { | ||
233 | gKeyboard->handleTranslatedKeyUp(KEY_PAD_UP, 0); | ||
234 | joystick_state &= ~0x4; | ||
235 | } | ||
236 | } | ||
237 | if (yval >= 0.5f) | ||
238 | { | ||
239 | if (!(joystick_state & 0x8)) | ||
240 | { | ||
241 | gKeyboard->handleTranslatedKeyDown(KEY_PAD_DOWN, 0); | ||
242 | joystick_state |= 0x8; | ||
243 | } | ||
244 | } | ||
245 | else | ||
246 | { | ||
247 | if (joystick_state & 0x8) | ||
248 | { | ||
249 | gKeyboard->handleTranslatedKeyUp(KEY_PAD_DOWN, 0); | ||
250 | joystick_state &= ~0x8; | ||
251 | } | ||
252 | } | ||
253 | 883 | ||
254 | for( int i = 0; i < 15; i++ ) | 884 | if (mBtn[0] == 1) |
885 | { | ||
886 | if (mBtn[0] != toggle_flycam) | ||
255 | { | 887 | { |
256 | if ( gViewerWindow->getWindow()->getJoystickButton(i) & 0x80 ) | 888 | toggle_flycam = toggleFlycam() ? 1 : 0; |
257 | { | ||
258 | if (!(button_state & (1<<i))) | ||
259 | { | ||
260 | gKeyboard->handleTranslatedKeyDown(KEY_BUTTON1+i, 0); | ||
261 | button_state |= (1<<i); | ||
262 | } | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | if (button_state & (1<<i)) | ||
267 | { | ||
268 | gKeyboard->handleTranslatedKeyUp(KEY_BUTTON1+i, 0); | ||
269 | button_state &= ~(1<<i); | ||
270 | } | ||
271 | } | ||
272 | } | 889 | } |
273 | } | 890 | } |
891 | else | ||
892 | { | ||
893 | toggle_flycam = 0; | ||
894 | } | ||
895 | |||
896 | if (!mOverrideCamera && !LLToolMgr::getInstance()->inBuildMode()) | ||
897 | { | ||
898 | moveAvatar(); | ||
899 | } | ||
900 | } | ||
901 | |||
902 | // ----------------------------------------------------------------------------- | ||
903 | std::string LLViewerJoystick::getDescription() | ||
904 | { | ||
905 | std::string res; | ||
906 | #if LIB_NDOF | ||
907 | if (mDriverState == JDS_INITIALIZED && mNdofDev) | ||
908 | { | ||
909 | res = ll_safe_string(mNdofDev->product); | ||
910 | } | ||
911 | #endif | ||
912 | return res; | ||
913 | } | ||
914 | |||
915 | bool LLViewerJoystick::isLikeSpaceNavigator() const | ||
916 | { | ||
917 | #if LIB_NDOF | ||
918 | return (isJoystickInitialized() | ||
919 | && (strncmp(mNdofDev->product, "SpaceNavigator", 14) == 0 | ||
920 | || strncmp(mNdofDev->product, "SpaceExplorer", 13) == 0 | ||
921 | || strncmp(mNdofDev->product, "SpaceTraveler", 13) == 0 | ||
922 | || strncmp(mNdofDev->product, "SpacePilot", 10) == 0)); | ||
923 | #else | ||
924 | return false; | ||
925 | #endif | ||
274 | } | 926 | } |
275 | 927 | ||
928 | // ----------------------------------------------------------------------------- | ||
929 | void LLViewerJoystick::setSNDefaults() | ||
930 | { | ||
931 | #if LL_DARWIN | ||
932 | #define kPlatformScale 20.f | ||
933 | #else | ||
934 | #define kPlatformScale 1.f | ||
935 | #endif | ||
936 | |||
937 | //gViewerWindow->alertXml("CacheWillClear"); | ||
938 | llinfos << "restoring SpaceNavigator defaults..." << llendl; | ||
939 | |||
940 | gSavedSettings.setS32("JoystickAxis0", 1); // z (at) | ||
941 | gSavedSettings.setS32("JoystickAxis1", 0); // x (slide) | ||
942 | gSavedSettings.setS32("JoystickAxis2", 2); // y (up) | ||
943 | gSavedSettings.setS32("JoystickAxis3", 4); // pitch | ||
944 | gSavedSettings.setS32("JoystickAxis4", 3); // roll | ||
945 | gSavedSettings.setS32("JoystickAxis5", 5); // yaw | ||
946 | gSavedSettings.setS32("JoystickAxis6", -1); | ||
947 | |||
948 | #if LL_DARWIN | ||
949 | // The SpaceNavigator doesn't act as a 3D cursor on OS X. | ||
950 | gSavedSettings.setBOOL("Cursor3D", false); | ||
951 | #else | ||
952 | gSavedSettings.setBOOL("Cursor3D", true); | ||
953 | #endif | ||
954 | gSavedSettings.setBOOL("AutoLeveling", true); | ||
955 | gSavedSettings.setBOOL("ZoomDirect", false); | ||
956 | |||
957 | gSavedSettings.setF32("AvatarAxisScale0", 1.f); | ||
958 | gSavedSettings.setF32("AvatarAxisScale1", 1.f); | ||
959 | gSavedSettings.setF32("AvatarAxisScale2", 1.f); | ||
960 | gSavedSettings.setF32("AvatarAxisScale4", .1f * kPlatformScale); | ||
961 | gSavedSettings.setF32("AvatarAxisScale5", .1f * kPlatformScale); | ||
962 | gSavedSettings.setF32("AvatarAxisScale3", 0.f * kPlatformScale); | ||
963 | gSavedSettings.setF32("BuildAxisScale1", .3f * kPlatformScale); | ||
964 | gSavedSettings.setF32("BuildAxisScale2", .3f * kPlatformScale); | ||
965 | gSavedSettings.setF32("BuildAxisScale0", .3f * kPlatformScale); | ||
966 | gSavedSettings.setF32("BuildAxisScale4", .3f * kPlatformScale); | ||
967 | gSavedSettings.setF32("BuildAxisScale5", .3f * kPlatformScale); | ||
968 | gSavedSettings.setF32("BuildAxisScale3", .3f * kPlatformScale); | ||
969 | gSavedSettings.setF32("FlycamAxisScale1", 2.f * kPlatformScale); | ||
970 | gSavedSettings.setF32("FlycamAxisScale2", 2.f * kPlatformScale); | ||
971 | gSavedSettings.setF32("FlycamAxisScale0", 2.1f * kPlatformScale); | ||
972 | gSavedSettings.setF32("FlycamAxisScale4", .1f * kPlatformScale); | ||
973 | gSavedSettings.setF32("FlycamAxisScale5", .15f * kPlatformScale); | ||
974 | gSavedSettings.setF32("FlycamAxisScale3", 0.f * kPlatformScale); | ||
975 | gSavedSettings.setF32("FlycamAxisScale6", 0.f * kPlatformScale); | ||
976 | |||
977 | gSavedSettings.setF32("AvatarAxisDeadZone0", .1f); | ||
978 | gSavedSettings.setF32("AvatarAxisDeadZone1", .1f); | ||
979 | gSavedSettings.setF32("AvatarAxisDeadZone2", .1f); | ||
980 | gSavedSettings.setF32("AvatarAxisDeadZone3", 1.f); | ||
981 | gSavedSettings.setF32("AvatarAxisDeadZone4", .02f); | ||
982 | gSavedSettings.setF32("AvatarAxisDeadZone5", .01f); | ||
983 | gSavedSettings.setF32("BuildAxisDeadZone0", .01f); | ||
984 | gSavedSettings.setF32("BuildAxisDeadZone1", .01f); | ||
985 | gSavedSettings.setF32("BuildAxisDeadZone2", .01f); | ||
986 | gSavedSettings.setF32("BuildAxisDeadZone3", .01f); | ||
987 | gSavedSettings.setF32("BuildAxisDeadZone4", .01f); | ||
988 | gSavedSettings.setF32("BuildAxisDeadZone5", .01f); | ||
989 | gSavedSettings.setF32("FlycamAxisDeadZone0", .01f); | ||
990 | gSavedSettings.setF32("FlycamAxisDeadZone1", .01f); | ||
991 | gSavedSettings.setF32("FlycamAxisDeadZone2", .01f); | ||
992 | gSavedSettings.setF32("FlycamAxisDeadZone3", .01f); | ||
993 | gSavedSettings.setF32("FlycamAxisDeadZone4", .01f); | ||
994 | gSavedSettings.setF32("FlycamAxisDeadZone5", .01f); | ||
995 | gSavedSettings.setF32("FlycamAxisDeadZone6", 1.f); | ||
996 | |||
997 | gSavedSettings.setF32("AvatarFeathering", 6.f); | ||
998 | gSavedSettings.setF32("BuildFeathering", 12.f); | ||
999 | gSavedSettings.setF32("FlycamFeathering", 5.f); | ||
1000 | } | ||