mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-14 02:06:30 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into amc
This commit is contained in:
commit
a45b91c4be
55 changed files with 1480 additions and 290 deletions
4
cmake/externals/LibOVR/CMakeLists.txt
vendored
4
cmake/externals/LibOVR/CMakeLists.txt
vendored
|
@ -17,8 +17,8 @@ if (WIN32)
|
|||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://public.highfidelity.com/dependencies/ovr_sdk_win_1.26.0_public.zip
|
||||
URL_MD5 06804ff9727b910dcd04a37c800053b5
|
||||
URL https://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.35.0.zip
|
||||
URL_MD5 1e3e8b2101387af07ff9c841d0ea285e
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LibOVRCMakeLists.txt" <SOURCE_DIR>/CMakeLists.txt
|
||||
LOG_DOWNLOAD 1
|
||||
|
|
|
@ -53,10 +53,5 @@ macro(add_crashpad)
|
|||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$<TARGET_FILE_DIR:${TARGET_NAME}>/"
|
||||
)
|
||||
install(
|
||||
PROGRAMS ${CRASHPAD_HANDLER_EXE_PATH}
|
||||
DESTINATION ${INTERFACE_INSTALL_DIR}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
endif ()
|
||||
endmacro()
|
||||
|
|
|
@ -678,12 +678,9 @@ $(document).ready(function(){
|
|||
var errorEl = createDomainLoadingError("There was an error retrieving your places.");
|
||||
$("#" + Settings.PLACES_TABLE_ID).after(errorEl);
|
||||
|
||||
// do we have a domain ID?
|
||||
if (!domainIDIsSet()) {
|
||||
// we don't have a domain ID - add a button to offer the user a chance to get a temporary one
|
||||
var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name');
|
||||
$('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton);
|
||||
}
|
||||
var temporaryPlaceButton = dynamicButton(Settings.GET_TEMPORARY_NAME_BTN_ID, 'Get a temporary place name');
|
||||
temporaryPlaceButton.hide();
|
||||
$('#' + Settings.PLACES_TABLE_ID).after(temporaryPlaceButton);
|
||||
if (accessTokenIsSet()) {
|
||||
appendAddButtonToPlacesTable();
|
||||
}
|
||||
|
@ -774,8 +771,9 @@ $(document).ready(function(){
|
|||
|
||||
// check if we have owner_places (for a real domain) or a name (for a temporary domain)
|
||||
if (data.status == "success") {
|
||||
$('#' + Settings.GET_TEMPORARY_NAME_BTN_ID).hide();
|
||||
$('.domain-loading-hide').show();
|
||||
if (data.domain.owner_places) {
|
||||
if (data.domain.owner_places && data.domain.owner_places.length > 0) {
|
||||
// add a table row for each of these names
|
||||
_.each(data.domain.owner_places, function(place){
|
||||
$('#' + Settings.PLACES_TABLE_ID + " tbody").append(placeTableRowForPlaceObject(place));
|
||||
|
@ -783,8 +781,9 @@ $(document).ready(function(){
|
|||
} else if (data.domain.name) {
|
||||
// add a table row for this temporary domain name
|
||||
$('#' + Settings.PLACES_TABLE_ID + " tbody").append(placeTableRow(data.domain.name, '/', true));
|
||||
} else {
|
||||
$('#' + Settings.GET_TEMPORARY_NAME_BTN_ID).show();
|
||||
}
|
||||
|
||||
// Update label
|
||||
if (showOrHideLabel()) {
|
||||
var label = data.domain.label;
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
|
||||
{ "from": "OculusTouch.LY", "to": "Standard.LY",
|
||||
"filters": [
|
||||
{ "type": "deadZone", "min": 0.7 },
|
||||
{ "type": "deadZone", "min": 0.15 },
|
||||
"invert"
|
||||
]
|
||||
},
|
||||
{ "from": "OculusTouch.LX", "filters": { "type": "deadZone", "min": 0.7 }, "to": "Standard.LX" },
|
||||
{ "from": "OculusTouch.LX", "filters": { "type": "deadZone", "min": 0.15 }, "to": "Standard.LX" },
|
||||
{ "from": "OculusTouch.LT", "to": "Standard.LTClick",
|
||||
"peek": true,
|
||||
"filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ]
|
||||
|
@ -29,11 +29,11 @@
|
|||
|
||||
{ "from": "OculusTouch.RY", "to": "Standard.RY",
|
||||
"filters": [
|
||||
{ "type": "deadZone", "min": 0.7 },
|
||||
{ "type": "deadZone", "min": 0.15 },
|
||||
"invert"
|
||||
]
|
||||
},
|
||||
{ "from": "OculusTouch.RX", "filters": { "type": "deadZone", "min": 0.7 }, "to": "Standard.RX" },
|
||||
{ "from": "OculusTouch.RX", "filters": { "type": "deadZone", "min": 0.15 }, "to": "Standard.RX" },
|
||||
{ "from": "OculusTouch.RT", "to": "Standard.RTClick",
|
||||
"peek": true,
|
||||
"filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ]
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
{
|
||||
"name": "Standard to Action",
|
||||
"channels": [
|
||||
{ "from": "Standard.LY", "to": "Actions.TranslateZ" },
|
||||
{ "from": "Standard.LY",
|
||||
"when": ["Application.RightHandDominant", "!Standard.RY"],
|
||||
"to": "Actions.TranslateZ"
|
||||
},
|
||||
|
||||
{ "from": "Standard.LX",
|
||||
"when": [
|
||||
"Application.InHMD", "!Application.AdvancedMovement",
|
||||
"Application.InHMD", "!Application.AdvancedMovement", "Application.RightHandDominant",
|
||||
"Application.SnapTurn", "!Standard.RX"
|
||||
],
|
||||
"to": "Actions.StepYaw",
|
||||
|
@ -18,14 +21,14 @@
|
|||
]
|
||||
},
|
||||
{ "from": "Standard.LX", "to": "Actions.TranslateX",
|
||||
"when": [ "Application.AdvancedMovement" ]
|
||||
"when": [ "Application.AdvancedMovement", "Application.StrafeEnabled", "Application.RightHandDominant" ]
|
||||
},
|
||||
{ "from": "Standard.LX", "to": "Actions.Yaw",
|
||||
"when": [ "!Application.AdvancedMovement", "!Application.SnapTurn" ]
|
||||
"when": [ "!Application.AdvancedMovement", "!Application.SnapTurn", "Application.RightHandDominant" ]
|
||||
},
|
||||
|
||||
{ "from": "Standard.RX",
|
||||
"when": [ "Application.SnapTurn" ],
|
||||
"when": [ "Application.SnapTurn", "Application.RightHandDominant" ],
|
||||
"to": "Actions.StepYaw",
|
||||
"filters":
|
||||
[
|
||||
|
@ -36,20 +39,69 @@
|
|||
]
|
||||
},
|
||||
{ "from": "Standard.RX", "to": "Actions.Yaw",
|
||||
"when": [ "!Application.SnapTurn" ]
|
||||
"when": [ "!Application.SnapTurn", "Application.RightHandDominant" ]
|
||||
},
|
||||
|
||||
{ "from": "Standard.LeftSecondaryThumb",
|
||||
"when": [ "Application.Grounded", "Application.LeftHandDominant" ],
|
||||
"to": "Actions.Up"
|
||||
},
|
||||
|
||||
{ "from": "Standard.LeftSecondaryThumb",
|
||||
"when": "Application.LeftHandDominant",
|
||||
"to": "Actions.Up"
|
||||
},
|
||||
|
||||
{ "from": "Standard.RY",
|
||||
"when": "Application.Grounded",
|
||||
"to": "Actions.Up",
|
||||
"when": ["Application.LeftHandDominant", "!Standard.LY"],
|
||||
"to": "Actions.TranslateZ"
|
||||
},
|
||||
|
||||
{ "from": "Standard.RX",
|
||||
"when": [
|
||||
"Application.InHMD", "!Application.AdvancedMovement", "Application.LeftHandDominant",
|
||||
"Application.SnapTurn", "!Standard.RX"
|
||||
],
|
||||
"to": "Actions.StepYaw",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "deadZone", "min": 0.6 },
|
||||
"invert"
|
||||
{ "type": "deadZone", "min": 0.15 },
|
||||
"constrainToInteger",
|
||||
{ "type": "pulse", "interval": 0.25 },
|
||||
{ "type": "scale", "scale": 22.5 }
|
||||
]
|
||||
},
|
||||
{ "from": "Standard.RX", "to": "Actions.TranslateX",
|
||||
"when": [ "Application.AdvancedMovement", "Application.StrafeEnabled", "Application.LeftHandDominant" ]
|
||||
},
|
||||
{ "from": "Standard.RX", "to": "Actions.Yaw",
|
||||
"when": [ "!Application.AdvancedMovement", "!Application.SnapTurn", "Application.LeftHandDominant" ]
|
||||
},
|
||||
|
||||
{ "from": "Standard.RY", "to": "Actions.Up", "filters": "invert"},
|
||||
{ "from": "Standard.LX",
|
||||
"when": [ "Application.SnapTurn", "Application.LeftHandDominant" ],
|
||||
"to": "Actions.StepYaw",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "deadZone", "min": 0.15 },
|
||||
"constrainToInteger",
|
||||
{ "type": "pulse", "interval": 0.25 },
|
||||
{ "type": "scale", "scale": 22.5 }
|
||||
]
|
||||
},
|
||||
{ "from": "Standard.LX", "to": "Actions.Yaw",
|
||||
"when": [ "!Application.SnapTurn", "Application.LeftHandDominant" ]
|
||||
},
|
||||
|
||||
{ "from": "Standard.RightSecondaryThumb",
|
||||
"when": [ "Application.Grounded", "Application.RightHandDominant" ],
|
||||
"to": "Actions.Up"
|
||||
},
|
||||
|
||||
{ "from": "Standard.RightSecondaryThumb",
|
||||
"when": "Application.RightHandDominant",
|
||||
"to": "Actions.Up"
|
||||
},
|
||||
|
||||
{ "from": "Standard.Back", "to": "Actions.CycleCamera" },
|
||||
{ "from": "Standard.Start", "to": "Actions.ContextMenu" },
|
||||
|
@ -128,4 +180,4 @@
|
|||
{ "from": "Standard.TrackedObject14", "to" : "Actions.TrackedObject14" },
|
||||
{ "from": "Standard.TrackedObject15", "to" : "Actions.TrackedObject15" }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
"filters": [ { "type": "hysteresis", "min": 0.7, "max": 0.75 } ]
|
||||
},
|
||||
|
||||
{ "from": "Vive.LY", "when": "Vive.LSY", "filters": ["invert"], "to": "Standard.LY" },
|
||||
{ "from": "Vive.LX", "when": "Vive.LSX", "to": "Standard.LX" },
|
||||
{ "from": "Vive.LY", "when": "Vive.LS", "filters": [ { "type": "deadZone", "min": 0.15 }, "invert" ], "to": "Standard.LY" },
|
||||
{ "from": "Vive.LX", "when": ["Vive.LS", "Application.RightHandDominant"], "filters": { "type": "deadZone", "min": 0.15 }, "to": "Standard.LX" },
|
||||
{ "from": "Vive.LX", "when": ["Vive.LS", "Vive.LSX", "!Vive.LSY", "Application.LeftHandDominant"], "filters": { "type": "deadZone", "min": 0.15 }, "to": "Standard.LX" },
|
||||
{
|
||||
"from": "Vive.LT", "to": "Standard.LT",
|
||||
"filters": [
|
||||
|
@ -28,8 +29,9 @@
|
|||
},
|
||||
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
|
||||
|
||||
{ "from": "Vive.RY", "when": "Vive.RSY", "filters": ["invert"], "to": "Standard.RY" },
|
||||
{ "from": "Vive.RX", "when": "Vive.RSX", "to": "Standard.RX" },
|
||||
{ "from": "Vive.RY", "when": "Vive.RS", "filters": [ { "type": "deadZone", "min": 0.15 }, "invert" ], "to": "Standard.RY" },
|
||||
{ "from": "Vive.RX", "when": ["Vive.RS", "Application.LeftHandDominant"], "filters": { "type": "deadZone", "min": 0.15 }, "to": "Standard.RX" },
|
||||
{ "from": "Vive.RX", "when": ["Vive.RS", "Vive.RSX", "!Vive.RSY", "Application.RightHandDominant"], "filters": { "type": "deadZone", "min": 0.15 }, "to": "Standard.RX" },
|
||||
{
|
||||
"from": "Vive.RT", "to": "Standard.RT",
|
||||
"filters": [
|
||||
|
|
|
@ -680,6 +680,8 @@ private:
|
|||
* <tr><td><code>InHMD</code></td><td>number</td><td>number</td><td>The user is in HMD mode.</td></tr>
|
||||
* <tr><td><code>AdvancedMovement</code></td><td>number</td><td>number</td><td>Advanced movement controls are enabled.
|
||||
* </td></tr>
|
||||
* <tr><td><code>LeftHandDominant</code></td><td>number</td><td>number</td><td>Dominant hand set to left.</td></tr>
|
||||
* <tr><td><code>RightHandDominant</code></td><td>number</td><td>number</td><td>Dominant hand set to right.</td></tr>
|
||||
* <tr><td><code>SnapTurn</code></td><td>number</td><td>number</td><td>Snap turn is enabled.</td></tr>
|
||||
* <tr><td><code>Grounded</code></td><td>number</td><td>number</td><td>The user's avatar is on the ground.</td></tr>
|
||||
* <tr><td><code>NavigationFocused</code></td><td>number</td><td>number</td><td><em>Not used.</em></td></tr>
|
||||
|
@ -701,6 +703,9 @@ static const QString STATE_NAV_FOCUSED = "NavigationFocused";
|
|||
static const QString STATE_PLATFORM_WINDOWS = "PlatformWindows";
|
||||
static const QString STATE_PLATFORM_MAC = "PlatformMac";
|
||||
static const QString STATE_PLATFORM_ANDROID = "PlatformAndroid";
|
||||
static const QString STATE_LEFT_HAND_DOMINANT = "LeftHandDominant";
|
||||
static const QString STATE_RIGHT_HAND_DOMINANT = "RightHandDominant";
|
||||
static const QString STATE_STRAFE_ENABLED = "StrafeEnabled";
|
||||
|
||||
// Statically provided display and input plugins
|
||||
extern DisplayPluginList getDisplayPlugins();
|
||||
|
@ -902,7 +907,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
|||
controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR,
|
||||
STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT,
|
||||
STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED,
|
||||
STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID } });
|
||||
STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } });
|
||||
DependencyManager::set<UserInputMapper>();
|
||||
DependencyManager::set<controller::ScriptingInterface, ControllerScriptingInterface>();
|
||||
DependencyManager::set<InterfaceParentFinder>();
|
||||
|
@ -1740,6 +1745,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_applicationStateDevice->setInputVariant(STATE_ADVANCED_MOVEMENT_CONTROLS, []() -> float {
|
||||
return qApp->getMyAvatar()->useAdvancedMovementControls() ? 1 : 0;
|
||||
});
|
||||
_applicationStateDevice->setInputVariant(STATE_LEFT_HAND_DOMINANT, []() -> float {
|
||||
return qApp->getMyAvatar()->getDominantHand() == "left" ? 1 : 0;
|
||||
});
|
||||
_applicationStateDevice->setInputVariant(STATE_RIGHT_HAND_DOMINANT, []() -> float {
|
||||
return qApp->getMyAvatar()->getDominantHand() == "right" ? 1 : 0;
|
||||
});
|
||||
_applicationStateDevice->setInputVariant(STATE_STRAFE_ENABLED, []() -> float {
|
||||
return qApp->getMyAvatar()->getStrafeEnabled() ? 1 : 0;
|
||||
});
|
||||
|
||||
_applicationStateDevice->setInputVariant(STATE_GROUNDED, []() -> float {
|
||||
return qApp->getMyAvatar()->getCharacterController()->onGround() ? 1 : 0;
|
||||
|
@ -6709,6 +6723,11 @@ void Application::updateRenderArgs(float deltaTime) {
|
|||
// Configure the type of display / stereo
|
||||
appRenderArgs._renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR);
|
||||
}
|
||||
|
||||
appRenderArgs._renderArgs._stencilMode = getActiveDisplayPlugin()->getStencilMaskMode();
|
||||
if (appRenderArgs._renderArgs._stencilMode == StencilMode::MESH) {
|
||||
appRenderArgs._renderArgs._stencilMaskOperator = getActiveDisplayPlugin()->getStencilMaskMeshOperator();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -155,6 +155,7 @@ MyAvatar::MyAvatar(QThread* thread) :
|
|||
_prevShouldDrawHead(true),
|
||||
_audioListenerMode(FROM_HEAD),
|
||||
_dominantHandSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "dominantHand", DOMINANT_RIGHT_HAND),
|
||||
_strafeEnabledSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "strafeEnabled", DEFAULT_STRAFE_ENABLED),
|
||||
_hmdAvatarAlignmentTypeSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "hmdAvatarAlignmentType", DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE),
|
||||
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
|
||||
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
|
||||
|
@ -169,7 +170,16 @@ MyAvatar::MyAvatar(QThread* thread) :
|
|||
_useSnapTurnSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "useSnapTurn", _useSnapTurn),
|
||||
_userHeightSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "userHeight", DEFAULT_AVATAR_HEIGHT),
|
||||
_flyingHMDSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "flyingHMD", _flyingPrefHMD),
|
||||
_movementReferenceSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "movementReference", _movementReference),
|
||||
_avatarEntityCountSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData" << "size", 0),
|
||||
_driveGear1Setting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "driveGear1", _driveGear1),
|
||||
_driveGear2Setting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "driveGear2", _driveGear2),
|
||||
_driveGear3Setting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "driveGear3", _driveGear3),
|
||||
_driveGear4Setting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "driveGear4", _driveGear4),
|
||||
_driveGear5Setting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "driveGear5", _driveGear5),
|
||||
_analogWalkSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "analogWalkSpeed", _analogWalkSpeed.get()),
|
||||
_analogPlusWalkSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "analogPlusWalkSpeed", _analogPlusWalkSpeed.get()),
|
||||
_controlSchemeIndexSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "controlSchemeIndex", _controlSchemeIndex),
|
||||
_userRecenterModelSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "userRecenterModel", USER_RECENTER_MODEL_AUTO)
|
||||
{
|
||||
_clientTraitsHandler.reset(new ClientTraitsHandler(this));
|
||||
|
@ -322,6 +332,14 @@ QString MyAvatar::getDominantHand() const {
|
|||
return _dominantHand.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setStrafeEnabled(bool enabled) {
|
||||
_strafeEnabled.set(enabled);
|
||||
}
|
||||
|
||||
bool MyAvatar::getStrafeEnabled() const {
|
||||
return _strafeEnabled.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setDominantHand(const QString& hand) {
|
||||
if (hand == DOMINANT_LEFT_HAND || hand == DOMINANT_RIGHT_HAND) {
|
||||
bool changed = (hand != _dominantHand.get());
|
||||
|
@ -1256,6 +1274,7 @@ void MyAvatar::resizeAvatarEntitySettingHandles(uint32_t maxIndex) {
|
|||
|
||||
void MyAvatar::saveData() {
|
||||
_dominantHandSetting.set(getDominantHand());
|
||||
_strafeEnabledSetting.set(getStrafeEnabled());
|
||||
_hmdAvatarAlignmentTypeSetting.set(getHmdAvatarAlignmentType());
|
||||
_headPitchSetting.set(getHead()->getBasePitch());
|
||||
_scaleSetting.set(_targetScale);
|
||||
|
@ -1279,6 +1298,15 @@ void MyAvatar::saveData() {
|
|||
_useSnapTurnSetting.set(_useSnapTurn);
|
||||
_userHeightSetting.set(getUserHeight());
|
||||
_flyingHMDSetting.set(getFlyingHMDPref());
|
||||
_movementReferenceSetting.set(getMovementReference());
|
||||
_driveGear1Setting.set(getDriveGear1());
|
||||
_driveGear2Setting.set(getDriveGear2());
|
||||
_driveGear3Setting.set(getDriveGear3());
|
||||
_driveGear4Setting.set(getDriveGear4());
|
||||
_driveGear5Setting.set(getDriveGear5());
|
||||
_analogWalkSpeedSetting.set(getAnalogWalkSpeed());
|
||||
_analogPlusWalkSpeedSetting.set(getAnalogPlusWalkSpeed());
|
||||
_controlSchemeIndexSetting.set(getControlSchemeIndex());
|
||||
_userRecenterModelSetting.set(userRecenterModelToString(getUserRecenterModel()));
|
||||
|
||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||
|
@ -1856,12 +1884,22 @@ void MyAvatar::loadData() {
|
|||
// Flying preferences must be loaded before calling setFlyingEnabled()
|
||||
Setting::Handle<bool> firstRunVal { Settings::firstRun, true };
|
||||
setFlyingHMDPref(firstRunVal.get() ? false : _flyingHMDSetting.get());
|
||||
setMovementReference(firstRunVal.get() ? false : _movementReferenceSetting.get());
|
||||
setDriveGear1(firstRunVal.get() ? DEFAULT_GEAR_1 : _driveGear1Setting.get());
|
||||
setDriveGear2(firstRunVal.get() ? DEFAULT_GEAR_2 : _driveGear2Setting.get());
|
||||
setDriveGear3(firstRunVal.get() ? DEFAULT_GEAR_3 : _driveGear3Setting.get());
|
||||
setDriveGear4(firstRunVal.get() ? DEFAULT_GEAR_4 : _driveGear4Setting.get());
|
||||
setDriveGear5(firstRunVal.get() ? DEFAULT_GEAR_5 : _driveGear5Setting.get());
|
||||
setControlSchemeIndex(firstRunVal.get() ? LocomotionControlsMode::CONTROLS_DEFAULT : _controlSchemeIndexSetting.get());
|
||||
setAnalogWalkSpeed(firstRunVal.get() ? ANALOG_AVATAR_MAX_WALKING_SPEED : _analogWalkSpeedSetting.get());
|
||||
setAnalogPlusWalkSpeed(firstRunVal.get() ? ANALOG_PLUS_AVATAR_MAX_WALKING_SPEED : _analogPlusWalkSpeedSetting.get());
|
||||
setFlyingEnabled(getFlyingEnabled());
|
||||
|
||||
setDisplayName(_displayNameSetting.get());
|
||||
setCollisionSoundURL(_collisionSoundURLSetting.get(QUrl(DEFAULT_AVATAR_COLLISION_SOUND_URL)).toString());
|
||||
setSnapTurn(_useSnapTurnSetting.get());
|
||||
setDominantHand(_dominantHandSetting.get(DOMINANT_RIGHT_HAND).toLower());
|
||||
setStrafeEnabled(_strafeEnabledSetting.get(DEFAULT_STRAFE_ENABLED));
|
||||
setHmdAvatarAlignmentType(_hmdAvatarAlignmentTypeSetting.get(DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE).toLower());
|
||||
setUserHeight(_userHeightSetting.get(DEFAULT_AVATAR_HEIGHT));
|
||||
setTargetScale(_scaleSetting.get());
|
||||
|
@ -2519,6 +2557,12 @@ controller::Pose MyAvatar::getControllerPoseInAvatarFrame(controller::Action act
|
|||
}
|
||||
}
|
||||
|
||||
glm::quat MyAvatar::getOffHandRotation() const {
|
||||
auto hand = (getDominantHand() == DOMINANT_RIGHT_HAND) ? controller::Action::LEFT_HAND : controller::Action::RIGHT_HAND;
|
||||
auto pose = getControllerPoseInAvatarFrame(hand);
|
||||
return pose.rotation;
|
||||
}
|
||||
|
||||
void MyAvatar::updateMotors() {
|
||||
_characterController.clearMotors();
|
||||
glm::quat motorRotation;
|
||||
|
@ -3285,21 +3329,131 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
static float scaleSpeedByDirection(const glm::vec2 velocityDirection, const float forwardSpeed, const float backwardSpeed) {
|
||||
// for the elipse function --> (x^2)/(backwardSpeed*backwardSpeed) + y^2/(forwardSpeed*forwardSpeed) = 1, scale == y^2 when x is 0
|
||||
float fwdScale = forwardSpeed * forwardSpeed;
|
||||
float backScale = backwardSpeed * backwardSpeed;
|
||||
float scaledX = velocityDirection.x * backwardSpeed;
|
||||
float scaledSpeed = forwardSpeed;
|
||||
if (velocityDirection.y < 0.0f) {
|
||||
if (backScale > 0.0f) {
|
||||
float yValue = sqrtf(fwdScale * (1.0f - ((scaledX * scaledX) / backScale)));
|
||||
scaledSpeed = sqrtf((scaledX * scaledX) + (yValue * yValue));
|
||||
float MyAvatar::calculateGearedSpeed(const float driveKey) {
|
||||
float absDriveKey = abs(driveKey);
|
||||
float sign = (driveKey < 0.0f) ? -1.0f : 1.0f;
|
||||
if (absDriveKey > getDriveGear5()) {
|
||||
return sign * 1.0f;
|
||||
}
|
||||
else if (absDriveKey > getDriveGear4()) {
|
||||
return sign * 0.8f;
|
||||
}
|
||||
else if (absDriveKey > getDriveGear3()) {
|
||||
return sign * 0.6f;
|
||||
}
|
||||
else if (absDriveKey > getDriveGear2()) {
|
||||
return sign * 0.4f;
|
||||
}
|
||||
else if (absDriveKey > getDriveGear1()) {
|
||||
return sign * 0.2f;
|
||||
}
|
||||
else {
|
||||
return sign * 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 right) {
|
||||
float stickFullOn = 0.85f;
|
||||
auto zSpeed = getDriveKey(TRANSLATE_Z);
|
||||
auto xSpeed = getDriveKey(TRANSLATE_X);
|
||||
glm::vec3 direction;
|
||||
if (!useAdvancedMovementControls() && qApp->isHMDMode()) {
|
||||
// Walking disabled in settings.
|
||||
return Vectors::ZERO;
|
||||
} else if (qApp->isHMDMode()) {
|
||||
// HMD advanced movement controls.
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
// No acceleration curve for this one, constant speed.
|
||||
if (zSpeed || xSpeed) {
|
||||
direction = (zSpeed * forward) + (xSpeed * right);
|
||||
// Normalize direction.
|
||||
auto length = glm::length(direction);
|
||||
if (length > EPSILON) {
|
||||
direction /= length;
|
||||
}
|
||||
return getSensorToWorldScale() * direction * getSprintSpeed() * _walkSpeedScalar;
|
||||
} else {
|
||||
return Vectors::ZERO;
|
||||
}
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
if (zSpeed || xSpeed) {
|
||||
glm::vec3 scaledForward = getSensorToWorldScale() * calculateGearedSpeed(zSpeed) * _walkSpeedScalar * ((zSpeed >= stickFullOn) ? getSprintSpeed() : getWalkSpeed()) * forward;
|
||||
glm::vec3 scaledRight = getSensorToWorldScale() * calculateGearedSpeed(xSpeed) * _walkSpeedScalar * ((xSpeed > stickFullOn) ? getSprintSpeed() : getWalkSpeed()) * right;
|
||||
direction = scaledForward + scaledRight;
|
||||
return direction;
|
||||
} else {
|
||||
return Vectors::ZERO;
|
||||
}
|
||||
default:
|
||||
qDebug() << "Invalid control scheme index.";
|
||||
return Vectors::ZERO;
|
||||
}
|
||||
} else {
|
||||
scaledSpeed = backwardSpeed;
|
||||
// Desktop mode.
|
||||
direction = (zSpeed * forward) + (xSpeed * right);
|
||||
auto length = glm::length(direction);
|
||||
if (length > EPSILON) {
|
||||
direction /= length;
|
||||
}
|
||||
direction *= getWalkSpeed() * _walkSpeedScalar;
|
||||
return direction;
|
||||
}
|
||||
return scaledSpeed;
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::calculateScaledDirection(){
|
||||
CharacterController::State state = _characterController.getState();
|
||||
|
||||
// compute action input
|
||||
// Determine if we're head or controller relative...
|
||||
glm::vec3 forward, right;
|
||||
|
||||
if (qApp->isHMDMode()) {
|
||||
auto handRotation = getOffHandRotation();
|
||||
glm::vec3 controllerForward(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 controllerRight(0.0f, 0.0f, (getDominantHand() == DOMINANT_RIGHT_HAND ? 1.0f : -1.0f));
|
||||
glm::vec3 transform;
|
||||
switch (getMovementReference()) {
|
||||
case LocomotionRelativeMovementMode::MOVEMENT_HAND_RELATIVE:
|
||||
forward = (handRotation * controllerForward);
|
||||
right = (handRotation * controllerRight);
|
||||
break;
|
||||
case LocomotionRelativeMovementMode::MOVEMENT_HAND_RELATIVE_LEVELED:
|
||||
forward = (handRotation * controllerForward);
|
||||
transform = forward - (glm::dot(forward, Vectors::UNIT_Y) * Vectors::UNIT_Y);
|
||||
if (glm::length(transform) > EPSILON) {
|
||||
forward = glm::normalize(transform);
|
||||
} else {
|
||||
forward = Vectors::ZERO;
|
||||
}
|
||||
right = (handRotation * controllerRight);
|
||||
transform = right - (glm::dot(right, Vectors::UNIT_Y) * Vectors::UNIT_Y);
|
||||
if (glm::length(transform) > EPSILON) {
|
||||
right = glm::normalize(transform);
|
||||
} else {
|
||||
right = Vectors::ZERO;
|
||||
}
|
||||
break;
|
||||
case LocomotionRelativeMovementMode::MOVEMENT_HMD_RELATIVE:
|
||||
default:
|
||||
forward = IDENTITY_FORWARD;
|
||||
right = IDENTITY_RIGHT;
|
||||
}
|
||||
} else {
|
||||
forward = IDENTITY_FORWARD;
|
||||
right = IDENTITY_RIGHT;
|
||||
}
|
||||
|
||||
glm::vec3 direction = scaleMotorSpeed(forward, right);
|
||||
|
||||
if (state == CharacterController::State::Hover ||
|
||||
_characterController.computeCollisionMask() == BULLET_COLLISION_MASK_COLLISIONLESS) {
|
||||
glm::vec3 up = (getDriveKey(TRANSLATE_Y)) * IDENTITY_UP;
|
||||
direction += up;
|
||||
}
|
||||
|
||||
return direction;
|
||||
}
|
||||
|
||||
void MyAvatar::updateActionMotor(float deltaTime) {
|
||||
|
@ -3319,25 +3473,13 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
|
||||
CharacterController::State state = _characterController.getState();
|
||||
|
||||
// compute action input
|
||||
glm::vec3 forward = (getDriveKey(TRANSLATE_Z)) * IDENTITY_FORWARD;
|
||||
glm::vec3 right = (getDriveKey(TRANSLATE_X)) * IDENTITY_RIGHT;
|
||||
|
||||
glm::vec3 direction = forward + right;
|
||||
if (state == CharacterController::State::Hover ||
|
||||
_characterController.computeCollisionMask() == BULLET_COLLISION_MASK_COLLISIONLESS) {
|
||||
glm::vec3 up = (getDriveKey(TRANSLATE_Y)) * IDENTITY_UP;
|
||||
direction += up;
|
||||
}
|
||||
glm::vec3 direction = calculateScaledDirection();
|
||||
|
||||
_wasPushing = _isPushing;
|
||||
float directionLength = glm::length(direction);
|
||||
_isPushing = directionLength > EPSILON;
|
||||
|
||||
// normalize direction
|
||||
if (_isPushing) {
|
||||
direction /= directionLength;
|
||||
} else {
|
||||
if (!_isPushing) {
|
||||
direction = Vectors::ZERO;
|
||||
}
|
||||
|
||||
|
@ -3353,6 +3495,7 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
const float maxBoostSpeed = sensorToWorldScale * MAX_BOOST_SPEED;
|
||||
|
||||
if (_isPushing) {
|
||||
direction /= directionLength;
|
||||
if (motorSpeed < maxBoostSpeed) {
|
||||
// an active action motor should never be slower than this
|
||||
float boostCoefficient = (maxBoostSpeed - motorSpeed) / maxBoostSpeed;
|
||||
|
@ -3363,11 +3506,17 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
}
|
||||
_actionMotorVelocity = motorSpeed * direction;
|
||||
} else {
|
||||
// we're interacting with a floor --> simple horizontal speed and exponential decay
|
||||
const glm::vec2 currentVel = { direction.x, direction.z };
|
||||
float scaledSpeed = scaleSpeedByDirection(currentVel, _walkSpeed.get(), _walkBackwardSpeed.get());
|
||||
// _walkSpeedScalar is a multiplier if we are in sprint mode, otherwise 1.0
|
||||
_actionMotorVelocity = sensorToWorldScale * (scaledSpeed * _walkSpeedScalar) * direction;
|
||||
_actionMotorVelocity = direction;
|
||||
}
|
||||
|
||||
float previousBoomLength = _boomLength;
|
||||
float boomChange = getDriveKey(ZOOM);
|
||||
_boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange;
|
||||
_boomLength = glm::clamp<float>(_boomLength, ZOOM_MIN, ZOOM_MAX);
|
||||
|
||||
// May need to change view if boom length has changed
|
||||
if (previousBoomLength != _boomLength) {
|
||||
qApp->changeViewAsNeeded(_boomLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3880,6 +4029,136 @@ void MyAvatar::setFlyingHMDPref(bool enabled) {
|
|||
_flyingPrefHMD = enabled;
|
||||
}
|
||||
|
||||
void MyAvatar::setMovementReference(int enabled) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setMovementReference", Q_ARG(bool, enabled));
|
||||
return;
|
||||
}
|
||||
_movementReference = enabled;
|
||||
}
|
||||
|
||||
int MyAvatar::getMovementReference() {
|
||||
return _movementReference;
|
||||
}
|
||||
|
||||
void MyAvatar::setControlSchemeIndex(int index){
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setControlSchemeIndex", Q_ARG(int, index));
|
||||
return;
|
||||
}
|
||||
// Need to add checks for valid indices.
|
||||
_controlSchemeIndex = index;
|
||||
}
|
||||
|
||||
int MyAvatar::getControlSchemeIndex() {
|
||||
return _controlSchemeIndex;
|
||||
}
|
||||
|
||||
void MyAvatar::setDriveGear1(float shiftPoint) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setDriveGear1", Q_ARG(float, shiftPoint));
|
||||
return;
|
||||
}
|
||||
if (shiftPoint > 1.0f || shiftPoint < 0.0f) return;
|
||||
_driveGear1 = (shiftPoint < _driveGear2) ? shiftPoint : _driveGear1;
|
||||
}
|
||||
|
||||
float MyAvatar::getDriveGear1() {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return ANALOG_AVATAR_GEAR_1;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _driveGear1;
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setDriveGear2(float shiftPoint) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setDriveGear2", Q_ARG(float, shiftPoint));
|
||||
return;
|
||||
}
|
||||
if (shiftPoint > 1.0f || shiftPoint < 0.0f) return;
|
||||
_driveGear2 = (shiftPoint < _driveGear3 && shiftPoint >= _driveGear1) ? shiftPoint : _driveGear2;
|
||||
}
|
||||
|
||||
float MyAvatar::getDriveGear2() {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return ANALOG_AVATAR_GEAR_2;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _driveGear2;
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setDriveGear3(float shiftPoint) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setDriveGear3", Q_ARG(float, shiftPoint));
|
||||
return;
|
||||
}
|
||||
if (shiftPoint > 1.0f || shiftPoint < 0.0f) return;
|
||||
_driveGear3 = (shiftPoint < _driveGear4 && shiftPoint >= _driveGear2) ? shiftPoint : _driveGear3;
|
||||
}
|
||||
|
||||
float MyAvatar::getDriveGear3() {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return ANALOG_AVATAR_GEAR_3;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _driveGear3;
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setDriveGear4(float shiftPoint) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setDriveGear4", Q_ARG(float, shiftPoint));
|
||||
return;
|
||||
}
|
||||
if (shiftPoint > 1.0f || shiftPoint < 0.0f) return;
|
||||
_driveGear4 = (shiftPoint < _driveGear5 && shiftPoint >= _driveGear3) ? shiftPoint : _driveGear4;
|
||||
}
|
||||
|
||||
float MyAvatar::getDriveGear4() {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return ANALOG_AVATAR_GEAR_4;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _driveGear4;
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setDriveGear5(float shiftPoint) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setDriveGear5", Q_ARG(float, shiftPoint));
|
||||
return;
|
||||
}
|
||||
if (shiftPoint > 1.0f || shiftPoint < 0.0f) return;
|
||||
_driveGear5 = (shiftPoint > _driveGear4) ? shiftPoint : _driveGear5;
|
||||
}
|
||||
|
||||
float MyAvatar::getDriveGear5() {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return ANALOG_AVATAR_GEAR_5;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _driveGear5;
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
bool MyAvatar::getFlyingHMDPref() {
|
||||
return _flyingPrefHMD;
|
||||
}
|
||||
|
@ -4488,11 +4767,37 @@ bool MyAvatar::getIsSitStandStateLocked() const {
|
|||
}
|
||||
|
||||
float MyAvatar::getWalkSpeed() const {
|
||||
return _walkSpeed.get() * _walkSpeedScalar;
|
||||
if (qApp->isHMDMode()) {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return _analogWalkSpeed.get();
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _analogPlusWalkSpeed.get();
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return _defaultWalkSpeed.get();
|
||||
}
|
||||
} else {
|
||||
return _defaultWalkSpeed.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float MyAvatar::getWalkBackwardSpeed() const {
|
||||
return _walkSpeed.get() * _walkSpeedScalar;
|
||||
if (qApp->isHMDMode()) {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return _analogWalkBackwardSpeed.get();
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _analogPlusWalkBackwardSpeed.get();
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return _defaultWalkBackwardSpeed.get();
|
||||
}
|
||||
} else {
|
||||
return _defaultWalkBackwardSpeed.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool MyAvatar::isReadyForPhysics() const {
|
||||
|
@ -4500,7 +4805,7 @@ bool MyAvatar::isReadyForPhysics() const {
|
|||
}
|
||||
|
||||
void MyAvatar::setSprintMode(bool sprint) {
|
||||
_walkSpeedScalar = sprint ? _sprintSpeed.get() : AVATAR_WALK_SPEED_SCALAR;
|
||||
_walkSpeedScalar = sprint ? AVATAR_SPRINT_SPEED_SCALAR : AVATAR_WALK_SPEED_SCALAR;
|
||||
}
|
||||
|
||||
void MyAvatar::setIsInWalkingState(bool isWalking) {
|
||||
|
@ -4563,19 +4868,103 @@ void MyAvatar::setIsSitStandStateLocked(bool isLocked) {
|
|||
}
|
||||
|
||||
void MyAvatar::setWalkSpeed(float value) {
|
||||
_walkSpeed.set(value);
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
_defaultWalkSpeed.set(value);
|
||||
break;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
_analogWalkSpeed.set(value);
|
||||
break;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
_analogPlusWalkSpeed.set(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setWalkBackwardSpeed(float value) {
|
||||
_walkBackwardSpeed.set(value);
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
_defaultWalkBackwardSpeed.set(value);
|
||||
break;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
_analogWalkBackwardSpeed.set(value);
|
||||
break;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
_analogPlusWalkBackwardSpeed.set(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setSprintSpeed(float value) {
|
||||
_sprintSpeed.set(value);
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
_defaultSprintSpeed.set(value);
|
||||
break;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
_analogSprintSpeed.set(value);
|
||||
break;
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
_analogPlusSprintSpeed.set(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float MyAvatar::getSprintSpeed() const {
|
||||
return _sprintSpeed.get();
|
||||
if (qApp->isHMDMode()) {
|
||||
switch (_controlSchemeIndex) {
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||
return _analogSprintSpeed.get();
|
||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||
return _analogPlusSprintSpeed.get();
|
||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||
default:
|
||||
return _defaultSprintSpeed.get();
|
||||
}
|
||||
} else {
|
||||
return _defaultSprintSpeed.get();
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setAnalogWalkSpeed(float value) {
|
||||
_analogWalkSpeed.set(value);
|
||||
// Sprint speed for Analog should be double walk speed.
|
||||
_analogSprintSpeed.set(value * 2.0f);
|
||||
}
|
||||
|
||||
float MyAvatar::getAnalogWalkSpeed() const {
|
||||
return _analogWalkSpeed.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setAnalogSprintSpeed(float value) {
|
||||
_analogSprintSpeed.set(value);
|
||||
}
|
||||
|
||||
float MyAvatar::getAnalogSprintSpeed() const {
|
||||
return _analogSprintSpeed.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setAnalogPlusWalkSpeed(float value) {
|
||||
_analogPlusWalkSpeed.set(value);
|
||||
// Sprint speed for Analog Plus should be double walk speed.
|
||||
_analogPlusSprintSpeed.set(value * 2.0f);
|
||||
}
|
||||
|
||||
float MyAvatar::getAnalogPlusWalkSpeed() const {
|
||||
return _analogPlusWalkSpeed.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setAnalogPlusSprintSpeed(float value) {
|
||||
_analogPlusSprintSpeed.set(value);
|
||||
}
|
||||
|
||||
float MyAvatar::getAnalogPlusSprintSpeed() const {
|
||||
return _analogPlusSprintSpeed.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setSitStandStateChange(bool stateChanged) {
|
||||
|
|
|
@ -39,6 +39,18 @@ class ModelItemID;
|
|||
class MyHead;
|
||||
class DetailedMotionState;
|
||||
|
||||
enum LocomotionControlsMode {
|
||||
CONTROLS_DEFAULT = 0,
|
||||
CONTROLS_ANALOG,
|
||||
CONTROLS_ANALOG_PLUS
|
||||
};
|
||||
|
||||
enum LocomotionRelativeMovementMode {
|
||||
MOVEMENT_HMD_RELATIVE = 0,
|
||||
MOVEMENT_HAND_RELATIVE,
|
||||
MOVEMENT_HAND_RELATIVE_LEVELED
|
||||
};
|
||||
|
||||
enum eyeContactTarget {
|
||||
LEFT_EYE,
|
||||
RIGHT_EYE,
|
||||
|
@ -371,6 +383,13 @@ class MyAvatar : public Avatar {
|
|||
using Clock = std::chrono::system_clock;
|
||||
using TimePoint = Clock::time_point;
|
||||
|
||||
const float DEFAULT_GEAR_1 = 0.2f;
|
||||
const float DEFAULT_GEAR_2 = 0.4f;
|
||||
const float DEFAULT_GEAR_3 = 0.8f;
|
||||
const float DEFAULT_GEAR_4 = 0.9f;
|
||||
const float DEFAULT_GEAR_5 = 1.0f;
|
||||
|
||||
const bool DEFAULT_STRAFE_ENABLED = true;
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
|
@ -729,7 +748,17 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; }
|
||||
|
||||
/**
|
||||
* @function MyAvatar.getControlScheme
|
||||
* @returns {number}
|
||||
*/
|
||||
Q_INVOKABLE int getControlScheme() const { return _controlSchemeIndex; }
|
||||
|
||||
/**
|
||||
* @function MyAvatar.setControlScheme
|
||||
* @param {number} index
|
||||
*/
|
||||
Q_INVOKABLE void setControlScheme(int index) { _controlSchemeIndex = (index >= 0 && index <= 2) ? index : 0; }
|
||||
/**jsdoc
|
||||
* Sets the avatar's dominant hand.
|
||||
* @function MyAvatar.setDominantHand
|
||||
|
@ -744,7 +773,16 @@ public:
|
|||
* @returns {string} <code>"left"</code> for the left hand, <code>"right"</code> for the right hand.
|
||||
*/
|
||||
Q_INVOKABLE QString getDominantHand() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAVatar.setStrafeEnabled
|
||||
* @param {bool} enabled
|
||||
*/
|
||||
Q_INVOKABLE void setStrafeEnabled(bool enabled);
|
||||
/**jsdoc
|
||||
* @function MyAvatar.getStrafeEnabled
|
||||
* @returns {bool}
|
||||
*/
|
||||
Q_INVOKABLE bool getStrafeEnabled() const;
|
||||
/**jsdoc
|
||||
* @function MyAvatar.setHmdAvatarAlignmentType
|
||||
* @param {string} type - <code>"head"</code> to align your head and your avatar's head, <code>"eyes"</code> to align your
|
||||
|
@ -1235,6 +1273,7 @@ public:
|
|||
controller::Pose getControllerPoseInSensorFrame(controller::Action action) const;
|
||||
controller::Pose getControllerPoseInWorldFrame(controller::Action action) const;
|
||||
controller::Pose getControllerPoseInAvatarFrame(controller::Action action) const;
|
||||
glm::quat getOffHandRotation() const;
|
||||
|
||||
bool hasDriveInput() const;
|
||||
|
||||
|
@ -1317,6 +1356,106 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE bool getFlyingHMDPref();
|
||||
|
||||
/**jsdoc
|
||||
* Set your preference for hand-relative movement.
|
||||
* @function MyAvatar.setHandRelativeMovement
|
||||
* @param {number} enabled - Set <code>true</code> if you want to enable hand-relative movement, otherwise set to <code>false</code>.
|
||||
*
|
||||
*/
|
||||
Q_INVOKABLE void setMovementReference(int enabled);
|
||||
|
||||
/**jsdoc
|
||||
* Get your preference for hand-relative movement.
|
||||
* @function MyAvatar.getHandRelativeMovement
|
||||
* @returns {number} <code>true</code> if your preference is for user locomotion to be relative to the direction your
|
||||
* controller is pointing, otherwise <code>false</code>.
|
||||
*/
|
||||
Q_INVOKABLE int getMovementReference();
|
||||
|
||||
/**jsdoc
|
||||
* Set the first 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.setDriveGear1
|
||||
* @param {number} shiftPoint - Set the first shift point for analog movement acceleration step function, between [0.0, 1.0]. Must be less than or equal to Gear 2.
|
||||
*/
|
||||
Q_INVOKABLE void setDriveGear1(float shiftPoint);
|
||||
|
||||
/**jsdoc
|
||||
* Get the first 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.getDriveGear1
|
||||
* @returns {number} Value between [0.0, 1.0].
|
||||
*/
|
||||
Q_INVOKABLE float getDriveGear1();
|
||||
|
||||
/**jsdoc
|
||||
* Set the second 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.setDriveGear2
|
||||
* @param {number} shiftPoint - Defines the second shift point for analog movement acceleration step function, between [0, 1]. Must be greater than or equal to Gear 1 and less than or equal to Gear 2.
|
||||
*/
|
||||
Q_INVOKABLE void setDriveGear2(float shiftPoint);
|
||||
|
||||
/**jsdoc
|
||||
* Get the second 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.getDriveGear2
|
||||
* @returns {number} Value between [0.0, 1.0].
|
||||
*/
|
||||
Q_INVOKABLE float getDriveGear2();
|
||||
|
||||
/**jsdoc
|
||||
* Set the third 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.setDriveGear3
|
||||
* @param {number} shiftPoint - Defines the third shift point for analog movement acceleration step function, between [0, 1]. Must be greater than or equal to Gear 2 and less than or equal to Gear 4.
|
||||
*/
|
||||
Q_INVOKABLE void setDriveGear3(float shiftPoint);
|
||||
|
||||
/**jsdoc
|
||||
* Get the third 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.getDriveGear3
|
||||
* @returns {number} Value between [0.0, 1.0].
|
||||
*/
|
||||
Q_INVOKABLE float getDriveGear3();
|
||||
|
||||
/**jsdoc
|
||||
* Set the fourth 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.setDriveGear4
|
||||
* @param {number} shiftPoint - Defines the fourth shift point for analog movement acceleration step function, between [0, 1]. Must be greater than Gear 3 and less than Gear 5.
|
||||
*/
|
||||
Q_INVOKABLE void setDriveGear4(float shiftPoint);
|
||||
|
||||
/**jsdoc
|
||||
* Get the fourth 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.getDriveGear4
|
||||
* @returns {number} Value between [0.0, 1.0].
|
||||
*/
|
||||
Q_INVOKABLE float getDriveGear4();
|
||||
|
||||
/**jsdoc
|
||||
* Set the fifth 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.setDriveGear5
|
||||
* @param {number} shiftPoint - Defines the fifth shift point for analog movement acceleration step function, between [0, 1]. Must be greater than or equal to Gear 4.
|
||||
*/
|
||||
Q_INVOKABLE void setDriveGear5(float shiftPoint);
|
||||
|
||||
/**jsdoc
|
||||
* Get the fifth 'shifting point' for acceleration step function.
|
||||
* @function MyAvatar.getDriveGear5
|
||||
* @returns {number} Value between [0.0, 1.0].
|
||||
*/
|
||||
Q_INVOKABLE float getDriveGear5();
|
||||
|
||||
/**jsdoc
|
||||
* Choose the control scheme.
|
||||
* @function MyAvatar.setControlSchemeIndex
|
||||
* @param {number} Choose the control scheme to be used.
|
||||
*/
|
||||
void setControlSchemeIndex(int index);
|
||||
|
||||
/**jsdoc
|
||||
* Check what control scheme is in use.
|
||||
* @function MyAvatar.getControlSchemeIndex
|
||||
* @returns {number} Returns the index associated with a given control scheme.
|
||||
*/
|
||||
int getControlSchemeIndex();
|
||||
|
||||
/**jsdoc
|
||||
* Gets the target scale of the avatar. The target scale is the desired scale of the avatar without any restrictions on
|
||||
* permissible scale values imposed by the domain.
|
||||
|
@ -1490,6 +1629,14 @@ public:
|
|||
float getWalkBackwardSpeed() const;
|
||||
void setSprintSpeed(float value);
|
||||
float getSprintSpeed() const;
|
||||
void setAnalogWalkSpeed(float value);
|
||||
float getAnalogWalkSpeed() const;
|
||||
void setAnalogSprintSpeed(float value);
|
||||
float getAnalogSprintSpeed() const;
|
||||
void setAnalogPlusWalkSpeed(float value);
|
||||
float getAnalogPlusWalkSpeed() const;
|
||||
void setAnalogPlusSprintSpeed(float value);
|
||||
float getAnalogPlusSprintSpeed() const;
|
||||
void setSitStandStateChange(bool stateChanged);
|
||||
float getSitStandStateChange() const;
|
||||
void updateSitStandState(float newHeightReading, float dt);
|
||||
|
@ -2230,6 +2377,13 @@ private:
|
|||
float _boomLength { ZOOM_DEFAULT };
|
||||
float _yawSpeed; // degrees/sec
|
||||
float _pitchSpeed; // degrees/sec
|
||||
float _driveGear1 { DEFAULT_GEAR_1 };
|
||||
float _driveGear2 { DEFAULT_GEAR_2 };
|
||||
float _driveGear3 { DEFAULT_GEAR_3 };
|
||||
float _driveGear4 { DEFAULT_GEAR_4 };
|
||||
float _driveGear5 { DEFAULT_GEAR_5 };
|
||||
int _controlSchemeIndex { CONTROLS_DEFAULT };
|
||||
int _movementReference{ 0 };
|
||||
|
||||
glm::vec3 _thrust { 0.0f }; // impulse accumulator for outside sources
|
||||
|
||||
|
@ -2270,6 +2424,9 @@ private:
|
|||
|
||||
// private methods
|
||||
void updateOrientation(float deltaTime);
|
||||
glm::vec3 calculateScaledDirection();
|
||||
float calculateGearedSpeed(const float driveKey);
|
||||
glm::vec3 scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 right);
|
||||
void updateActionMotor(float deltaTime);
|
||||
void updatePosition(float deltaTime);
|
||||
void updateViewBoom();
|
||||
|
@ -2287,6 +2444,7 @@ private:
|
|||
bool _useSnapTurn { true };
|
||||
ThreadSafeValueCache<QString> _dominantHand { DOMINANT_RIGHT_HAND };
|
||||
ThreadSafeValueCache<QString> _hmdAvatarAlignmentType { DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE };
|
||||
ThreadSafeValueCache<bool> _strafeEnabled{ DEFAULT_STRAFE_ENABLED };
|
||||
|
||||
const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // degrees
|
||||
const float ROLL_CONTROL_RATE_DEFAULT = 114.0f; // degrees / sec
|
||||
|
@ -2438,9 +2596,16 @@ private:
|
|||
ThreadSafeValueCache<bool> _lockSitStandState { false };
|
||||
|
||||
// max unscaled forward movement speed
|
||||
ThreadSafeValueCache<float> _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED };
|
||||
ThreadSafeValueCache<float> _walkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED };
|
||||
ThreadSafeValueCache<float> _sprintSpeed { AVATAR_SPRINT_SPEED_SCALAR };
|
||||
ThreadSafeValueCache<float> _defaultWalkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED };
|
||||
ThreadSafeValueCache<float> _defaultWalkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED };
|
||||
ThreadSafeValueCache<float> _defaultSprintSpeed { DEFAULT_AVATAR_MAX_SPRINT_SPEED };
|
||||
ThreadSafeValueCache<float> _analogWalkSpeed { ANALOG_AVATAR_MAX_WALKING_SPEED };
|
||||
ThreadSafeValueCache<float> _analogWalkBackwardSpeed { ANALOG_AVATAR_MAX_WALKING_BACKWARD_SPEED };
|
||||
ThreadSafeValueCache<float> _analogSprintSpeed { ANALOG_AVATAR_MAX_SPRINT_SPEED };
|
||||
ThreadSafeValueCache<float> _analogPlusWalkSpeed { ANALOG_PLUS_AVATAR_MAX_WALKING_SPEED };
|
||||
ThreadSafeValueCache<float> _analogPlusWalkBackwardSpeed { ANALOG_PLUS_AVATAR_MAX_WALKING_BACKWARD_SPEED };
|
||||
ThreadSafeValueCache<float> _analogPlusSprintSpeed { ANALOG_PLUS_AVATAR_MAX_SPRINT_SPEED };
|
||||
|
||||
float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR };
|
||||
bool _isInWalkingState { false };
|
||||
ThreadSafeValueCache<bool> _isInSittingState { false };
|
||||
|
@ -2460,6 +2625,7 @@ private:
|
|||
TimePoint _nextTraitsSendWindow;
|
||||
|
||||
Setting::Handle<QString> _dominantHandSetting;
|
||||
Setting::Handle<bool> _strafeEnabledSetting;
|
||||
Setting::Handle<QString> _hmdAvatarAlignmentTypeSetting;
|
||||
Setting::Handle<float> _headPitchSetting;
|
||||
Setting::Handle<float> _scaleSetting;
|
||||
|
@ -2473,8 +2639,17 @@ private:
|
|||
Setting::Handle<bool> _useSnapTurnSetting;
|
||||
Setting::Handle<float> _userHeightSetting;
|
||||
Setting::Handle<bool> _flyingHMDSetting;
|
||||
Setting::Handle<int> _movementReferenceSetting;
|
||||
Setting::Handle<int> _avatarEntityCountSetting;
|
||||
Setting::Handle<bool> _allowTeleportingSetting { "allowTeleporting", true };
|
||||
Setting::Handle<float> _driveGear1Setting;
|
||||
Setting::Handle<float> _driveGear2Setting;
|
||||
Setting::Handle<float> _driveGear3Setting;
|
||||
Setting::Handle<float> _driveGear4Setting;
|
||||
Setting::Handle<float> _driveGear5Setting;
|
||||
Setting::Handle<float> _analogWalkSpeedSetting;
|
||||
Setting::Handle<float> _analogPlusWalkSpeedSetting;
|
||||
Setting::Handle<int> _controlSchemeIndexSetting;
|
||||
std::vector<Setting::Handle<QUuid>> _avatarEntityIDSettings;
|
||||
std::vector<Setting::Handle<QByteArray>> _avatarEntityDataSettings;
|
||||
Setting::Handle<QString> _userRecenterModelSetting;
|
||||
|
|
|
@ -266,6 +266,11 @@ void setupPreferences() {
|
|||
auto preference = new CheckPreference(VR_MOVEMENT, "Walking", getter, setter);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->bool { return myAvatar->getStrafeEnabled(); };
|
||||
auto setter = [myAvatar](bool value) { myAvatar->setStrafeEnabled(value); };
|
||||
preferences->addPreference(new CheckPreference(VR_MOVEMENT, "Strafing", getter, setter));
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->bool { return myAvatar->getFlyingHMDPref(); };
|
||||
auto setter = [myAvatar](bool value) { myAvatar->setFlyingHMDPref(value); };
|
||||
|
@ -273,6 +278,22 @@ void setupPreferences() {
|
|||
preference->setIndented(true);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->int { return myAvatar->getMovementReference(); };
|
||||
auto setter = [myAvatar](int value) { myAvatar->setMovementReference(value); };
|
||||
//auto preference = new CheckPreference(VR_MOVEMENT, "Hand-Relative Movement", getter, setter);
|
||||
auto preference = new RadioButtonsPreference(VR_MOVEMENT, "Movement Direction", getter, setter);
|
||||
QStringList items;
|
||||
items << "HMD-Relative" << "Hand-Relative" << "Hand-Relative (Leveled)";
|
||||
preference->setHeading("Movement Direction");
|
||||
preference->setItems(items);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->QString { return myAvatar->getDominantHand(); };
|
||||
auto setter = [myAvatar](const QString& value) { myAvatar->setDominantHand(value); };
|
||||
preferences->addPreference(new PrimaryHandPreference(VR_MOVEMENT, "Dominant Hand", getter, setter));
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->int { return myAvatar->getSnapTurn() ? 0 : 1; };
|
||||
auto setter = [myAvatar](int value) { myAvatar->setSnapTurn(value == 0); };
|
||||
|
@ -283,6 +304,26 @@ void setupPreferences() {
|
|||
preference->setItems(items);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->int { return myAvatar->getControlScheme(); };
|
||||
auto setter = [myAvatar](int index) { myAvatar->setControlScheme(index); };
|
||||
auto preference = new RadioButtonsPreference(VR_MOVEMENT, "Control Scheme", getter, setter);
|
||||
QStringList items;
|
||||
items << "Default" << "Analog" << "Analog++";
|
||||
preference->setHeading("Control Scheme Selection");
|
||||
preference->setItems(items);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->float { return myAvatar->getAnalogPlusWalkSpeed(); };
|
||||
auto setter = [myAvatar](float value) { myAvatar->setAnalogPlusWalkSpeed(value); };
|
||||
auto preference = new SpinnerSliderPreference(VR_MOVEMENT, "Analog++ Walk Speed", getter, setter);
|
||||
preference->setMin(6.0f);
|
||||
preference->setMax(30.0f);
|
||||
preference->setStep(1);
|
||||
preference->setDecimals(2);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [myAvatar]()->bool { return myAvatar->getShowPlayArea(); };
|
||||
auto setter = [myAvatar](bool value) { myAvatar->setShowPlayArea(value); };
|
||||
|
|
|
@ -48,6 +48,8 @@ public:
|
|||
|
||||
void pluginUpdate() override {};
|
||||
|
||||
virtual StencilMode getStencilMaskMode() const override { return StencilMode::PAINT; }
|
||||
|
||||
signals:
|
||||
void hmdMountedChanged();
|
||||
void hmdVisibleChanged(bool visible);
|
||||
|
|
|
@ -1459,7 +1459,7 @@ void EntityTree::startDynamicDomainVerificationOnServer(float minimumAgeToRemove
|
|||
|
||||
QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson());
|
||||
|
||||
connect(networkReply, &QNetworkReply::finished, this, [this, entityIDs, networkReply, minimumAgeToRemove, &certificateID] {
|
||||
connect(networkReply, &QNetworkReply::finished, this, [this, entityIDs, networkReply, minimumAgeToRemove, certificateID] {
|
||||
|
||||
QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object();
|
||||
jsonObject = jsonObject["data"].toObject();
|
||||
|
|
|
@ -362,7 +362,6 @@ MeshPointer Mesh::createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numI
|
|||
mesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(numIndices * sizeof(uint32_t), (gpu::Byte*) indices), gpu::Element::INDEX_INT32));
|
||||
}
|
||||
|
||||
|
||||
std::vector<graphics::Mesh::Part> parts;
|
||||
parts.push_back(graphics::Mesh::Part(0, numIndices, 0, graphics::Mesh::TRIANGLES));
|
||||
mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <SimpleMovingAverage.h>
|
||||
#include <gpu/Forward.h>
|
||||
#include "Plugin.h"
|
||||
#include "StencilMode.h"
|
||||
|
||||
class QOpenGLFramebufferObject;
|
||||
|
||||
|
@ -221,6 +222,10 @@ public:
|
|||
// for updating plugin-related commands. Mimics the input plugin.
|
||||
virtual void pluginUpdate() = 0;
|
||||
|
||||
virtual StencilMode getStencilMaskMode() const { return StencilMode::NONE; }
|
||||
using StencilMaskMeshOperator = std::function<void(gpu::Batch&)>;
|
||||
virtual StencilMaskMeshOperator getStencilMaskMeshOperator() { return nullptr; }
|
||||
|
||||
signals:
|
||||
void recommendedFramebufferSizeChanged(const QSize& size);
|
||||
void resetSensorsRequested();
|
||||
|
|
|
@ -1289,6 +1289,8 @@ void Model::scaleToFit() {
|
|||
// size is our "target size in world space"
|
||||
// we need to set our model scale so that the extents of the mesh, fit in a box that size...
|
||||
glm::vec3 meshDimensions = modelMeshExtents.maximum - modelMeshExtents.minimum;
|
||||
const glm::vec3 MIN_MESH_DIMENSIONS { 1.0e-6f }; // one micrometer
|
||||
meshDimensions = glm::max(meshDimensions, MIN_MESH_DIMENSIONS);
|
||||
glm::vec3 rescaleDimensions = _scaleToFitDimensions / meshDimensions;
|
||||
setScaleInternal(rescaleDimensions);
|
||||
_scaledToFit = true;
|
||||
|
|
|
@ -397,7 +397,7 @@ protected:
|
|||
|
||||
glm::vec3 _translation; // this is the translation in world coordinates to the model's registration point
|
||||
glm::quat _rotation;
|
||||
glm::vec3 _scale;
|
||||
glm::vec3 _scale { 1.0f };
|
||||
|
||||
glm::vec3 _overrideTranslation;
|
||||
glm::quat _overrideRotation;
|
||||
|
|
|
@ -19,7 +19,6 @@ using namespace render;
|
|||
|
||||
void PrepareStencil::configure(const Config& config) {
|
||||
_maskMode = config.maskMode;
|
||||
_forceDraw = config.forceDraw;
|
||||
}
|
||||
|
||||
graphics::MeshPointer PrepareStencil::getMesh() {
|
||||
|
@ -43,6 +42,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() {
|
|||
auto state = std::make_shared<gpu::State>();
|
||||
drawMask(*state);
|
||||
state->setColorWriteMask(gpu::State::WRITE_NONE);
|
||||
state->setCullMode(gpu::State::CullMode::CULL_NONE);
|
||||
|
||||
_meshStencilPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
@ -64,30 +64,37 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() {
|
|||
void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) {
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
// Only draw the stencil mask if in HMD mode or not forced.
|
||||
if (!_forceDraw && (args->_displayMode != RenderArgs::STEREO_HMD)) {
|
||||
StencilMode maskMode = _maskMode;
|
||||
std::function<void(gpu::Batch&)> maskOperator = [this](gpu::Batch& batch) {
|
||||
auto mesh = getMesh();
|
||||
batch.setIndexBuffer(mesh->getIndexBuffer());
|
||||
batch.setInputFormat((mesh->getVertexFormat()));
|
||||
batch.setInputStream(0, mesh->getVertexStream());
|
||||
|
||||
// Draw
|
||||
auto part = mesh->getPartBuffer().get<graphics::Mesh::Part>(0);
|
||||
batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex);
|
||||
};
|
||||
|
||||
if (maskMode == StencilMode::NONE) {
|
||||
maskMode = args->_stencilMode;
|
||||
maskOperator = args->_stencilMaskOperator;
|
||||
}
|
||||
|
||||
if (maskMode == StencilMode::NONE || (maskMode == StencilMode::MESH && !maskOperator)) {
|
||||
return;
|
||||
}
|
||||
|
||||
doInBatch("PrepareStencil::run", args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
|
||||
if (_maskMode < 0) {
|
||||
batch.setPipeline(getMeshStencilPipeline());
|
||||
|
||||
auto mesh = getMesh();
|
||||
batch.setIndexBuffer(mesh->getIndexBuffer());
|
||||
batch.setInputFormat((mesh->getVertexFormat()));
|
||||
batch.setInputStream(0, mesh->getVertexStream());
|
||||
|
||||
// Draw
|
||||
auto part = mesh->getPartBuffer().get<graphics::Mesh::Part>(0);
|
||||
batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex);
|
||||
} else {
|
||||
if (maskMode == StencilMode::PAINT) {
|
||||
batch.setPipeline(getPaintStencilPipeline());
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
} else if (maskMode == StencilMode::MESH) {
|
||||
batch.setPipeline(getMeshStencilPipeline());
|
||||
maskOperator(batch);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,17 +15,19 @@
|
|||
#include <render/Engine.h>
|
||||
#include <gpu/Pipeline.h>
|
||||
#include <graphics/Geometry.h>
|
||||
#include <StencilMode.h>
|
||||
|
||||
class PrepareStencilConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int maskMode MEMBER maskMode NOTIFY dirty)
|
||||
Q_PROPERTY(bool forceDraw MEMBER forceDraw NOTIFY dirty)
|
||||
Q_PROPERTY(StencilMode maskMode MEMBER maskMode NOTIFY dirty)
|
||||
|
||||
public:
|
||||
PrepareStencilConfig(bool enabled = true) : JobConfig(enabled) {}
|
||||
|
||||
int maskMode { 0 };
|
||||
bool forceDraw { false };
|
||||
// -1 -> don't force drawing (fallback to render args mode)
|
||||
// 0 -> force draw without mesh
|
||||
// 1 -> force draw with mesh
|
||||
StencilMode maskMode { StencilMode::NONE };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
@ -66,8 +68,7 @@ private:
|
|||
graphics::MeshPointer _mesh;
|
||||
graphics::MeshPointer getMesh();
|
||||
|
||||
int _maskMode { 0 };
|
||||
bool _forceDraw { false };
|
||||
StencilMode _maskMode { StencilMode::NONE };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
#include <GLMHelpers.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <StencilMode.h>
|
||||
|
||||
#include <gpu/Forward.h>
|
||||
#include "Forward.h"
|
||||
|
||||
|
||||
class AABox;
|
||||
|
||||
namespace render {
|
||||
|
@ -133,6 +133,9 @@ namespace render {
|
|||
|
||||
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> _hudOperator;
|
||||
gpu::TexturePointer _hudTexture;
|
||||
|
||||
StencilMode _stencilMode { StencilMode::NONE };
|
||||
std::function<void(gpu::Batch&)> _stencilMaskOperator;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ ScriptEnginePointer scriptEngineFactory(ScriptEngine::Context context,
|
|||
const QString& scriptContents,
|
||||
const QString& fileNameString) {
|
||||
ScriptEngine* engine = new ScriptEngine(context, scriptContents, fileNameString);
|
||||
ScriptEnginePointer engineSP = ScriptEnginePointer(engine);
|
||||
ScriptEnginePointer engineSP = ScriptEnginePointer(engine, &QObject::deleteLater);
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
scriptEngines->addScriptEngine(qSharedPointerCast<ScriptEngine>(engineSP));
|
||||
engine->setScriptEngines(scriptEngines);
|
||||
|
@ -267,7 +267,7 @@ void ScriptEngine::disconnectNonEssentialSignals() {
|
|||
QThread* workerThread;
|
||||
// Ensure the thread should be running, and does exist
|
||||
if (_isRunning && _isThreaded && (workerThread = thread())) {
|
||||
connect(this, &ScriptEngine::doneRunning, workerThread, &QThread::quit);
|
||||
connect(this, &QObject::destroyed, workerThread, &QThread::quit);
|
||||
connect(workerThread, &QThread::finished, workerThread, &QObject::deleteLater);
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ void ScriptEngine::runInThread() {
|
|||
// the script engine, make sure to add code to "reconnect" them to the
|
||||
// disconnectNonEssentialSignals() method
|
||||
connect(workerThread, &QThread::started, this, &ScriptEngine::run);
|
||||
connect(this, &ScriptEngine::doneRunning, workerThread, &QThread::quit);
|
||||
connect(this, &QObject::destroyed, workerThread, &QThread::quit);
|
||||
connect(workerThread, &QThread::finished, workerThread, &QObject::deleteLater);
|
||||
|
||||
workerThread->start();
|
||||
|
|
|
@ -69,7 +69,23 @@ const glm::quat DEFAULT_AVATAR_RIGHTFOOT_ROT { -0.4016716778278351f, 0.915461599
|
|||
const float DEFAULT_AVATAR_MAX_WALKING_SPEED = 2.6f; // meters / second
|
||||
const float DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED = 2.2f; // meters / second
|
||||
const float DEFAULT_AVATAR_MAX_FLYING_SPEED = 30.0f; // meters / second
|
||||
const float DEFAULT_AVATAR_WALK_SPEED_THRESHOLD = 0.15f;
|
||||
const float DEFAULT_AVATAR_MAX_SPRINT_SPEED = 3.4f; // meters / second
|
||||
const float DEFAULT_AVATAR_WALK_SPEED_THRESHOLD = 0.15f; // meters / second
|
||||
|
||||
const float ANALOG_AVATAR_MAX_WALKING_SPEED = 6.0f; // meters / second
|
||||
const float ANALOG_AVATAR_MAX_WALKING_BACKWARD_SPEED = 2.2f; // meters / second
|
||||
const float ANALOG_AVATAR_MAX_FLYING_SPEED = 30.0f; // meters / second
|
||||
const float ANALOG_AVATAR_MAX_SPRINT_SPEED = 8.0f; // meters / second
|
||||
const float ANALOG_AVATAR_GEAR_1 = 0.2f; // meters / second
|
||||
const float ANALOG_AVATAR_GEAR_2 = 0.4f; // meters / second
|
||||
const float ANALOG_AVATAR_GEAR_3 = 0.6f; // meters / second
|
||||
const float ANALOG_AVATAR_GEAR_4 = 0.8f; // meters / second
|
||||
const float ANALOG_AVATAR_GEAR_5 = 1.0f; // meters / second
|
||||
|
||||
const float ANALOG_PLUS_AVATAR_MAX_WALKING_SPEED = 10.0f; // meters / second
|
||||
const float ANALOG_PLUS_AVATAR_MAX_WALKING_BACKWARD_SPEED = 2.42f; // meters / second
|
||||
const float ANALOG_PLUS_AVATAR_MAX_FLYING_SPEED = 30.0f; // meters / second
|
||||
const float ANALOG_PLUS_AVATAR_MAX_SPRINT_SPEED = 20.0f; // meters / second
|
||||
|
||||
const float DEFAULT_AVATAR_GRAVITY = -5.0f; // meters / second^2 (world)
|
||||
const float DEFAULT_AVATAR_JUMP_SPEED = 3.5f; // meters / second (sensor)
|
||||
|
@ -86,6 +102,6 @@ static const float MAX_AVATAR_HEIGHT = 1000.0f * DEFAULT_AVATAR_HEIGHT; // meter
|
|||
static const float MIN_AVATAR_HEIGHT = 0.005f * DEFAULT_AVATAR_HEIGHT; // meters
|
||||
static const float MIN_AVATAR_RADIUS = 0.5f * MIN_AVATAR_HEIGHT;
|
||||
static const float AVATAR_WALK_SPEED_SCALAR = 1.0f;
|
||||
static const float AVATAR_SPRINT_SPEED_SCALAR = 3.0f;
|
||||
static const float AVATAR_SPRINT_SPEED_SCALAR = 2.0f;
|
||||
|
||||
#endif // hifi_AvatarConstants_h
|
||||
|
|
|
@ -40,6 +40,7 @@ int qMapURLStringMetaTypeId = qRegisterMetaType<QMap<QUrl,QString>>();
|
|||
int socketErrorMetaTypeId = qRegisterMetaType<QAbstractSocket::SocketError>();
|
||||
int voidLambdaType = qRegisterMetaType<std::function<void()>>();
|
||||
int variantLambdaType = qRegisterMetaType<std::function<QVariant()>>();
|
||||
int stencilModeMetaTypeId = qRegisterMetaType<StencilMode>();
|
||||
|
||||
void registerMetaTypes(QScriptEngine* engine) {
|
||||
qScriptRegisterMetaType(engine, vec2ToScriptValue, vec2FromScriptValue);
|
||||
|
@ -64,6 +65,8 @@ void registerMetaTypes(QScriptEngine* engine) {
|
|||
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, aaCubeToScriptValue, aaCubeFromScriptValue);
|
||||
|
||||
qScriptRegisterMetaType(engine, stencilModeToScriptValue, stencilModeFromScriptValue);
|
||||
}
|
||||
|
||||
QScriptValue vec2ToScriptValue(QScriptEngine* engine, const glm::vec2& vec2) {
|
||||
|
@ -1283,4 +1286,12 @@ QVariantMap parseTexturesToMap(QString newTextures, const QVariantMap& defaultTe
|
|||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
QScriptValue stencilModeToScriptValue(QScriptEngine* engine, const StencilMode& stencilMode) {
|
||||
return engine->newVariant((int)stencilMode);
|
||||
}
|
||||
|
||||
void stencilModeFromScriptValue(const QScriptValue& object, StencilMode& stencilMode) {
|
||||
stencilMode = StencilMode(object.toVariant().toInt());
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
#include "shared/Bilateral.h"
|
||||
#include "Transform.h"
|
||||
#include "PhysicsCollisionGroups.h"
|
||||
#include "StencilMode.h"
|
||||
|
||||
class QColor;
|
||||
class QUrl;
|
||||
|
@ -729,5 +730,8 @@ void qVectorMeshFaceFromScriptValue(const QScriptValue& array, QVector<MeshFace>
|
|||
|
||||
QVariantMap parseTexturesToMap(QString textures, const QVariantMap& defaultTextures);
|
||||
|
||||
Q_DECLARE_METATYPE(StencilMode)
|
||||
QScriptValue stencilModeToScriptValue(QScriptEngine* engine, const StencilMode& stencilMode);
|
||||
void stencilModeFromScriptValue(const QScriptValue &object, StencilMode& stencilMode);
|
||||
|
||||
#endif // hifi_RegisteredMetaTypes_h
|
||||
|
|
19
libraries/shared/src/StencilMode.h
Normal file
19
libraries/shared/src/StencilMode.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 3/26/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_StencilMode_h
|
||||
#define hifi_StencilMode_h
|
||||
|
||||
enum class StencilMode {
|
||||
NONE = -1, // for legacy reasons, this is -1
|
||||
PAINT = 0,
|
||||
MESH = 1
|
||||
};
|
||||
|
||||
#endif // hifi_StencilMode_h
|
||||
|
|
@ -18,7 +18,7 @@ if (WIN32 AND (NOT USE_GLES))
|
|||
link_hifi_libraries(
|
||||
shared task gl shaders gpu ${PLATFORM_GL_BACKEND} controllers ui qml
|
||||
plugins ui-plugins display-plugins input-plugins
|
||||
audio-client networking render-utils
|
||||
audio-client networking render-utils graphics
|
||||
${PLATFORM_GL_BACKEND}
|
||||
)
|
||||
include_hifi_library_headers(octree)
|
||||
|
|
|
@ -227,3 +227,66 @@ QVector<glm::vec3> OculusBaseDisplayPlugin::getSensorPositions() {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
DisplayPlugin::StencilMaskMeshOperator OculusBaseDisplayPlugin::getStencilMaskMeshOperator() {
|
||||
if (_session) {
|
||||
if (!_stencilMeshesInitialized) {
|
||||
_stencilMeshesInitialized = true;
|
||||
ovr::for_each_eye([&](ovrEyeType eye) {
|
||||
ovrFovStencilDesc stencilDesc = {
|
||||
ovrFovStencil_HiddenArea, 0, eye,
|
||||
_eyeRenderDescs[eye].Fov, _eyeRenderDescs[eye].HmdToEyePose.Orientation
|
||||
};
|
||||
// First we get the size of the buffer we need
|
||||
ovrFovStencilMeshBuffer buffer = { 0, 0, nullptr, 0, 0, nullptr };
|
||||
ovrResult result = ovr_GetFovStencil(_session, &stencilDesc, &buffer);
|
||||
if (!OVR_SUCCESS(result)) {
|
||||
_stencilMeshesInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<ovrVector2f> ovrVertices(buffer.UsedVertexCount);
|
||||
std::vector<uint16_t> ovrIndices(buffer.UsedIndexCount);
|
||||
|
||||
// Now we populate the actual buffer
|
||||
buffer = { (int)ovrVertices.size(), 0, ovrVertices.data(), (int)ovrIndices.size(), 0, ovrIndices.data() };
|
||||
result = ovr_GetFovStencil(_session, &stencilDesc, &buffer);
|
||||
|
||||
if (!OVR_SUCCESS(result)) {
|
||||
_stencilMeshesInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<glm::vec3> vertices;
|
||||
vertices.reserve(ovrVertices.size());
|
||||
for (auto& ovrVertex : ovrVertices) {
|
||||
// We need the vertices in clip space
|
||||
vertices.emplace_back(ovrVertex.x - (1.0f - (float)eye), 2.0f * ovrVertex.y - 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> indices;
|
||||
indices.reserve(ovrIndices.size());
|
||||
for (auto& ovrIndex : ovrIndices) {
|
||||
indices.push_back(ovrIndex);
|
||||
}
|
||||
|
||||
_stencilMeshes[eye] = graphics::Mesh::createIndexedTriangles_P3F((uint32_t)vertices.size(), (uint32_t)indices.size(), vertices.data(), indices.data());
|
||||
});
|
||||
}
|
||||
|
||||
if (_stencilMeshesInitialized) {
|
||||
return [&](gpu::Batch& batch) {
|
||||
for (auto& mesh : _stencilMeshes) {
|
||||
batch.setIndexBuffer(mesh->getIndexBuffer());
|
||||
batch.setInputFormat((mesh->getVertexFormat()));
|
||||
batch.setInputStream(0, mesh->getVertexStream());
|
||||
|
||||
// Draw
|
||||
auto part = mesh->getPartBuffer().get<graphics::Mesh::Part>(0);
|
||||
batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
|
@ -16,6 +16,8 @@
|
|||
#define OVRPL_DISABLED
|
||||
#include <OVR_Platform.h>
|
||||
|
||||
#include <graphics/Geometry.h>
|
||||
|
||||
class OculusBaseDisplayPlugin : public HmdDisplayPlugin {
|
||||
using Parent = HmdDisplayPlugin;
|
||||
public:
|
||||
|
@ -34,6 +36,9 @@ public:
|
|||
QRectF getPlayAreaRect() override;
|
||||
QVector<glm::vec3> getSensorPositions() override;
|
||||
|
||||
virtual StencilMode getStencilMaskMode() const override { return StencilMode::MESH; }
|
||||
virtual StencilMaskMeshOperator getStencilMaskMeshOperator() override;
|
||||
|
||||
protected:
|
||||
void customizeContext() override;
|
||||
void uncustomizeContext() override;
|
||||
|
@ -52,4 +57,7 @@ protected:
|
|||
// ovrLayerEyeFovDepth _depthLayer;
|
||||
bool _hmdMounted { false };
|
||||
bool _visible { true };
|
||||
|
||||
std::array<graphics::MeshPointer, 2> _stencilMeshes;
|
||||
bool _stencilMeshesInitialized { false };
|
||||
};
|
||||
|
|
|
@ -784,3 +784,49 @@ QRectF OpenVrDisplayPlugin::getPlayAreaRect() {
|
|||
|
||||
return QRectF(center.x, center.y, dimensions.x, dimensions.y);
|
||||
}
|
||||
|
||||
|
||||
DisplayPlugin::StencilMaskMeshOperator OpenVrDisplayPlugin::getStencilMaskMeshOperator() {
|
||||
if (_system) {
|
||||
if (!_stencilMeshesInitialized) {
|
||||
_stencilMeshesInitialized = true;
|
||||
for (auto eye : VR_EYES) {
|
||||
vr::HiddenAreaMesh_t stencilMesh = _system->GetHiddenAreaMesh(eye);
|
||||
if (stencilMesh.pVertexData && stencilMesh.unTriangleCount > 0) {
|
||||
std::vector<glm::vec3> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
|
||||
const int NUM_INDICES_PER_TRIANGLE = 3;
|
||||
int numIndices = stencilMesh.unTriangleCount * NUM_INDICES_PER_TRIANGLE;
|
||||
vertices.reserve(numIndices);
|
||||
indices.reserve(numIndices);
|
||||
for (int i = 0; i < numIndices; i++) {
|
||||
vr::HmdVector2_t vertex2D = stencilMesh.pVertexData[i];
|
||||
// We need the vertices in clip space
|
||||
vertices.emplace_back(vertex2D.v[0] - (1.0f - (float)eye), 2.0f * vertex2D.v[1] - 1.0f, 0.0f);
|
||||
indices.push_back(i);
|
||||
}
|
||||
|
||||
_stencilMeshes[eye] = graphics::Mesh::createIndexedTriangles_P3F((uint32_t)vertices.size(), (uint32_t)indices.size(), vertices.data(), indices.data());
|
||||
} else {
|
||||
_stencilMeshesInitialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_stencilMeshesInitialized) {
|
||||
return [&](gpu::Batch& batch) {
|
||||
for (auto& mesh : _stencilMeshes) {
|
||||
batch.setIndexBuffer(mesh->getIndexBuffer());
|
||||
batch.setInputFormat((mesh->getVertexFormat()));
|
||||
batch.setInputStream(0, mesh->getVertexStream());
|
||||
|
||||
// Draw
|
||||
auto part = mesh->getPartBuffer().get<graphics::Mesh::Part>(0);
|
||||
batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <display-plugins/hmd/HmdDisplayPlugin.h>
|
||||
|
||||
#include <graphics/Geometry.h>
|
||||
|
||||
const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only.
|
||||
|
||||
namespace gl {
|
||||
|
@ -67,6 +69,9 @@ public:
|
|||
|
||||
QRectF getPlayAreaRect() override;
|
||||
|
||||
virtual StencilMode getStencilMaskMode() const override{ return StencilMode::MESH; }
|
||||
virtual StencilMaskMeshOperator getStencilMaskMeshOperator() override;
|
||||
|
||||
protected:
|
||||
bool internalActivate() override;
|
||||
void internalDeactivate() override;
|
||||
|
@ -94,4 +99,7 @@ private:
|
|||
bool _asyncReprojectionActive { false };
|
||||
|
||||
bool _hmdMounted { false };
|
||||
|
||||
std::array<graphics::MeshPointer, 2> _stencilMeshes;
|
||||
bool _stencilMeshesInitialized { false };
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
|
||||
(function() {
|
||||
(function () {
|
||||
var MARGIN = 25;
|
||||
|
||||
function TargetObject(entityID, entityProps) {
|
||||
|
@ -27,12 +27,13 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.targetEntityID = null;
|
||||
this.targetEntityProps = null;
|
||||
|
||||
this.getTargetEntity = function() {
|
||||
this.getTargetEntity = function () {
|
||||
var parentPropsLength = this.parentProps.length;
|
||||
if (parentPropsLength !== 0) {
|
||||
var targetEntity = {
|
||||
id: this.parentProps[parentPropsLength - 1].id,
|
||||
props: this.parentProps[parentPropsLength - 1]};
|
||||
props: this.parentProps[parentPropsLength - 1]
|
||||
};
|
||||
this.targetEntityID = targetEntity.id;
|
||||
this.targetEntityProps = targetEntity.props;
|
||||
return targetEntity;
|
||||
|
@ -41,7 +42,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.targetEntityProps = this.entityProps;
|
||||
return {
|
||||
id: this.entityID,
|
||||
props: this.entityProps};
|
||||
props: this.entityProps
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -62,8 +64,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.MIN_HAPTIC_PULSE_INTERVAL = 500; // ms
|
||||
this.disabled = false;
|
||||
var _this = this;
|
||||
this.leftTrigger = 0.0;
|
||||
this.rightTrigger = 0.0;
|
||||
this.initialControllerRotation = Quat.IDENTITY;
|
||||
this.currentControllerRotation = Quat.IDENTITY;
|
||||
this.manipulating = false;
|
||||
|
@ -101,13 +101,9 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return (this.hand === RIGHT_HAND ? LEFT_HAND : RIGHT_HAND);
|
||||
}
|
||||
|
||||
this.getOffhandTrigger = function () {
|
||||
return (_this.hand === RIGHT_HAND ? _this.leftTrigger : _this.rightTrigger);
|
||||
}
|
||||
|
||||
// Activation criteria for rotating a fargrabbed entity. If we're changing the mapping, this is where to do it.
|
||||
this.shouldManipulateTarget = function () {
|
||||
return (_this.getOffhandTrigger() > TRIGGER_ON_VALUE) ? true : false;
|
||||
this.shouldManipulateTarget = function (controllerData) {
|
||||
return (controllerData.triggerValues[this.getOffhand()] > TRIGGER_ON_VALUE || controllerData.secondaryValues[this.getOffhand()] > TRIGGER_ON_VALUE) ? true : false;
|
||||
};
|
||||
|
||||
// Get the delta between the current rotation and where the controller was when manipulation started.
|
||||
|
@ -123,11 +119,15 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
MyAvatar.setJointRotation(FAR_GRAB_JOINTS[this.hand], newTargetRotLocal);
|
||||
};
|
||||
|
||||
this.handToController = function() {
|
||||
this.setJointRotation = function (newTargetRotLocal) {
|
||||
MyAvatar.setJointRotation(FAR_GRAB_JOINTS[this.hand], newTargetRotLocal);
|
||||
};
|
||||
|
||||
this.handToController = function () {
|
||||
return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||
};
|
||||
|
||||
this.distanceGrabTimescale = function(mass, distance) {
|
||||
this.distanceGrabTimescale = function (mass, distance) {
|
||||
var timeScale = DISTANCE_HOLDING_ACTION_TIMEFRAME * mass /
|
||||
DISTANCE_HOLDING_UNITY_MASS * distance /
|
||||
DISTANCE_HOLDING_UNITY_DISTANCE;
|
||||
|
@ -137,7 +137,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return timeScale;
|
||||
};
|
||||
|
||||
this.getMass = function(dimensions, density) {
|
||||
this.getMass = function (dimensions, density) {
|
||||
return (dimensions.x * dimensions.y * dimensions.z) * density;
|
||||
};
|
||||
|
||||
|
@ -204,8 +204,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
}
|
||||
var farJointIndex = FAR_GRAB_JOINTS[this.hand];
|
||||
this.grabID = MyAvatar.grab(targetProps.id, farJointIndex,
|
||||
Entities.worldToLocalPosition(targetProps.position, MyAvatar.SELF_ID, farJointIndex),
|
||||
Entities.worldToLocalRotation(targetProps.rotation, MyAvatar.SELF_ID, farJointIndex));
|
||||
Entities.worldToLocalPosition(targetProps.position, MyAvatar.SELF_ID, farJointIndex),
|
||||
Entities.worldToLocalRotation(targetProps.rotation, MyAvatar.SELF_ID, farJointIndex));
|
||||
|
||||
Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({
|
||||
action: 'grab',
|
||||
|
@ -217,7 +217,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.previousRoomControllerPosition = roomControllerPosition;
|
||||
};
|
||||
|
||||
this.continueDistanceHolding = function(controllerData) {
|
||||
this.continueDistanceHolding = function (controllerData) {
|
||||
var controllerLocation = controllerData.controllerLocations[this.hand];
|
||||
var worldControllerPosition = controllerLocation.position;
|
||||
var worldControllerRotation = controllerLocation.orientation;
|
||||
|
@ -263,7 +263,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
var RADIAL_GRAB_AMPLIFIER = 10.0;
|
||||
if (Math.abs(this.grabRadialVelocity) > 0.0) {
|
||||
this.grabRadius = this.grabRadius + (this.grabRadialVelocity * deltaObjectTime *
|
||||
this.grabRadius * RADIAL_GRAB_AMPLIFIER);
|
||||
this.grabRadius * RADIAL_GRAB_AMPLIFIER);
|
||||
}
|
||||
|
||||
// don't let grabRadius go all the way to zero, because it can't come back from that
|
||||
|
@ -278,7 +278,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
var newTargetPosLocal = MyAvatar.worldToJointPoint(newTargetPosition);
|
||||
|
||||
// This block handles the user's ability to rotate the object they're FarGrabbing
|
||||
if (this.shouldManipulateTarget()) {
|
||||
if (this.shouldManipulateTarget(controllerData)) {
|
||||
// Get the pose of the controller that is not grabbing.
|
||||
var pose = Controller.getPoseValue((this.getOffhand() ? Controller.Standard.RightHand : Controller.Standard.LeftHand));
|
||||
if (pose.valid) {
|
||||
|
@ -345,13 +345,13 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
otherModule.disabled = false;
|
||||
};
|
||||
|
||||
this.updateRecommendedArea = function() {
|
||||
this.updateRecommendedArea = function () {
|
||||
var dims = Controller.getViewportDimensions();
|
||||
this.reticleMaxX = dims.x - MARGIN;
|
||||
this.reticleMaxY = dims.y - MARGIN;
|
||||
};
|
||||
|
||||
this.calculateNewReticlePosition = function(intersection) {
|
||||
this.calculateNewReticlePosition = function (intersection) {
|
||||
this.updateRecommendedArea();
|
||||
var point2d = HMD.overlayFromWorldPoint(intersection);
|
||||
point2d.x = Math.max(this.reticleMinX, Math.min(point2d.x, this.reticleMaxX));
|
||||
|
@ -359,7 +359,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return point2d;
|
||||
};
|
||||
|
||||
this.notPointingAtEntity = function(controllerData) {
|
||||
this.notPointingAtEntity = function (controllerData) {
|
||||
var intersection = controllerData.rayPicks[this.hand];
|
||||
var entityProperty = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES);
|
||||
var entityType = entityProperty.type;
|
||||
|
@ -372,7 +372,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return false;
|
||||
};
|
||||
|
||||
this.destroyContextOverlay = function(controllerData) {
|
||||
this.destroyContextOverlay = function (controllerData) {
|
||||
if (this.entityWithContextOverlay) {
|
||||
ContextOverlay.destroyContextOverlay(this.entityWithContextOverlay);
|
||||
this.entityWithContextOverlay = false;
|
||||
|
@ -380,7 +380,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
}
|
||||
};
|
||||
|
||||
this.targetIsNull = function() {
|
||||
this.targetIsNull = function () {
|
||||
var properties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES);
|
||||
if (Object.keys(properties).length === 0 && this.distanceHolding) {
|
||||
return true;
|
||||
|
@ -424,8 +424,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.run = function (controllerData) {
|
||||
this.leftTrigger = controllerData.triggerValues[LEFT_HAND];
|
||||
this.rightTrigger = controllerData.triggerValues[RIGHT_HAND];
|
||||
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.targetIsNull()) {
|
||||
this.endFarGrabEntity(controllerData);
|
||||
return makeRunningValues(false, [], []);
|
||||
|
@ -522,12 +520,12 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
_this.contextOverlayTimer &&
|
||||
_this.potentialEntityWithContextOverlay === rayPickInfo.objectID) {
|
||||
var cotProps = Entities.getEntityProperties(rayPickInfo.objectID,
|
||||
DISPATCHER_PROPERTIES);
|
||||
DISPATCHER_PROPERTIES);
|
||||
var pointerEvent = {
|
||||
type: "Move",
|
||||
id: _this.hand + 1, // 0 is reserved for hardware mouse
|
||||
pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID,
|
||||
rayPickInfo.intersection, cotProps),
|
||||
rayPickInfo.intersection, cotProps),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.surfaceNormal,
|
||||
direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal),
|
||||
|
@ -546,7 +544,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return this.exitIfDisabled(controllerData);
|
||||
};
|
||||
|
||||
this.exitIfDisabled = function(controllerData) {
|
||||
this.exitIfDisabled = function (controllerData) {
|
||||
var moduleName = this.hand === RIGHT_HAND ? "RightDisableModules" : "LeftDisableModules";
|
||||
var disableModule = getEnabledModuleByName(moduleName);
|
||||
if (disableModule) {
|
||||
|
@ -563,10 +561,10 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return makeRunningValues(true, [], [], laserLockInfo);
|
||||
};
|
||||
|
||||
this.calculateOffset = function(controllerData) {
|
||||
this.calculateOffset = function (controllerData) {
|
||||
if (this.distanceHolding) {
|
||||
var targetProps = Entities.getEntityProperties(this.targetObject.entityID,
|
||||
[ "position", "rotation", "registrationPoint", "dimensions" ]);
|
||||
["position", "rotation", "registrationPoint", "dimensions"]);
|
||||
return worldPositionToRegistrationFrameMatrix(targetProps, controllerData.rayPicks[this.hand].intersection);
|
||||
}
|
||||
return undefined;
|
||||
|
|
|
@ -129,6 +129,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.init = false;
|
||||
this.hand = hand;
|
||||
this.buttonValue = 0;
|
||||
this.standardAxisLY = 0.0;
|
||||
this.standardAxisRY = 0.0;
|
||||
this.disabled = false; // used by the 'Hifi-Teleport-Disabler' message handler
|
||||
this.active = false;
|
||||
this.state = TELEPORTER_STATES.IDLE;
|
||||
|
@ -690,6 +692,44 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
}
|
||||
};
|
||||
|
||||
this.getStandardLY = function (value) {
|
||||
_this.standardAxisLY = value;
|
||||
};
|
||||
|
||||
this.getStandardRY = function (value) {
|
||||
_this.standardAxisRY = value;
|
||||
};
|
||||
|
||||
// Return value for the getDominantY and getOffhandY functions has to be inverted.
|
||||
this.getDominantY = function () {
|
||||
return (MyAvatar.getDominantHand() === "left") ? -(_this.standardAxisLY) : -(_this.standardAxisRY);
|
||||
};
|
||||
|
||||
this.getOffhandY = function () {
|
||||
return (MyAvatar.getDominantHand() === "left") ? -(_this.standardAxisRY) : -(_this.standardAxisLY);
|
||||
};
|
||||
|
||||
this.getDominantHand = function () {
|
||||
return (MyAvatar.getDominantHand() === "left") ? LEFT_HAND : RIGHT_HAND;
|
||||
}
|
||||
|
||||
this.getOffHand = function () {
|
||||
return (MyAvatar.getDominantHand() === "left") ? RIGHT_HAND : LEFT_HAND;
|
||||
}
|
||||
|
||||
this.showReticle = function () {
|
||||
return (_this.getDominantY() > TELEPORT_DEADZONE) ? true : false;
|
||||
};
|
||||
|
||||
this.shouldTeleport = function () {
|
||||
return (_this.getDominantY() > TELEPORT_DEADZONE && _this.getOffhandY() > TELEPORT_DEADZONE) ? true : false;
|
||||
};
|
||||
|
||||
this.shouldCancel = function () {
|
||||
//return (_this.getDominantY() < -TELEPORT_DEADZONE || _this.getOffhandY() < -TELEPORT_DEADZONE) ? true : false;
|
||||
return (_this.getDominantY() <= TELEPORT_DEADZONE) ? true : false;
|
||||
};
|
||||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
80,
|
||||
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
||||
|
@ -706,7 +746,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
}
|
||||
|
||||
var otherModule = this.getOtherModule();
|
||||
if (!this.disabled && this.buttonValue !== 0 && !otherModule.active) {
|
||||
if (!this.disabled && this.showReticle() && !otherModule.active && this.hand === this.getDominantHand()) {
|
||||
this.active = true;
|
||||
this.enterTeleport();
|
||||
return makeRunningValues(true, [], []);
|
||||
|
@ -715,6 +755,12 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.run = function(controllerData, deltaTime) {
|
||||
// Kill condition:
|
||||
if (_this.shouldCancel()) {
|
||||
_this.disableLasers();
|
||||
this.active = false;
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
||||
// Get current hand pose information to see if the pose is valid
|
||||
var pose = Controller.getPoseValue(handInfo[(_this.hand === RIGHT_HAND) ? 'right' : 'left'].controllerInput);
|
||||
|
@ -778,7 +824,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
this.teleport = function(newResult, target) {
|
||||
var result = newResult;
|
||||
_this.teleportedPosition = newResult.intersection;
|
||||
if (_this.buttonValue !== 0) {
|
||||
if (!_this.shouldTeleport()) {
|
||||
return makeRunningValues(true, [], []);
|
||||
}
|
||||
|
||||
|
@ -801,8 +847,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.disableLasers = function() {
|
||||
_this.setPlayAreaVisible(false, null, true);
|
||||
_this.setTeleportVisible(false, null, true);
|
||||
_this.setPlayAreaVisible(false, null, false);
|
||||
_this.setTeleportVisible(false, null, false);
|
||||
Pointers.disablePointer(_this.teleportParabolaHandVisuals);
|
||||
Pointers.disablePointer(_this.teleportParabolaHandCollisions);
|
||||
Pointers.disablePointer(_this.teleportParabolaHeadVisuals);
|
||||
|
@ -982,6 +1028,10 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
// Teleport actions.
|
||||
teleportMapping.from(Controller.Standard.LeftPrimaryThumb).peek().to(leftTeleporter.buttonPress);
|
||||
teleportMapping.from(Controller.Standard.RightPrimaryThumb).peek().to(rightTeleporter.buttonPress);
|
||||
teleportMapping.from(Controller.Standard.LY).peek().to(leftTeleporter.getStandardLY);
|
||||
teleportMapping.from(Controller.Standard.RY).peek().to(leftTeleporter.getStandardRY);
|
||||
teleportMapping.from(Controller.Standard.LY).peek().to(rightTeleporter.getStandardLY);
|
||||
teleportMapping.from(Controller.Standard.RY).peek().to(rightTeleporter.getStandardRY);
|
||||
}
|
||||
|
||||
var leftTeleporter = new Teleporter(LEFT_HAND);
|
||||
|
|
|
@ -15,7 +15,7 @@ var CONTOLLER_SCRIPTS = [
|
|||
"squeezeHands.js",
|
||||
"controllerDisplayManager.js",
|
||||
"grab.js",
|
||||
"toggleAdvancedMovementForHandControllers.js",
|
||||
//"toggleAdvancedMovementForHandControllers.js",
|
||||
"handTouch.js",
|
||||
"controllerDispatcher.js",
|
||||
"controllerModules/nearParentGrabOverlay.js",
|
||||
|
|
|
@ -103,6 +103,8 @@ TEAR_AWAY_DISTANCE = 0.15; // ungrab an entity if its bounding-box moves this fa
|
|||
TEAR_AWAY_COUNT = 2; // multiply by TEAR_AWAY_CHECK_TIME to know how long the item must be away
|
||||
TEAR_AWAY_CHECK_TIME = 0.15; // seconds, duration between checks
|
||||
|
||||
TELEPORT_DEADZONE = 0.15;
|
||||
|
||||
NEAR_GRAB_DISTANCE = 0.14; // Grab an entity if its bounding box is within this distance.
|
||||
// Smaller than TEAR_AWAY_DISTANCE for hysteresis.
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@
|
|||
var clickMapping = Controller.newMapping('tabletToggle-click');
|
||||
var wantsMenu = 0;
|
||||
clickMapping.from(function () { return wantsMenu; }).to(Controller.Actions.ContextMenu);
|
||||
clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(function (clicked) {
|
||||
clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().when(Controller.Hardware.Application.LeftHandDominant).to(function (clicked) {
|
||||
if (clicked) {
|
||||
//activeHudPoint2d(Controller.Standard.RightHand);
|
||||
Messages.sendLocalMessage("toggleHand", Controller.Standard.RightHand);
|
||||
|
@ -299,7 +299,7 @@
|
|||
wantsMenu = clicked;
|
||||
});
|
||||
|
||||
clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (clicked) {
|
||||
clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().when(Controller.Hardware.Application.RightHandDominant).to(function (clicked) {
|
||||
if (clicked) {
|
||||
//activeHudPoint2d(Controller.Standard.LeftHand);
|
||||
Messages.sendLocalMessage("toggleHand", Controller.Standard.LeftHand);
|
||||
|
|
|
@ -11,7 +11,7 @@ If you would like the extra functionality for gravPrep:
|
|||
To generate html documentation for the High Fidelity JavaScript API:
|
||||
|
||||
* `cd tools/jsdoc`
|
||||
* `jsdoc root.js -c config.json`
|
||||
* `jsdoc root.js -r api-mainpage.md -c config.json`
|
||||
|
||||
The out folder should contain index.html.
|
||||
|
||||
|
|
9
tools/jsdoc/api-mainpage.md
Normal file
9
tools/jsdoc/api-mainpage.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
The High Fidelity JavaScript API lets content creators and developers create new experiences and transform virtual worlds within the High Fidelity metaverse. With it, you can build great content, customize avatars, play audio and so much more.
|
||||
|
||||
You are most likely to interact with these APIs:
|
||||
|
||||
* The **[Entities](Entities.html)** namespace lets you add, remove, and edit entities around you to build an interactive environment. In addition, you can use this namespace to find entities in range, direction, collision, or raytrace.
|
||||
* The **[AvatarList](AvatarList.html)**, **[MyAvatar](MyAvatar.html)**, and **[Avatar](Avatar.html)** namespaces affect your personal avatars, and lets you get information on other people's avatars.
|
||||
* The **[Script](Script.html)** namespace lets you to connect callbacks from your client to script, such as functionality that is dependent on time (`Script.update`, `Script.setTimeout`, `Script.setInterval`, etc), connect paths relatively to assets (`Script.resolvePath`), refer to other scripts (`Script.require`, `Script.include`), or connect functions to events which occur when the script is turned off (`Script.scriptEnding`).
|
||||
|
||||
To learn more about using High Fidelity and exploring the metaverse, visit the [High Fidelity Documentation](https://docs.highfidelity.com).
|
|
@ -420,7 +420,7 @@ function linktoExternal(longName, name) {
|
|||
*/
|
||||
|
||||
function buildNav(members) {
|
||||
var nav = '<h3><a href="index.html">Home</a></h3>';
|
||||
var nav = '<h3><a href="index.html">API Reference Home</a></h3>';
|
||||
var seen = {};
|
||||
var seenTutorials = {};
|
||||
var docdash = env && env.conf && env.conf.docdash || {};
|
||||
|
|
Binary file not shown.
BIN
tools/jsdoc/hifi-jsdoc-template/static/fonts/Graphik-Regular.otf
Normal file
BIN
tools/jsdoc/hifi-jsdoc-template/static/fonts/Graphik-Regular.otf
Normal file
Binary file not shown.
Binary file not shown.
BIN
tools/jsdoc/hifi-jsdoc-template/static/images/fav-icon.ico
Normal file
BIN
tools/jsdoc/hifi-jsdoc-template/static/images/fav-icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 49 KiB |
|
@ -4,8 +4,13 @@
|
|||
********************************************************************/
|
||||
|
||||
@font-face{
|
||||
font-family: 'Cairo';
|
||||
src: url('../fonts/Cairo-Bold.ttf') format('truetype');
|
||||
font-family: 'Graphik Semibold';
|
||||
src: url('../fonts/Graphik-SemiBold.otf') format('opentype');
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family: 'Graphik Regular';
|
||||
src: url('../fonts/Graphik-Regular.otf') format('opentype');
|
||||
}
|
||||
|
||||
@font-face{
|
||||
|
@ -29,12 +34,15 @@ html
|
|||
|
||||
body
|
||||
{
|
||||
font-family: 'Proxima Nova', sans-serif;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.5px;
|
||||
margin: 1.5rem;
|
||||
color: #555;
|
||||
font-family: 'Graphik Regular', 'Proxima Nova', arial, sans-serif;
|
||||
font-weight: 400;
|
||||
color: #000000;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
#main p {
|
||||
line-height: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
section
|
||||
|
@ -50,14 +58,13 @@ section
|
|||
********************************************************************/
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: "Cairo", Helvetica, sans-serif;
|
||||
font-family: "Graphik Semibold", Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
font-size: 3.25rem;
|
||||
text-align: center;
|
||||
letter-spacing: 1.5px;
|
||||
margin: 50px 25px 25px;
|
||||
}
|
||||
|
||||
|
@ -69,15 +76,13 @@ h2
|
|||
|
||||
h3
|
||||
{
|
||||
font-size: 1.5rem;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
h4
|
||||
{
|
||||
font-size: 18px;
|
||||
letter-spacing: -0.33px;
|
||||
margin-bottom: 12px;
|
||||
color: #4d4e53;
|
||||
font-family: 'Graphik Regular';
|
||||
font-size: 1.03rem;
|
||||
}
|
||||
|
||||
h6
|
||||
|
@ -119,7 +124,7 @@ table
|
|||
background-color: #fff;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 1px solid #ccc;
|
||||
border: solid #d8e1d9 1px;
|
||||
text-align: left;
|
||||
overflow: auto;
|
||||
font-size: 0.9rem;
|
||||
|
@ -128,18 +133,19 @@ table
|
|||
}
|
||||
|
||||
table > thead {
|
||||
background-color: #ddd;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-color: #d8e1d9;
|
||||
background: #d8e1d9;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
padding: 0.5rem;
|
||||
border-left: 1px solid #ccc;
|
||||
border-left: 1px solid #d8e1d9;
|
||||
font-size: .95em;
|
||||
}
|
||||
|
||||
table tr {
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-bottom: 1px solid #d8e1d9;
|
||||
}
|
||||
|
||||
table tr:nth-child(even) {
|
||||
|
@ -150,18 +156,14 @@ table tr:nth-child(even) {
|
|||
****************************** Link styles *************************
|
||||
********************************************************************/
|
||||
|
||||
a, a:visited, a:active {
|
||||
color: #1694CA;
|
||||
text-decoration: none;
|
||||
a, a:hover, a:active, a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
article a:hover {
|
||||
color: #0e6185;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
#main a, #main a:visited, #main a:active, #main a:hover {
|
||||
color: #009ee0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
***************************** List styles **************************
|
||||
********************************************************************/
|
||||
|
@ -171,20 +173,29 @@ article ul {
|
|||
}
|
||||
|
||||
article li {
|
||||
font-size: .95rem;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.readme ul {
|
||||
font-size: 0.95rem;
|
||||
line-height: 24px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
********************** Navigation sidebar styles *******************
|
||||
********************************************************************/
|
||||
|
||||
nav {
|
||||
position: fixed;
|
||||
top: 165px;
|
||||
top: 260px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 305px;
|
||||
width: 300px;
|
||||
background-color: #000000;
|
||||
border-right: 1px solid #ccc;
|
||||
overflow-y: scroll;
|
||||
padding-left: 20px;
|
||||
|
@ -192,6 +203,11 @@ nav {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
nav::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
nav #nav-search {
|
||||
width: 210px;
|
||||
height: 30px;
|
||||
|
@ -207,21 +223,28 @@ nav #nav-search {
|
|||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 165px;
|
||||
width: 305px;
|
||||
background-color: #00B4EF;
|
||||
vertical-align: middle;
|
||||
height: 260px;
|
||||
width: 300px;
|
||||
background-color: #000000;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.nav-header p {
|
||||
padding-top: 15px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.nav-header a {
|
||||
color: #FFFFFF;
|
||||
font-size: .9rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
nav h3 {
|
||||
font-family: "Proxima Nova", sans-serif;
|
||||
font-family: "Graphik Regular", sans-serif;
|
||||
font-size: 0.9rem;
|
||||
color: #FFFFFF;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
@ -233,8 +256,16 @@ nav ul {
|
|||
list-style: none;
|
||||
}
|
||||
|
||||
nav h3 a {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
nav ul a, nav ul a:visited, nav ul a:active {
|
||||
color: #a1a1a1;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
nav ul a:hover {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
nav ul ul {
|
||||
|
@ -250,7 +281,7 @@ nav ul ul li:first-child
|
|||
|
||||
nav li
|
||||
{
|
||||
margin-top: 3px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
|
||||
|
@ -333,14 +364,14 @@ nav > h2 > a {
|
|||
|
||||
.search-input
|
||||
{
|
||||
font-family: 'Proxima Nova', sans-serif;
|
||||
font-size: 0.9rem;
|
||||
font-family: 'Graphik Regular', sans-serif;
|
||||
font-size: 80%;
|
||||
border: 1px solid #ddd;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.06);
|
||||
border-radius: 0.1875rem;
|
||||
border-radius: 0;
|
||||
color: #3A3F3E;
|
||||
width: 75%;
|
||||
padding: 0.425rem;
|
||||
width: 70%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
@ -349,23 +380,20 @@ nav > h2 > a {
|
|||
|
||||
tt, code, kbd, samp {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
font-size: 0.8rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.name, .signature {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
font-size: 0.8rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
p, ul, ol, blockquote {
|
||||
|
@ -427,7 +455,7 @@ header {
|
|||
color: #999 !important;
|
||||
}
|
||||
|
||||
.availableIn
|
||||
#main p.availableIn
|
||||
{
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
@ -517,7 +545,7 @@ header {
|
|||
|
||||
.prettyprint code
|
||||
{
|
||||
font-size: 0.65rem;
|
||||
font-size: 0.7rem;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
padding: 4px 12px;
|
||||
|
@ -580,13 +608,8 @@ header {
|
|||
padding-top: 0;
|
||||
}
|
||||
|
||||
.params td.description > p:last-child, .props td.description > p:last-child {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
span.param-type, .params td .param-type, .param-type dd {
|
||||
color: #606;
|
||||
color: #606;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace
|
||||
}
|
||||
|
||||
|
|
|
@ -16,10 +16,11 @@
|
|||
<body>
|
||||
|
||||
<div class="nav-header">
|
||||
<p><img src="images/white-logo.png" width="200px" /></p>
|
||||
<p><a href="https://www.highfidelity.com"><img src="images/white-logo.png" width="214px" /></a></p>
|
||||
<?js if (env.conf.docdash.search) { ?>
|
||||
<input type="text" class="search-input" id="nav-search" placeholder="Search ..." />
|
||||
<input type="text" class="search-input" id="nav-search" placeholder="Search API Docs ..." />
|
||||
<?js } ?>
|
||||
<p><a href="https://docs.highfidelity.com">Looking for <strong>High Fidelity</strong><br /> Documentation?</a></p>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
|
@ -69,5 +70,54 @@
|
|||
<?js } ?>
|
||||
<?js } ?>
|
||||
|
||||
<!-- Start Google Analytics Tag -->
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', '{{ theme_config.google_analytics_code }}', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
<!-- End Google Analytics Tag -->
|
||||
|
||||
<!-- Start of HubSpot Embed Code -->
|
||||
<script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/5066246.js"></script>
|
||||
<!-- End of HubSpot Embed Code -->
|
||||
|
||||
<!-- Start Quantcast Tag -->
|
||||
<script type="text/javascript">
|
||||
var _qevents = _qevents || [];
|
||||
(function() {
|
||||
var elem = document.createElement('script');
|
||||
elem.src = (document.location.protocol == "https:" ? "https://secure" : "http://edge") + ".quantserve.com/quant.js";
|
||||
elem.async = true;
|
||||
elem.type = "text/javascript";
|
||||
var scpt = document.getElementsByTagName('script')[0];
|
||||
scpt.parentNode.insertBefore(elem, scpt);
|
||||
})();
|
||||
_qevents.push({qacct: "p-tK6PFLJY3q1s-"});
|
||||
</script>
|
||||
<noscript>
|
||||
<img src="//pixel.quantserve.com/pixel/p-tK6PFLJY3q1s-.gif?labels=_fp.event.Default" style="display: none;" border="0" height="1" width="1" alt="Quantcast"/>
|
||||
</noscript>
|
||||
<!-- End Quantcast Tag -->
|
||||
|
||||
|
||||
<!-- Start Hotjar Tracking Code for https://highfidelity.com/ -->
|
||||
<script>
|
||||
(function(h,o,t,j,a,r){
|
||||
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
|
||||
h._hjSettings={hjid:908553,hjsv:6};
|
||||
a=o.getElementsByTagName('head')[0];
|
||||
r=o.createElement('script');r.async=1;
|
||||
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
|
||||
a.appendChild(r);
|
||||
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
|
||||
</script>
|
||||
<!-- End Hotjar Tracking Code for https://highfidelity.com/ -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -20,7 +20,7 @@ var self = this;
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<?js if (data.kind !== 'module' && data.description && !data.hideconstructor) { ?>
|
||||
<?js if (data.kind !== 'module' && !data.hideconstructor) { ?>
|
||||
<p>
|
||||
<?js= data.description ?>
|
||||
<?js= this.partial('details.tmpl', data) ?>
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
<?js } ?>
|
||||
|
||||
<?js if (params.hasDefault) {?>
|
||||
<th>Default</th>
|
||||
<th>Default Value</th>
|
||||
<?js } ?>
|
||||
|
||||
<th class="last">Description</th>
|
||||
|
@ -96,10 +96,26 @@
|
|||
<?js } ?>
|
||||
</td>
|
||||
|
||||
<?js if (params.hasAttributes) {?>
|
||||
<td class="attributes">
|
||||
<?js if (param.optional) { ?>
|
||||
<optional><br>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (param.nullable) { ?>
|
||||
<nullable><br>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (param.variable) { ?>
|
||||
<repeatable><br>
|
||||
<?js } ?>
|
||||
</td>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (params.hasDefault) {?>
|
||||
<td class="default">
|
||||
<?js if (typeof param.defaultvalue !== 'undefined') { ?>
|
||||
Default Value: <?js= self.htmlsafe(param.defaultvalue) ?>
|
||||
<?js= self.htmlsafe(param.defaultvalue) ?>
|
||||
<?js } ?>
|
||||
</td>
|
||||
<?js } ?>
|
||||
|
|
|
@ -480,7 +480,7 @@ void AWSInterface::createEntry(const int index, const QString& testResult, QText
|
|||
if (differenceFileFound) {
|
||||
stream << "\t\t\t\t<td><img src=\"./" << folder << "/" << resultName << "/" << _comparisonImageFilename << "\" width = \"576\" height = \"324\" ></td>\n";
|
||||
} else {
|
||||
stream << "\t\t\t\t<td><h2>No Image Found</h2>\n";
|
||||
stream << "\t\t\t\t<td><h2>Image size mismatch</h2>\n";
|
||||
}
|
||||
|
||||
stream << "\t\t\t</tr>\n";
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "Nitpick.h"
|
||||
#include "Platform.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
|
@ -40,9 +41,15 @@ Nitpick::Nitpick(QWidget* parent) : QMainWindow(parent) {
|
|||
|
||||
setWindowTitle("Nitpick - " + nitpickVersion);
|
||||
|
||||
clientProfiles << "VR-High" << "Desktop-High" << "Desktop-Low" << "Mobile-Touch" << "VR-Standalone";
|
||||
_ui.clientProfileComboBox->insertItems(0, clientProfiles);
|
||||
_GPUVendors << "Nvidia" << "AMD";
|
||||
_ui.gpuVendorComboBox->insertItems(0, _GPUVendors);
|
||||
|
||||
QString gpuVendor = Platform::getGraphicsCardType().toUpper();
|
||||
if (gpuVendor.contains("NVIDIA")) {
|
||||
_ui.gpuVendorComboBox->setCurrentIndex(0);
|
||||
} else {
|
||||
_ui.gpuVendorComboBox->setCurrentIndex(1);
|
||||
}
|
||||
}
|
||||
|
||||
Nitpick::~Nitpick() {
|
||||
|
@ -126,13 +133,14 @@ void Nitpick::setup() {
|
|||
);
|
||||
}
|
||||
|
||||
void Nitpick::startTestsEvaluation(const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branch,
|
||||
const QString& user
|
||||
void Nitpick::startTestsEvaluation(
|
||||
const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branch,
|
||||
const QString& user
|
||||
) {
|
||||
_testCreator->startTestsEvaluation(isRunningFromCommandLine, isRunningInAutomaticTestRun, snapshotDirectory, branch, user);
|
||||
_testCreator->startTestsEvaluation(_ui.gpuVendorComboBox, isRunningFromCommandLine, isRunningInAutomaticTestRun, snapshotDirectory, branch, user);
|
||||
}
|
||||
|
||||
void Nitpick::on_tabWidget_currentChanged(int index) {
|
||||
|
@ -144,9 +152,11 @@ void Nitpick::on_tabWidget_currentChanged(int index) {
|
|||
#endif
|
||||
_ui.userLineEdit->setDisabled(false);
|
||||
_ui.branchLineEdit->setDisabled(false);
|
||||
_ui.gpuVendorComboBox->setDisabled(false);
|
||||
} else {
|
||||
_ui.userLineEdit->setDisabled(true);
|
||||
_ui.branchLineEdit->setDisabled(true);
|
||||
_ui.gpuVendorComboBox->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +169,7 @@ void Nitpick::on_createAllRecursiveScriptsPushbutton_clicked() {
|
|||
}
|
||||
|
||||
void Nitpick::on_createTestsPushbutton_clicked() {
|
||||
_testCreator->createTests(_ui.clientProfileComboBox->currentText());
|
||||
_testCreator->createTests(_ui.gpuVendorComboBox->currentText());
|
||||
}
|
||||
|
||||
void Nitpick::on_createMDFilePushbutton_clicked() {
|
||||
|
@ -250,7 +260,7 @@ void Nitpick::on_showTaskbarPushbutton_clicked() {
|
|||
}
|
||||
|
||||
void Nitpick::on_evaluateTestsPushbutton_clicked() {
|
||||
_testCreator->startTestsEvaluation(false, false);
|
||||
_testCreator->startTestsEvaluation(_ui.gpuVendorComboBox, false, false);
|
||||
}
|
||||
|
||||
void Nitpick::on_closePushbutton_clicked() {
|
||||
|
|
|
@ -28,11 +28,13 @@ public:
|
|||
|
||||
void setup();
|
||||
|
||||
void startTestsEvaluation(const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branch,
|
||||
const QString& user);
|
||||
void startTestsEvaluation(
|
||||
const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branch,
|
||||
const QString& user
|
||||
);
|
||||
|
||||
void automaticTestRunEvaluationComplete(QString zippedFolderName, int numberOfFailures);
|
||||
|
||||
|
@ -111,7 +113,7 @@ private:
|
|||
|
||||
bool _isRunningFromCommandline{ false };
|
||||
|
||||
QStringList clientProfiles;
|
||||
QStringList _GPUVendors;
|
||||
};
|
||||
|
||||
#endif // hifi_Nitpick_h
|
121
tools/nitpick/src/Platform.cpp
Normal file
121
tools/nitpick/src/Platform.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
//
|
||||
// Platform.h
|
||||
//
|
||||
// Created by Nissim Hadar on 2 Apr 2019.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "Platform.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <dxgi1_3.h>
|
||||
#pragma comment(lib, "dxgi.lib")
|
||||
#elif defined Q_OS_MAC
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <sstream>
|
||||
#include <QStringList>
|
||||
#endif
|
||||
|
||||
QString Platform::getGraphicsCardType() {
|
||||
#ifdef Q_OS_WIN
|
||||
IDXGIFactory1* pFactory = nullptr;
|
||||
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory));
|
||||
if (hr != S_OK || pFactory == nullptr) {
|
||||
return "Unable to create DXGI";
|
||||
}
|
||||
std::vector<int> validAdapterList;
|
||||
|
||||
using AdapterEntry = std::pair<std::pair<DXGI_ADAPTER_DESC1, LARGE_INTEGER>, std::vector<DXGI_OUTPUT_DESC>>;
|
||||
std::vector<AdapterEntry> adapterToOutputs;
|
||||
// Enumerate adapters and outputs
|
||||
{
|
||||
UINT adapterNum = 0;
|
||||
IDXGIAdapter1* pAdapter = nullptr;
|
||||
while (pFactory->EnumAdapters1(adapterNum, &pAdapter) != DXGI_ERROR_NOT_FOUND) {
|
||||
|
||||
// Found an adapter, get descriptor
|
||||
DXGI_ADAPTER_DESC1 adapterDesc;
|
||||
pAdapter->GetDesc1(&adapterDesc);
|
||||
|
||||
LARGE_INTEGER version;
|
||||
hr = pAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &version);
|
||||
|
||||
std::wstring wDescription (adapterDesc.Description);
|
||||
std::string description(wDescription.begin(), wDescription.end());
|
||||
|
||||
AdapterEntry adapterEntry;
|
||||
adapterEntry.first.first = adapterDesc;
|
||||
adapterEntry.first.second = version;
|
||||
|
||||
|
||||
|
||||
UINT outputNum = 0;
|
||||
IDXGIOutput * pOutput;
|
||||
bool hasOutputConnectedToDesktop = false;
|
||||
while (pAdapter->EnumOutputs(outputNum, &pOutput) != DXGI_ERROR_NOT_FOUND) {
|
||||
|
||||
// FOund an output attached to the adapter, get descriptor
|
||||
DXGI_OUTPUT_DESC outputDesc;
|
||||
pOutput->GetDesc(&outputDesc);
|
||||
|
||||
adapterEntry.second.push_back(outputDesc);
|
||||
|
||||
std::wstring wDeviceName(outputDesc.DeviceName);
|
||||
std::string deviceName(wDeviceName.begin(), wDeviceName.end());
|
||||
|
||||
hasOutputConnectedToDesktop |= (bool)outputDesc.AttachedToDesktop;
|
||||
|
||||
pOutput->Release();
|
||||
outputNum++;
|
||||
}
|
||||
|
||||
adapterToOutputs.push_back(adapterEntry);
|
||||
|
||||
// add this adapter to the valid list if has output
|
||||
if (hasOutputConnectedToDesktop && !adapterEntry.second.empty()) {
|
||||
validAdapterList.push_back(adapterNum);
|
||||
}
|
||||
|
||||
pAdapter->Release();
|
||||
adapterNum++;
|
||||
}
|
||||
}
|
||||
pFactory->Release();
|
||||
|
||||
if (!validAdapterList.empty()) {
|
||||
auto& adapterEntry = adapterToOutputs[validAdapterList.front()];
|
||||
|
||||
std::wstring wDescription(adapterEntry.first.first.Description);
|
||||
std::string description(wDescription.begin(), wDescription.end());
|
||||
return QString(description.c_str());
|
||||
}
|
||||
|
||||
#elif defined Q_OS_MAC
|
||||
FILE* stream = popen("system_profiler SPDisplaysDataType | grep Chipset", "r");
|
||||
|
||||
std::ostringstream hostStream;
|
||||
while (!feof(stream) && !ferror(stream)) {
|
||||
char buf[128];
|
||||
int bytesRead = fread(buf, 1, 128, stream);
|
||||
hostStream.write(buf, bytesRead);
|
||||
}
|
||||
|
||||
QString result = QString::fromStdString(hostStream.str());
|
||||
QStringList parts = result.split('\n');
|
||||
for (int i = 0; i < parts.size(); ++i) {
|
||||
if (parts[i].toLower().contains("radeon") || parts[i].toLower().contains("nvidia")) {
|
||||
return parts[i];
|
||||
}
|
||||
}
|
||||
|
||||
// unkown graphics card
|
||||
return "UNKNOWN";
|
||||
#else
|
||||
return QString("NO IMPLEMENTED");
|
||||
#endif
|
||||
return "";
|
||||
}
|
20
tools/nitpick/src/Platform.h
Normal file
20
tools/nitpick/src/Platform.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Platform.h
|
||||
//
|
||||
// Created by Nissim Hadar on 2 Apr 2019.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_Platform_h
|
||||
#define hifi_Platform_h
|
||||
|
||||
#include <QString>
|
||||
|
||||
class Platform {
|
||||
public:
|
||||
static QString getGraphicsCardType();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -67,7 +67,7 @@ QString TestCreator::zipAndDeleteTestResultsFolder() {
|
|||
return zippedResultsFileName;
|
||||
}
|
||||
|
||||
int TestCreator::compareImageLists() {
|
||||
int TestCreator::compareImageLists(const QString& gpuVendor) {
|
||||
_progressBar->setMinimum(0);
|
||||
_progressBar->setMaximum(_expectedImagesFullFilenames.length() - 1);
|
||||
_progressBar->setValue(0);
|
||||
|
@ -108,8 +108,16 @@ int TestCreator::compareImageLists() {
|
|||
};
|
||||
|
||||
_mismatchWindow.setTestResult(testResult);
|
||||
|
||||
if (similarityIndex < THRESHOLD_GLOBAL || worstTileValue < THRESHOLD_LOCAL) {
|
||||
|
||||
// Lower threshold for non-Nvidia GPUs
|
||||
double thresholdGlobal{ 0.9995 };
|
||||
double thresholdLocal{ 0.6 };
|
||||
if (gpuVendor != "Nvidia") {
|
||||
thresholdGlobal = 0.97;
|
||||
thresholdLocal = 0.2;
|
||||
}
|
||||
|
||||
if (similarityIndex < thresholdGlobal || worstTileValue < thresholdLocal) {
|
||||
if (!isInteractiveMode) {
|
||||
++numberOfFailures;
|
||||
appendTestResultsToFile(testResult, _mismatchWindow.getComparisonImage(), _mismatchWindow.getSSIMResultsImage(testResult._ssimResults), true);
|
||||
|
@ -258,11 +266,13 @@ void::TestCreator::appendTestResultsToFile(QString testResultFilename, bool hasF
|
|||
}
|
||||
}
|
||||
|
||||
void TestCreator::startTestsEvaluation(const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branchFromCommandLine,
|
||||
const QString& userFromCommandLine
|
||||
void TestCreator::startTestsEvaluation(
|
||||
QComboBox *gpuVendor,
|
||||
const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branchFromCommandLine,
|
||||
const QString& userFromCommandLine
|
||||
) {
|
||||
_isRunningFromCommandLine = isRunningFromCommandLine;
|
||||
_isRunningInAutomaticTestRun = isRunningInAutomaticTestRun;
|
||||
|
@ -332,12 +342,12 @@ void TestCreator::startTestsEvaluation(const bool isRunningFromCommandLine,
|
|||
}
|
||||
|
||||
_downloader->downloadFiles(expectedImagesURLs, _snapshotDirectory, _expectedImagesFilenames, (void *)this);
|
||||
finishTestsEvaluation();
|
||||
finishTestsEvaluation(gpuVendor->currentText());
|
||||
}
|
||||
|
||||
void TestCreator::finishTestsEvaluation() {
|
||||
void TestCreator::finishTestsEvaluation(const QString& gpuVendor) {
|
||||
// First - compare the pairs of images
|
||||
int numberOfFailures = compareImageLists();
|
||||
int numberOfFailures = compareImageLists(gpuVendor);
|
||||
|
||||
// Next - check text results
|
||||
numberOfFailures += checkTextResults();
|
||||
|
@ -430,8 +440,9 @@ void TestCreator::createTests(const QString& clientProfile) {
|
|||
parent += "/";
|
||||
}
|
||||
|
||||
_testsRootDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select test root folder", parent,
|
||||
QFileDialog::ShowDirsOnly);
|
||||
if (!createAllFilesSetup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If user canceled then restore previous selection and return
|
||||
if (_testsRootDirectory == "") {
|
||||
|
@ -881,23 +892,12 @@ void TestCreator::createRecursiveScript(const QString& directory, bool interacti
|
|||
}
|
||||
|
||||
void TestCreator::createTestsOutline() {
|
||||
QString previousSelection = _testDirectory;
|
||||
QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
|
||||
if (!parent.isNull() && parent.right(1) != "/") {
|
||||
parent += "/";
|
||||
}
|
||||
|
||||
_testDirectory =
|
||||
QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", parent, QFileDialog::ShowDirsOnly);
|
||||
|
||||
// If user canceled then restore previous selection and return
|
||||
if (_testDirectory == "") {
|
||||
_testDirectory = previousSelection;
|
||||
if (!createAllFilesSetup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString testsOutlineFilename { "testsOutline.md" };
|
||||
QString mdFilename(_testDirectory + "/" + testsOutlineFilename);
|
||||
QString mdFilename(_testsRootDirectory + "/" + testsOutlineFilename);
|
||||
QFile mdFile(mdFilename);
|
||||
if (!mdFile.open(QIODevice::WriteOnly)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + mdFilename);
|
||||
|
@ -911,10 +911,10 @@ void TestCreator::createTestsOutline() {
|
|||
stream << "Directories with an appended (*) have an automatic test\n\n";
|
||||
|
||||
// We need to know our current depth, as this isn't given by QDirIterator
|
||||
int rootDepth { _testDirectory.count('/') };
|
||||
int rootDepth { _testsRootDirectory.count('/') };
|
||||
|
||||
// Each test is shown as the folder name linking to the matching GitHub URL, and the path to the associated test.md file
|
||||
QDirIterator it(_testDirectory, QDirIterator::Subdirectories);
|
||||
QDirIterator it(_testsRootDirectory, QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
QString directory = it.next();
|
||||
|
||||
|
|
|
@ -45,13 +45,16 @@ class TestCreator {
|
|||
public:
|
||||
TestCreator(QProgressBar* progressBar, QCheckBox* checkBoxInteractiveMode);
|
||||
|
||||
void startTestsEvaluation(const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory = QString(),
|
||||
const QString& branchFromCommandLine = QString(),
|
||||
const QString& userFromCommandLine = QString());
|
||||
void startTestsEvaluation(
|
||||
QComboBox *gpuVendor,
|
||||
const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory = QString(),
|
||||
const QString& branchFromCommandLine = QString(),
|
||||
const QString& userFromCommandLine = QString()
|
||||
);
|
||||
|
||||
void finishTestsEvaluation();
|
||||
void finishTestsEvaluation(const QString& gpuVendor);
|
||||
|
||||
void createTests(const QString& clientProfile);
|
||||
|
||||
|
@ -79,7 +82,7 @@ public:
|
|||
void createRecursiveScript();
|
||||
void createRecursiveScript(const QString& directory, bool interactiveMode);
|
||||
|
||||
int compareImageLists();
|
||||
int compareImageLists(const QString& gpuVendor);
|
||||
int checkTextResults();
|
||||
|
||||
QStringList createListOfAll_imagesInDirectory(const QString& imageFormat, const QString& pathToImageDirectory);
|
||||
|
@ -124,9 +127,6 @@ private:
|
|||
const QString TEST_RESULTS_FOLDER { "TestResults" };
|
||||
const QString TEST_RESULTS_FILENAME { "TestResults.txt" };
|
||||
|
||||
const double THRESHOLD_GLOBAL{ 0.9995 };
|
||||
const double THRESHOLD_LOCAL { 0.6 };
|
||||
|
||||
QDir _imageDirectory;
|
||||
|
||||
MismatchWindow _mismatchWindow;
|
||||
|
|
|
@ -60,5 +60,5 @@ const double R_Y = 0.212655f;
|
|||
const double G_Y = 0.715158f;
|
||||
const double B_Y = 0.072187f;
|
||||
|
||||
const QString nitpickVersion{ "v3.1.5" };
|
||||
const QString nitpickVersion{ "v3.2.0" };
|
||||
#endif // hifi_common_h
|
|
@ -56,7 +56,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>40</y>
|
||||
<y>120</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -69,7 +69,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>180</y>
|
||||
<y>200</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -82,7 +82,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>180</y>
|
||||
<y>200</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -94,7 +94,7 @@
|
|||
<widget class="QPushButton" name="createTestsOutlinePushbutton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>210</x>
|
||||
<x>320</x>
|
||||
<y>120</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
|
@ -108,7 +108,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>300</y>
|
||||
<y>360</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -121,7 +121,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>300</y>
|
||||
<y>360</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -134,7 +134,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>240</y>
|
||||
<y>280</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -147,7 +147,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>240</y>
|
||||
<y>280</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -156,16 +156,6 @@
|
|||
<string>Create all testAuto scripts</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="clientProfileComboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>40</y>
|
||||
<width>120</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
|
@ -927,8 +917,8 @@
|
|||
<rect>
|
||||
<x>330</x>
|
||||
<y>190</y>
|
||||
<width>181</width>
|
||||
<height>51</height>
|
||||
<width>180</width>
|
||||
<height>50</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -1186,6 +1176,39 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="gpuVendorComboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>450</x>
|
||||
<y>60</y>
|
||||
<width>180</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>505</x>
|
||||
<y>40</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>GPU Vendor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
|
|
Loading…
Reference in a new issue