mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-12 17:55:01 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into model-scripting-1
This commit is contained in:
commit
35c38b8130
24 changed files with 272 additions and 269 deletions
|
@ -4385,16 +4385,16 @@ void Application::update(float deltaTime) {
|
|||
myAvatar->clearDriveKeys();
|
||||
if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
|
||||
if (!_controllerScriptingInterface->areActionsCaptured()) {
|
||||
myAvatar->setDriveKeys(TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z));
|
||||
myAvatar->setDriveKeys(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y));
|
||||
myAvatar->setDriveKeys(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X));
|
||||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z));
|
||||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y));
|
||||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X));
|
||||
if (deltaTime > FLT_EPSILON) {
|
||||
myAvatar->setDriveKeys(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH));
|
||||
myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW));
|
||||
myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW));
|
||||
myAvatar->setDriveKey(MyAvatar::PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH));
|
||||
myAvatar->setDriveKey(MyAvatar::YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW));
|
||||
myAvatar->setDriveKey(MyAvatar::STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW));
|
||||
}
|
||||
}
|
||||
myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z));
|
||||
myAvatar->setDriveKey(MyAvatar::ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z));
|
||||
}
|
||||
|
||||
controller::Pose leftHandPose = userInputMapper->getPoseState(controller::Action::LEFT_HAND);
|
||||
|
@ -5505,8 +5505,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
scriptEngine->registerGlobalObject("Rates", new RatesScriptingInterface(this));
|
||||
|
||||
// hook our avatar and avatar hash map object into this script engine
|
||||
scriptEngine->registerGlobalObject("MyAvatar", getMyAvatar().get());
|
||||
qScriptRegisterMetaType(scriptEngine, audioListenModeToScriptValue, audioListenModeFromScriptValue);
|
||||
getMyAvatar()->registerMetaTypes(scriptEngine);
|
||||
|
||||
scriptEngine->registerGlobalObject("AvatarList", DependencyManager::get<AvatarManager>().data());
|
||||
|
||||
|
|
|
@ -560,8 +560,6 @@ Menu::Menu() {
|
|||
false,
|
||||
&UserActivityLogger::getInstance(),
|
||||
SLOT(disable(bool)));
|
||||
addActionToQMenuAndActionHash(networkMenu, MenuOption::CachesSize, 0,
|
||||
dialogsManager.data(), SLOT(cachesSizeDialog()));
|
||||
addActionToQMenuAndActionHash(networkMenu, MenuOption::DiskCacheEditor, 0,
|
||||
dialogsManager.data(), SLOT(toggleDiskCacheEditor()));
|
||||
addActionToQMenuAndActionHash(networkMenu, MenuOption::ShowDSConnectTable, 0,
|
||||
|
|
|
@ -52,7 +52,6 @@ namespace MenuOption {
|
|||
const QString BinaryEyelidControl = "Binary Eyelid Control";
|
||||
const QString BookmarkLocation = "Bookmark Location";
|
||||
const QString Bookmarks = "Bookmarks";
|
||||
const QString CachesSize = "RAM Caches Size";
|
||||
const QString CalibrateCamera = "Calibrate Camera";
|
||||
const QString CameraEntityMode = "Entity Mode";
|
||||
const QString CenterPlayerInView = "Center Player In View";
|
||||
|
|
|
@ -119,9 +119,7 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
|||
using namespace recording;
|
||||
_skeletonModel->flagAsCauterized();
|
||||
|
||||
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
|
||||
_driveKeys[i] = 0.0f;
|
||||
}
|
||||
clearDriveKeys();
|
||||
|
||||
// Necessary to select the correct slot
|
||||
using SlotType = void(MyAvatar::*)(const glm::vec3&, bool, const glm::quat&, bool);
|
||||
|
@ -230,6 +228,21 @@ MyAvatar::~MyAvatar() {
|
|||
_lookAtTargetAvatar.reset();
|
||||
}
|
||||
|
||||
void MyAvatar::registerMetaTypes(QScriptEngine* engine) {
|
||||
QScriptValue value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects);
|
||||
engine->globalObject().setProperty("MyAvatar", value);
|
||||
|
||||
QScriptValue driveKeys = engine->newObject();
|
||||
auto metaEnum = QMetaEnum::fromType<DriveKeys>();
|
||||
for (int i = 0; i < MAX_DRIVE_KEYS; ++i) {
|
||||
driveKeys.setProperty(metaEnum.key(i), metaEnum.value(i));
|
||||
}
|
||||
engine->globalObject().setProperty("DriveKeys", driveKeys);
|
||||
|
||||
qScriptRegisterMetaType(engine, audioListenModeToScriptValue, audioListenModeFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, driveKeysToScriptValue, driveKeysFromScriptValue);
|
||||
}
|
||||
|
||||
void MyAvatar::setOrientationVar(const QVariant& newOrientationVar) {
|
||||
Avatar::setOrientation(quatFromVariant(newOrientationVar));
|
||||
}
|
||||
|
@ -462,7 +475,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
// When there are no step values, we zero out the last step pulse.
|
||||
// This allows a user to do faster snapping by tapping a control
|
||||
for (int i = STEP_TRANSLATE_X; !stepAction && i <= STEP_YAW; ++i) {
|
||||
if (_driveKeys[i] != 0.0f) {
|
||||
if (getDriveKey((DriveKeys)i) != 0.0f) {
|
||||
stepAction = true;
|
||||
}
|
||||
}
|
||||
|
@ -1655,7 +1668,7 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
|||
void MyAvatar::updateOrientation(float deltaTime) {
|
||||
|
||||
// Smoothly rotate body with arrow keys
|
||||
float targetSpeed = _driveKeys[YAW] * _yawSpeed;
|
||||
float targetSpeed = getDriveKey(YAW) * _yawSpeed;
|
||||
if (targetSpeed != 0.0f) {
|
||||
const float ROTATION_RAMP_TIMESCALE = 0.1f;
|
||||
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
|
||||
|
@ -1684,8 +1697,8 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
// Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll
|
||||
// get an instantaneous 15 degree turn. If you keep holding the key down you'll get another
|
||||
// snap turn every half second.
|
||||
if (_driveKeys[STEP_YAW] != 0.0f) {
|
||||
totalBodyYaw += _driveKeys[STEP_YAW];
|
||||
if (getDriveKey(STEP_YAW) != 0.0f) {
|
||||
totalBodyYaw += getDriveKey(STEP_YAW);
|
||||
}
|
||||
|
||||
// use head/HMD orientation to turn while flying
|
||||
|
@ -1722,7 +1735,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
// update body orientation by movement inputs
|
||||
setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))));
|
||||
|
||||
getHead()->setBasePitch(getHead()->getBasePitch() + _driveKeys[PITCH] * _pitchSpeed * deltaTime);
|
||||
getHead()->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime);
|
||||
|
||||
if (qApp->isHMDMode()) {
|
||||
glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation();
|
||||
|
@ -1756,14 +1769,14 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
}
|
||||
|
||||
// compute action input
|
||||
glm::vec3 front = (_driveKeys[TRANSLATE_Z]) * IDENTITY_FRONT;
|
||||
glm::vec3 right = (_driveKeys[TRANSLATE_X]) * IDENTITY_RIGHT;
|
||||
glm::vec3 front = (getDriveKey(TRANSLATE_Z)) * IDENTITY_FRONT;
|
||||
glm::vec3 right = (getDriveKey(TRANSLATE_X)) * IDENTITY_RIGHT;
|
||||
|
||||
glm::vec3 direction = front + right;
|
||||
CharacterController::State state = _characterController.getState();
|
||||
if (state == CharacterController::State::Hover) {
|
||||
// we're flying --> support vertical motion
|
||||
glm::vec3 up = (_driveKeys[TRANSLATE_Y]) * IDENTITY_UP;
|
||||
glm::vec3 up = (getDriveKey(TRANSLATE_Y)) * IDENTITY_UP;
|
||||
direction += up;
|
||||
}
|
||||
|
||||
|
@ -1802,7 +1815,7 @@ void MyAvatar::updateActionMotor(float deltaTime) {
|
|||
_actionMotorVelocity = MAX_WALKING_SPEED * direction;
|
||||
}
|
||||
|
||||
float boomChange = _driveKeys[ZOOM];
|
||||
float boomChange = getDriveKey(ZOOM);
|
||||
_boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange;
|
||||
_boomLength = glm::clamp<float>(_boomLength, ZOOM_MIN, ZOOM_MAX);
|
||||
}
|
||||
|
@ -1833,11 +1846,11 @@ void MyAvatar::updatePosition(float deltaTime) {
|
|||
}
|
||||
|
||||
// capture the head rotation, in sensor space, when the user first indicates they would like to move/fly.
|
||||
if (!_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) > 0.1f || fabs(_driveKeys[TRANSLATE_X]) > 0.1f)) {
|
||||
if (!_hoverReferenceCameraFacingIsCaptured && (fabs(getDriveKey(TRANSLATE_Z)) > 0.1f || fabs(getDriveKey(TRANSLATE_X)) > 0.1f)) {
|
||||
_hoverReferenceCameraFacingIsCaptured = true;
|
||||
// transform the camera facing vector into sensor space.
|
||||
_hoverReferenceCameraFacing = transformVectorFast(glm::inverse(_sensorToWorldMatrix), getHead()->getCameraOrientation() * Vectors::UNIT_Z);
|
||||
} else if (_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) <= 0.1f && fabs(_driveKeys[TRANSLATE_X]) <= 0.1f)) {
|
||||
} else if (_hoverReferenceCameraFacingIsCaptured && (fabs(getDriveKey(TRANSLATE_Z)) <= 0.1f && fabs(getDriveKey(TRANSLATE_X)) <= 0.1f)) {
|
||||
_hoverReferenceCameraFacingIsCaptured = false;
|
||||
}
|
||||
}
|
||||
|
@ -2093,17 +2106,61 @@ bool MyAvatar::getCharacterControllerEnabled() {
|
|||
}
|
||||
|
||||
void MyAvatar::clearDriveKeys() {
|
||||
for (int i = 0; i < MAX_DRIVE_KEYS; ++i) {
|
||||
_driveKeys[i] = 0.0f;
|
||||
_driveKeys.fill(0.0f);
|
||||
}
|
||||
|
||||
void MyAvatar::setDriveKey(DriveKeys key, float val) {
|
||||
try {
|
||||
_driveKeys.at(key) = val;
|
||||
} catch (const std::exception&) {
|
||||
qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds";
|
||||
}
|
||||
}
|
||||
|
||||
float MyAvatar::getDriveKey(DriveKeys key) const {
|
||||
return isDriveKeyDisabled(key) ? 0.0f : getRawDriveKey(key);
|
||||
}
|
||||
|
||||
float MyAvatar::getRawDriveKey(DriveKeys key) const {
|
||||
try {
|
||||
return _driveKeys.at(key);
|
||||
} catch (const std::exception&) {
|
||||
qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds";
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::relayDriveKeysToCharacterController() {
|
||||
if (_driveKeys[TRANSLATE_Y] > 0.0f) {
|
||||
if (getDriveKey(TRANSLATE_Y) > 0.0f) {
|
||||
_characterController.jump();
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::disableDriveKey(DriveKeys key) {
|
||||
try {
|
||||
_disabledDriveKeys.set(key);
|
||||
} catch (const std::exception&) {
|
||||
qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds";
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::enableDriveKey(DriveKeys key) {
|
||||
try {
|
||||
_disabledDriveKeys.reset(key);
|
||||
} catch (const std::exception&) {
|
||||
qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds";
|
||||
}
|
||||
}
|
||||
|
||||
bool MyAvatar::isDriveKeyDisabled(DriveKeys key) const {
|
||||
try {
|
||||
return _disabledDriveKeys.test(key);
|
||||
} catch (const std::exception&) {
|
||||
qCCritical(interfaceapp) << Q_FUNC_INFO << ": Index out of bounds";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::getWorldBodyPosition() const {
|
||||
return transformPoint(_sensorToWorldMatrix, extractTranslation(_bodySensorMatrix));
|
||||
}
|
||||
|
@ -2189,7 +2246,15 @@ QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioList
|
|||
}
|
||||
|
||||
void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) {
|
||||
audioListenerMode = (AudioListenerMode)object.toUInt16();
|
||||
audioListenerMode = static_cast<AudioListenerMode>(object.toUInt16());
|
||||
}
|
||||
|
||||
QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys) {
|
||||
return driveKeys;
|
||||
}
|
||||
|
||||
void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys) {
|
||||
driveKeys = static_cast<MyAvatar::DriveKeys>(object.toUInt16());
|
||||
}
|
||||
|
||||
|
||||
|
@ -2382,7 +2447,7 @@ bool MyAvatar::didTeleport() {
|
|||
}
|
||||
|
||||
bool MyAvatar::hasDriveInput() const {
|
||||
return fabsf(_driveKeys[TRANSLATE_X]) > 0.0f || fabsf(_driveKeys[TRANSLATE_Y]) > 0.0f || fabsf(_driveKeys[TRANSLATE_Z]) > 0.0f;
|
||||
return fabsf(getDriveKey(TRANSLATE_X)) > 0.0f || fabsf(getDriveKey(TRANSLATE_Y)) > 0.0f || fabsf(getDriveKey(TRANSLATE_Z)) > 0.0f;
|
||||
}
|
||||
|
||||
void MyAvatar::setAway(bool value) {
|
||||
|
@ -2498,7 +2563,7 @@ bool MyAvatar::pinJoint(int index, const glm::vec3& position, const glm::quat& o
|
|||
return false;
|
||||
}
|
||||
|
||||
setPosition(position);
|
||||
slamPosition(position);
|
||||
setOrientation(orientation);
|
||||
|
||||
_rig->setMaxHipsOffsetLength(0.05f);
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef hifi_MyAvatar_h
|
||||
#define hifi_MyAvatar_h
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <SettingHandle.h>
|
||||
|
@ -29,20 +31,6 @@
|
|||
class AvatarActionHold;
|
||||
class ModelItemID;
|
||||
|
||||
enum DriveKeys {
|
||||
TRANSLATE_X = 0,
|
||||
TRANSLATE_Y,
|
||||
TRANSLATE_Z,
|
||||
YAW,
|
||||
STEP_TRANSLATE_X,
|
||||
STEP_TRANSLATE_Y,
|
||||
STEP_TRANSLATE_Z,
|
||||
STEP_YAW,
|
||||
PITCH,
|
||||
ZOOM,
|
||||
MAX_DRIVE_KEYS
|
||||
};
|
||||
|
||||
enum eyeContactTarget {
|
||||
LEFT_EYE,
|
||||
RIGHT_EYE,
|
||||
|
@ -88,9 +76,26 @@ class MyAvatar : public Avatar {
|
|||
Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled)
|
||||
|
||||
public:
|
||||
enum DriveKeys {
|
||||
TRANSLATE_X = 0,
|
||||
TRANSLATE_Y,
|
||||
TRANSLATE_Z,
|
||||
YAW,
|
||||
STEP_TRANSLATE_X,
|
||||
STEP_TRANSLATE_Y,
|
||||
STEP_TRANSLATE_Z,
|
||||
STEP_YAW,
|
||||
PITCH,
|
||||
ZOOM,
|
||||
MAX_DRIVE_KEYS
|
||||
};
|
||||
Q_ENUM(DriveKeys)
|
||||
|
||||
explicit MyAvatar(RigPointer rig);
|
||||
~MyAvatar();
|
||||
|
||||
void registerMetaTypes(QScriptEngine* engine);
|
||||
|
||||
virtual void simulateAttachments(float deltaTime) override;
|
||||
|
||||
AudioListenerMode getAudioListenerModeHead() const { return FROM_HEAD; }
|
||||
|
@ -180,9 +185,15 @@ public:
|
|||
|
||||
// Set what driving keys are being pressed to control thrust levels
|
||||
void clearDriveKeys();
|
||||
void setDriveKeys(int key, float val) { _driveKeys[key] = val; };
|
||||
void setDriveKey(DriveKeys key, float val);
|
||||
float getDriveKey(DriveKeys key) const;
|
||||
Q_INVOKABLE float getRawDriveKey(DriveKeys key) const;
|
||||
void relayDriveKeysToCharacterController();
|
||||
|
||||
Q_INVOKABLE void disableDriveKey(DriveKeys key);
|
||||
Q_INVOKABLE void enableDriveKey(DriveKeys key);
|
||||
Q_INVOKABLE bool isDriveKeyDisabled(DriveKeys key) const;
|
||||
|
||||
eyeContactTarget getEyeContactTarget();
|
||||
|
||||
Q_INVOKABLE glm::vec3 getTrackedHeadPosition() const { return _trackedHeadPosition; }
|
||||
|
@ -352,7 +363,6 @@ private:
|
|||
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override;
|
||||
void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; setEnableMeshVisible(shouldRender); }
|
||||
bool getShouldRenderLocally() const { return _shouldRender; }
|
||||
bool getDriveKeys(int key) { return _driveKeys[key] != 0.0f; };
|
||||
bool isMyAvatar() const override { return true; }
|
||||
virtual int parseDataFromBuffer(const QByteArray& buffer) override;
|
||||
virtual glm::vec3 getSkeletonPosition() const override;
|
||||
|
@ -388,7 +398,9 @@ private:
|
|||
void clampScaleChangeToDomainLimits(float desiredScale);
|
||||
glm::mat4 computeCameraRelativeHandControllerMatrix(const glm::mat4& controllerSensorMatrix) const;
|
||||
|
||||
float _driveKeys[MAX_DRIVE_KEYS];
|
||||
std::array<float, MAX_DRIVE_KEYS> _driveKeys;
|
||||
std::bitset<MAX_DRIVE_KEYS> _disabledDriveKeys;
|
||||
|
||||
bool _wasPushing;
|
||||
bool _isPushing;
|
||||
bool _isBeingPushed;
|
||||
|
@ -541,4 +553,7 @@ private:
|
|||
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);
|
||||
void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode);
|
||||
|
||||
QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys);
|
||||
void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys);
|
||||
|
||||
#endif // hifi_MyAvatar_h
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
//
|
||||
// CachesSizeDialog.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/12/15.
|
||||
// Copyright 2015 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 <QDoubleSpinBox>
|
||||
#include <QFormLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
#include <AnimationCache.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <SoundCache.h>
|
||||
#include <TextureCache.h>
|
||||
|
||||
#include "CachesSizeDialog.h"
|
||||
|
||||
|
||||
QDoubleSpinBox* createDoubleSpinBox(QWidget* parent) {
|
||||
QDoubleSpinBox* box = new QDoubleSpinBox(parent);
|
||||
box->setDecimals(0);
|
||||
box->setRange(MIN_UNUSED_MAX_SIZE / BYTES_PER_MEGABYTES, MAX_UNUSED_MAX_SIZE / BYTES_PER_MEGABYTES);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
CachesSizeDialog::CachesSizeDialog(QWidget* parent) :
|
||||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint)
|
||||
{
|
||||
setWindowTitle("Caches Size");
|
||||
|
||||
// Create layouter
|
||||
QFormLayout* form = new QFormLayout(this);
|
||||
setLayout(form);
|
||||
|
||||
form->addRow("Animations cache size (MB):", _animations = createDoubleSpinBox(this));
|
||||
form->addRow("Geometries cache size (MB):", _geometries = createDoubleSpinBox(this));
|
||||
form->addRow("Sounds cache size (MB):", _sounds = createDoubleSpinBox(this));
|
||||
form->addRow("Textures cache size (MB):", _textures = createDoubleSpinBox(this));
|
||||
|
||||
resetClicked(true);
|
||||
|
||||
// Add a button to reset
|
||||
QPushButton* confirmButton = new QPushButton("Confirm", this);
|
||||
QPushButton* resetButton = new QPushButton("Reset", this);
|
||||
form->addRow(confirmButton, resetButton);
|
||||
connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(confirmClicked(bool)));
|
||||
connect(resetButton, SIGNAL(clicked(bool)), this, SLOT(resetClicked(bool)));
|
||||
}
|
||||
|
||||
void CachesSizeDialog::confirmClicked(bool checked) {
|
||||
DependencyManager::get<AnimationCache>()->setUnusedResourceCacheSize(_animations->value() * BYTES_PER_MEGABYTES);
|
||||
DependencyManager::get<ModelCache>()->setUnusedResourceCacheSize(_geometries->value() * BYTES_PER_MEGABYTES);
|
||||
DependencyManager::get<SoundCache>()->setUnusedResourceCacheSize(_sounds->value() * BYTES_PER_MEGABYTES);
|
||||
// Disabling the texture cache because it's a liability in cases where we're overcommiting GPU memory
|
||||
#if 0
|
||||
DependencyManager::get<TextureCache>()->setUnusedResourceCacheSize(_textures->value() * BYTES_PER_MEGABYTES);
|
||||
#endif
|
||||
|
||||
QDialog::close();
|
||||
}
|
||||
|
||||
void CachesSizeDialog::resetClicked(bool checked) {
|
||||
_animations->setValue(DependencyManager::get<AnimationCache>()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES);
|
||||
_geometries->setValue(DependencyManager::get<ModelCache>()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES);
|
||||
_sounds->setValue(DependencyManager::get<SoundCache>()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES);
|
||||
_textures->setValue(DependencyManager::get<TextureCache>()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES);
|
||||
}
|
||||
|
||||
void CachesSizeDialog::reject() {
|
||||
// Just regularly close upon ESC
|
||||
QDialog::close();
|
||||
}
|
||||
|
||||
void CachesSizeDialog::closeEvent(QCloseEvent* event) {
|
||||
QDialog::closeEvent(event);
|
||||
emit closed();
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
//
|
||||
// CachesSizeDialog.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 1/12/15.
|
||||
// Copyright 2015 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_CachesSizeDialog_h
|
||||
#define hifi_CachesSizeDialog_h
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QDoubleSpinBox;
|
||||
|
||||
class CachesSizeDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Sets up the UI
|
||||
CachesSizeDialog(QWidget* parent);
|
||||
|
||||
signals:
|
||||
void closed();
|
||||
|
||||
public slots:
|
||||
void reject() override;
|
||||
void confirmClicked(bool checked);
|
||||
void resetClicked(bool checked);
|
||||
|
||||
protected:
|
||||
// Emits a 'closed' signal when this dialog is closed.
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
private:
|
||||
QDoubleSpinBox* _animations = nullptr;
|
||||
QDoubleSpinBox* _geometries = nullptr;
|
||||
QDoubleSpinBox* _scripts = nullptr;
|
||||
QDoubleSpinBox* _sounds = nullptr;
|
||||
QDoubleSpinBox* _textures = nullptr;
|
||||
};
|
||||
|
||||
#endif // hifi_CachesSizeDialog_h
|
|
@ -19,7 +19,6 @@
|
|||
#include <PathUtils.h>
|
||||
|
||||
#include "AddressBarDialog.h"
|
||||
#include "CachesSizeDialog.h"
|
||||
#include "ConnectionFailureDialog.h"
|
||||
#include "DiskCacheEditor.h"
|
||||
#include "DomainConnectionDialog.h"
|
||||
|
@ -97,16 +96,6 @@ void DialogsManager::octreeStatsDetails() {
|
|||
_octreeStatsDialog->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::cachesSizeDialog() {
|
||||
if (!_cachesSizeDialog) {
|
||||
maybeCreateDialog(_cachesSizeDialog);
|
||||
|
||||
connect(_cachesSizeDialog, SIGNAL(closed()), _cachesSizeDialog, SLOT(deleteLater()));
|
||||
_cachesSizeDialog->show();
|
||||
}
|
||||
_cachesSizeDialog->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::lodTools() {
|
||||
if (!_lodToolsDialog) {
|
||||
maybeCreateDialog(_lodToolsDialog);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
class AnimationsDialog;
|
||||
class AttachmentsDialog;
|
||||
class CachesSizeDialog;
|
||||
class DiskCacheEditor;
|
||||
class LodToolsDialog;
|
||||
class OctreeStatsDialog;
|
||||
|
@ -50,7 +49,6 @@ public slots:
|
|||
void toggleLoginDialog();
|
||||
void showLoginDialog();
|
||||
void octreeStatsDetails();
|
||||
void cachesSizeDialog();
|
||||
void lodTools();
|
||||
void hmdTools(bool showTools);
|
||||
void showScriptEditor();
|
||||
|
@ -76,7 +74,6 @@ private:
|
|||
|
||||
QPointer<AnimationsDialog> _animationsDialog;
|
||||
QPointer<AttachmentsDialog> _attachmentsDialog;
|
||||
QPointer<CachesSizeDialog> _cachesSizeDialog;
|
||||
QPointer<DiskCacheEditor> _diskCacheEditor;
|
||||
QPointer<QMessageBox> _ircInfoBox;
|
||||
QPointer<HMDToolsDialog> _hmdToolsDialog;
|
||||
|
|
|
@ -160,7 +160,7 @@ AudioClient::AudioClient() :
|
|||
_loopbackAudioOutput(NULL),
|
||||
_loopbackOutputDevice(NULL),
|
||||
_inputRingBuffer(0),
|
||||
_localInjectorsStream(0),
|
||||
_localInjectorsStream(0, 1),
|
||||
_receivedAudioStream(RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES),
|
||||
_isStereoInput(false),
|
||||
_outputStarveDetectionStartTimeMsec(0),
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
#include "PhysicalEntitySimulation.h"
|
||||
|
||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
|
||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_wireframePipeline = nullptr;
|
||||
|
||||
const float MARCHING_CUBE_COLLISION_HULL_OFFSET = 0.5;
|
||||
|
||||
|
||||
|
@ -705,7 +707,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
!mesh->getIndexBuffer()._buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!_pipeline) {
|
||||
gpu::ShaderPointer vertexShader = gpu::Shader::createVertex(std::string(polyvox_vert));
|
||||
gpu::ShaderPointer pixelShader = gpu::Shader::createPixel(std::string(polyvox_frag));
|
||||
|
@ -724,6 +726,13 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
|
||||
_pipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
auto wireframeState = std::make_shared<gpu::State>();
|
||||
wireframeState->setCullMode(gpu::State::CULL_BACK);
|
||||
wireframeState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
wireframeState->setFillMode(gpu::State::FILL_LINE);
|
||||
|
||||
_wireframePipeline = gpu::Pipeline::create(program, wireframeState);
|
||||
}
|
||||
|
||||
if (!_vertexFormat) {
|
||||
|
@ -734,7 +743,11 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
batch.setPipeline(_pipeline);
|
||||
|
||||
// Pick correct Pipeline
|
||||
bool wireframe = (render::ShapeKey(args->_globalShapeKey).isWireframe());
|
||||
auto pipeline = (wireframe ? _wireframePipeline : _pipeline);
|
||||
batch.setPipeline(pipeline);
|
||||
|
||||
Transform transform(voxelToWorldMatrix());
|
||||
batch.setModelTransform(transform);
|
||||
|
@ -771,7 +784,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
batch.setResourceTexture(2, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
|
||||
int voxelVolumeSizeLocation = _pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize");
|
||||
int voxelVolumeSizeLocation = pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize");
|
||||
batch._glUniform3f(voxelVolumeSizeLocation, voxelVolumeSize.x, voxelVolumeSize.y, voxelVolumeSize.z);
|
||||
|
||||
batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)mesh->getNumIndices(), 0);
|
||||
|
|
|
@ -164,6 +164,7 @@ private:
|
|||
const int MATERIAL_GPU_SLOT = 3;
|
||||
render::ItemID _myItem{ render::Item::INVALID_ITEM_ID };
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
static gpu::PipelinePointer _wireframePipeline;
|
||||
|
||||
ShapeInfo _shapeInfo;
|
||||
|
||||
|
|
|
@ -114,13 +114,22 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
|
|||
auto outColor = _procedural->getColor(color);
|
||||
outColor.a *= _procedural->isFading() ? Interpolate::calculateFadeRatio(_procedural->getFadeStartTime()) : 1.0f;
|
||||
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
||||
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||
DependencyManager::get<GeometryCache>()->renderWireShape(batch, MAPPING[_shape]);
|
||||
} else {
|
||||
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
|
||||
}
|
||||
} else {
|
||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||
color.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = color.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||
geometryCache->renderSolidShapeInstance(batch, MAPPING[_shape], color, pipeline);
|
||||
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||
geometryCache->renderWireShapeInstance(batch, MAPPING[_shape], color, pipeline);
|
||||
} else {
|
||||
geometryCache->renderSolidShapeInstance(batch, MAPPING[_shape], color, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(MAPPING[_shape]);
|
||||
|
|
|
@ -71,7 +71,6 @@ bool writeOBJToTextStream(QTextStream& out, QList<MeshPointer> meshes) {
|
|||
|
||||
const gpu::BufferView& partBuffer = mesh->getPartBuffer();
|
||||
const gpu::BufferView& indexBuffer = mesh->getIndexBuffer();
|
||||
// const gpu::BufferView& vertexBuffer = mesh->getVertexBuffer();
|
||||
|
||||
model::Index partCount = (model::Index)mesh->getNumParts();
|
||||
for (int partIndex = 0; partIndex < partCount; partIndex++) {
|
||||
|
|
|
@ -133,6 +133,7 @@ void LightingModel::setSpotLight(bool enable) {
|
|||
bool LightingModel::isSpotLightEnabled() const {
|
||||
return (bool)_parametersBuffer.get<Parameters>().enableSpotLight;
|
||||
}
|
||||
|
||||
void LightingModel::setShowLightContour(bool enable) {
|
||||
if (enable != isShowLightContourEnabled()) {
|
||||
_parametersBuffer.edit<Parameters>().showLightContour = (float)enable;
|
||||
|
@ -142,6 +143,14 @@ bool LightingModel::isShowLightContourEnabled() const {
|
|||
return (bool)_parametersBuffer.get<Parameters>().showLightContour;
|
||||
}
|
||||
|
||||
void LightingModel::setWireframe(bool enable) {
|
||||
if (enable != isWireframeEnabled()) {
|
||||
_parametersBuffer.edit<Parameters>().enableWireframe = (float)enable;
|
||||
}
|
||||
}
|
||||
bool LightingModel::isWireframeEnabled() const {
|
||||
return (bool)_parametersBuffer.get<Parameters>().enableWireframe;
|
||||
}
|
||||
MakeLightingModel::MakeLightingModel() {
|
||||
_lightingModel = std::make_shared<LightingModel>();
|
||||
}
|
||||
|
@ -167,6 +176,7 @@ void MakeLightingModel::configure(const Config& config) {
|
|||
_lightingModel->setSpotLight(config.enableSpotLight);
|
||||
|
||||
_lightingModel->setShowLightContour(config.showLightContour);
|
||||
_lightingModel->setWireframe(config.enableWireframe);
|
||||
}
|
||||
|
||||
void MakeLightingModel::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, LightingModelPointer& lightingModel) {
|
||||
|
|
|
@ -64,6 +64,9 @@ public:
|
|||
void setShowLightContour(bool enable);
|
||||
bool isShowLightContourEnabled() const;
|
||||
|
||||
void setWireframe(bool enable);
|
||||
bool isWireframeEnabled() const;
|
||||
|
||||
UniformBufferView getParametersBuffer() const { return _parametersBuffer; }
|
||||
|
||||
protected:
|
||||
|
@ -89,13 +92,12 @@ protected:
|
|||
float enablePointLight{ 1.0f };
|
||||
float enableSpotLight{ 1.0f };
|
||||
|
||||
float showLightContour{ 0.0f }; // false by default
|
||||
float showLightContour { 0.0f }; // false by default
|
||||
|
||||
float enableObscurance{ 1.0f };
|
||||
|
||||
float enableMaterialTexturing { 1.0f };
|
||||
|
||||
float spares{ 0.0f };
|
||||
float enableWireframe { 0.0f }; // false by default
|
||||
|
||||
Parameters() {}
|
||||
};
|
||||
|
@ -129,6 +131,7 @@ class MakeLightingModelConfig : public render::Job::Config {
|
|||
Q_PROPERTY(bool enablePointLight MEMBER enablePointLight NOTIFY dirty)
|
||||
Q_PROPERTY(bool enableSpotLight MEMBER enableSpotLight NOTIFY dirty)
|
||||
|
||||
Q_PROPERTY(bool enableWireframe MEMBER enableWireframe NOTIFY dirty)
|
||||
Q_PROPERTY(bool showLightContour MEMBER showLightContour NOTIFY dirty)
|
||||
|
||||
public:
|
||||
|
@ -152,9 +155,10 @@ public:
|
|||
bool enablePointLight{ true };
|
||||
bool enableSpotLight{ true };
|
||||
|
||||
|
||||
bool showLightContour { false }; // false by default
|
||||
|
||||
bool enableWireframe { false }; // false by default
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@ struct LightingModel {
|
|||
vec4 _UnlitEmissiveLightmapBackground;
|
||||
vec4 _ScatteringDiffuseSpecularAlbedo;
|
||||
vec4 _AmbientDirectionalPointSpot;
|
||||
vec4 _ShowContourObscuranceSpare2;
|
||||
vec4 _ShowContourObscuranceWireframe;
|
||||
};
|
||||
|
||||
uniform lightingModelBuffer{
|
||||
|
@ -37,7 +37,7 @@ float isBackgroundEnabled() {
|
|||
return lightingModel._UnlitEmissiveLightmapBackground.w;
|
||||
}
|
||||
float isObscuranceEnabled() {
|
||||
return lightingModel._ShowContourObscuranceSpare2.y;
|
||||
return lightingModel._ShowContourObscuranceWireframe.y;
|
||||
}
|
||||
|
||||
float isScatteringEnabled() {
|
||||
|
@ -67,9 +67,12 @@ float isSpotEnabled() {
|
|||
}
|
||||
|
||||
float isShowLightContour() {
|
||||
return lightingModel._ShowContourObscuranceSpare2.x;
|
||||
return lightingModel._ShowContourObscuranceWireframe.x;
|
||||
}
|
||||
|
||||
float isWireframeEnabled() {
|
||||
return lightingModel._ShowContourObscuranceWireframe.z;
|
||||
}
|
||||
|
||||
<@endfunc@>
|
||||
<$declareLightingModel()$>
|
||||
|
|
|
@ -259,8 +259,18 @@ void DrawDeferred::run(const SceneContextPointer& sceneContext, const RenderCont
|
|||
// Setup lighting model for all items;
|
||||
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
||||
|
||||
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn);
|
||||
// From the lighting model define a global shapKey ORED with individiual keys
|
||||
ShapeKey::Builder keyBuilder;
|
||||
if (lightingModel->isWireframeEnabled()) {
|
||||
keyBuilder.withWireframe();
|
||||
}
|
||||
ShapeKey globalKey = keyBuilder.build();
|
||||
args->_globalShapeKey = globalKey._flags.to_ulong();
|
||||
|
||||
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn, globalKey);
|
||||
|
||||
args->_batch = nullptr;
|
||||
args->_globalShapeKey = 0;
|
||||
});
|
||||
|
||||
config->setNumDrawn((int)inItems.size());
|
||||
|
@ -295,12 +305,21 @@ void DrawStateSortDeferred::run(const SceneContextPointer& sceneContext, const R
|
|||
// Setup lighting model for all items;
|
||||
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
||||
|
||||
// From the lighting model define a global shapKey ORED with individiual keys
|
||||
ShapeKey::Builder keyBuilder;
|
||||
if (lightingModel->isWireframeEnabled()) {
|
||||
keyBuilder.withWireframe();
|
||||
}
|
||||
ShapeKey globalKey = keyBuilder.build();
|
||||
args->_globalShapeKey = globalKey._flags.to_ulong();
|
||||
|
||||
if (_stateSort) {
|
||||
renderStateSortShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn);
|
||||
renderStateSortShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn, globalKey);
|
||||
} else {
|
||||
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn);
|
||||
renderShapes(sceneContext, renderContext, _shapePlumber, inItems, _maxDrawn, globalKey);
|
||||
}
|
||||
args->_batch = nullptr;
|
||||
args->_globalShapeKey = 0;
|
||||
});
|
||||
|
||||
config->setNumDrawn((int)inItems.size());
|
||||
|
|
|
@ -39,9 +39,9 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo
|
|||
}
|
||||
}
|
||||
|
||||
void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item) {
|
||||
void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, const Item& item, const ShapeKey& globalKey) {
|
||||
assert(item.getKey().isShape());
|
||||
const auto& key = item.getShapeKey();
|
||||
auto key = item.getShapeKey() | globalKey;
|
||||
if (key.isValid() && !key.hasOwnPipeline()) {
|
||||
args->_pipeline = shapeContext->pickPipeline(args, key);
|
||||
if (args->_pipeline) {
|
||||
|
@ -56,7 +56,7 @@ void renderShape(RenderArgs* args, const ShapePlumberPointer& shapeContext, cons
|
|||
}
|
||||
|
||||
void render::renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||
const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems) {
|
||||
const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems, const ShapeKey& globalKey) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
@ -66,12 +66,12 @@ void render::renderShapes(const SceneContextPointer& sceneContext, const RenderC
|
|||
}
|
||||
for (auto i = 0; i < numItemsToDraw; ++i) {
|
||||
auto& item = scene->getItem(inItems[i].id);
|
||||
renderShape(args, shapeContext, item);
|
||||
renderShape(args, shapeContext, item, globalKey);
|
||||
}
|
||||
}
|
||||
|
||||
void render::renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext,
|
||||
const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems) {
|
||||
const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems, const ShapeKey& globalKey) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
@ -91,7 +91,7 @@ void render::renderStateSortShapes(const SceneContextPointer& sceneContext, cons
|
|||
|
||||
{
|
||||
assert(item.getKey().isShape());
|
||||
const auto key = item.getShapeKey();
|
||||
auto key = item.getShapeKey() | globalKey;
|
||||
if (key.isValid() && !key.hasOwnPipeline()) {
|
||||
auto& bucket = sortedShapes[key];
|
||||
if (bucket.empty()) {
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
namespace render {
|
||||
|
||||
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, int maxDrawnItems = -1);
|
||||
void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1);
|
||||
void renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1);
|
||||
void renderShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1, const ShapeKey& globalKey = ShapeKey());
|
||||
void renderStateSortShapes(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapePlumberPointer& shapeContext, const ItemBounds& inItems, int maxDrawnItems = -1, const ShapeKey& globalKey = ShapeKey());
|
||||
|
||||
class DrawLightConfig : public Job::Config {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -46,6 +46,10 @@ public:
|
|||
ShapeKey() : _flags{ 0 } {}
|
||||
ShapeKey(const Flags& flags) : _flags{flags} {}
|
||||
|
||||
friend ShapeKey operator&(const ShapeKey& _Left, const ShapeKey& _Right) { return ShapeKey(_Left._flags & _Right._flags); }
|
||||
friend ShapeKey operator|(const ShapeKey& _Left, const ShapeKey& _Right) { return ShapeKey(_Left._flags | _Right._flags); }
|
||||
friend ShapeKey operator^(const ShapeKey& _Left, const ShapeKey& _Right) { return ShapeKey(_Left._flags ^ _Right._flags); }
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
Builder() {}
|
||||
|
@ -144,7 +148,7 @@ public:
|
|||
bool isSkinned() const { return _flags[SKINNED]; }
|
||||
bool isDepthOnly() const { return _flags[DEPTH_ONLY]; }
|
||||
bool isDepthBiased() const { return _flags[DEPTH_BIAS]; }
|
||||
bool isWireFrame() const { return _flags[WIREFRAME]; }
|
||||
bool isWireframe() const { return _flags[WIREFRAME]; }
|
||||
bool isCullFace() const { return !_flags[NO_CULL_FACE]; }
|
||||
|
||||
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
|
||||
|
@ -180,7 +184,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
|
|||
<< "isSkinned:" << key.isSkinned()
|
||||
<< "isDepthOnly:" << key.isDepthOnly()
|
||||
<< "isDepthBiased:" << key.isDepthBiased()
|
||||
<< "isWireFrame:" << key.isWireFrame()
|
||||
<< "isWireframe:" << key.isWireframe()
|
||||
<< "isCullFace:" << key.isCullFace()
|
||||
<< "]";
|
||||
}
|
||||
|
|
|
@ -122,6 +122,7 @@ public:
|
|||
gpu::Batch* _batch = nullptr;
|
||||
|
||||
std::shared_ptr<gpu::Texture> _whiteTexture;
|
||||
uint32_t _globalShapeKey { 0 };
|
||||
bool _enableTexturing { true };
|
||||
|
||||
RenderDetails _details;
|
||||
|
|
|
@ -25,7 +25,7 @@ Column {
|
|||
"Lightmap:LightingModel:enableLightmap",
|
||||
"Background:LightingModel:enableBackground",
|
||||
"ssao:AmbientOcclusion:enabled",
|
||||
"Textures:LightingModel:enableMaterialTexturing",
|
||||
"Textures:LightingModel:enableMaterialTexturing"
|
||||
]
|
||||
CheckBox {
|
||||
text: modelData.split(":")[0]
|
||||
|
@ -45,6 +45,7 @@ Column {
|
|||
"Diffuse:LightingModel:enableDiffuse",
|
||||
"Specular:LightingModel:enableSpecular",
|
||||
"Albedo:LightingModel:enableAlbedo",
|
||||
"Wireframe:LightingModel:enableWireframe"
|
||||
]
|
||||
CheckBox {
|
||||
text: modelData.split(":")[0]
|
||||
|
|
|
@ -6,26 +6,35 @@
|
|||
var ANIMATION_FPS = 30;
|
||||
var ANIMATION_FIRST_FRAME = 1;
|
||||
var ANIMATION_LAST_FRAME = 10;
|
||||
var RELEASE_KEYS = ['w', 'a', 's', 'd', 'UP', 'LEFT', 'DOWN', 'RIGHT'];
|
||||
var RELEASE_TIME = 500; // ms
|
||||
var RELEASE_DISTANCE = 0.2; // meters
|
||||
var MAX_IK_ERROR = 30;
|
||||
var IK_SETTLE_TIME = 250; // ms
|
||||
var DESKTOP_UI_CHECK_INTERVAL = 100;
|
||||
var DESKTOP_MAX_DISTANCE = 5;
|
||||
var SIT_DELAY = 25
|
||||
var MAX_RESET_DISTANCE = 0.5
|
||||
var SIT_DELAY = 25;
|
||||
var MAX_RESET_DISTANCE = 0.5; // meters
|
||||
var OVERRIDEN_DRIVE_KEYS = [
|
||||
DriveKeys.TRANSLATE_X,
|
||||
DriveKeys.TRANSLATE_Y,
|
||||
DriveKeys.TRANSLATE_Z,
|
||||
DriveKeys.STEP_TRANSLATE_X,
|
||||
DriveKeys.STEP_TRANSLATE_Y,
|
||||
DriveKeys.STEP_TRANSLATE_Z,
|
||||
];
|
||||
|
||||
this.entityID = null;
|
||||
this.timers = {};
|
||||
this.animStateHandlerID = null;
|
||||
this.interval = null;
|
||||
this.sitDownSettlePeriod = null;
|
||||
this.lastTimeNoDriveKeys = null;
|
||||
|
||||
this.preload = function(entityID) {
|
||||
this.entityID = entityID;
|
||||
}
|
||||
this.unload = function() {
|
||||
if (Settings.getValue(SETTING_KEY) === this.entityID) {
|
||||
this.sitUp();
|
||||
this.standUp();
|
||||
}
|
||||
if (this.interval !== null) {
|
||||
Script.clearInterval(this.interval);
|
||||
|
@ -96,6 +105,11 @@
|
|||
print("Someone is already sitting in that chair.");
|
||||
return;
|
||||
}
|
||||
print("Sitting down (" + this.entityID + ")");
|
||||
|
||||
var now = Date.now();
|
||||
this.sitDownSettlePeriod = now + IK_SETTLE_TIME;
|
||||
this.lastTimeNoDriveKeys = now;
|
||||
|
||||
var previousValue = Settings.getValue(SETTING_KEY);
|
||||
Settings.setValue(SETTING_KEY, this.entityID);
|
||||
|
@ -118,20 +132,17 @@
|
|||
return { headType: 0 };
|
||||
}, ["headType"]);
|
||||
Script.update.connect(this, this.update);
|
||||
Controller.keyPressEvent.connect(this, this.keyPressed);
|
||||
Controller.keyReleaseEvent.connect(this, this.keyReleased);
|
||||
for (var i in RELEASE_KEYS) {
|
||||
Controller.captureKeyEvents({ text: RELEASE_KEYS[i] });
|
||||
for (var i in OVERRIDEN_DRIVE_KEYS) {
|
||||
MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.sitUp = function() {
|
||||
this.standUp = function() {
|
||||
print("Standing up (" + this.entityID + ")");
|
||||
MyAvatar.removeAnimationStateHandler(this.animStateHandlerID);
|
||||
Script.update.disconnect(this, this.update);
|
||||
Controller.keyPressEvent.disconnect(this, this.keyPressed);
|
||||
Controller.keyReleaseEvent.disconnect(this, this.keyReleased);
|
||||
for (var i in RELEASE_KEYS) {
|
||||
Controller.releaseKeyEvents({ text: RELEASE_KEYS[i] });
|
||||
for (var i in OVERRIDEN_DRIVE_KEYS) {
|
||||
MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS[i]);
|
||||
}
|
||||
|
||||
this.setSeatUser(null);
|
||||
|
@ -156,6 +167,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// function called by teleport.js if it detects the appropriate userData
|
||||
this.sit = function () {
|
||||
this.sitDown();
|
||||
}
|
||||
|
@ -207,7 +219,33 @@
|
|||
var properties = Entities.getEntityProperties(this.entityID);
|
||||
var avatarDistance = Vec3.distance(MyAvatar.position, properties.position);
|
||||
var ikError = MyAvatar.getIKErrorOnLastSolve();
|
||||
if (avatarDistance > RELEASE_DISTANCE || ikError > MAX_IK_ERROR) {
|
||||
var now = Date.now();
|
||||
var shouldStandUp = false;
|
||||
|
||||
// Check if a drive key is pressed
|
||||
var hasActiveDriveKey = false;
|
||||
for (var i in OVERRIDEN_DRIVE_KEYS) {
|
||||
if (MyAvatar.getRawDriveKey(OVERRIDEN_DRIVE_KEYS[i]) != 0.0) {
|
||||
hasActiveDriveKey = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only standup if user has been pushing a drive key for RELEASE_TIME
|
||||
if (hasActiveDriveKey) {
|
||||
var elapsed = now - this.lastTimeNoDriveKeys;
|
||||
shouldStandUp = elapsed > RELEASE_TIME;
|
||||
} else {
|
||||
this.lastTimeNoDriveKeys = Date.now();
|
||||
}
|
||||
|
||||
// Allow some time for the IK to settle
|
||||
if (ikError > MAX_IK_ERROR && now > this.sitDownSettlePeriod) {
|
||||
shouldStandUp = true;
|
||||
}
|
||||
|
||||
|
||||
if (shouldStandUp || avatarDistance > RELEASE_DISTANCE) {
|
||||
print("IK error: " + ikError + ", distance from chair: " + avatarDistance);
|
||||
|
||||
// Move avatar in front of the chair to avoid getting stuck in collision hulls
|
||||
|
@ -215,45 +253,13 @@
|
|||
var offset = { x: 0, y: 1.0, z: -0.5 - properties.dimensions.z * properties.registrationPoint.z };
|
||||
var position = Vec3.sum(properties.position, Vec3.multiplyQbyV(properties.rotation, offset));
|
||||
MyAvatar.position = position;
|
||||
print("Moving Avatar in front of the chair.")
|
||||
}
|
||||
|
||||
this.sitUp();
|
||||
this.standUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.keyPressed = function(event) {
|
||||
if (isInEditMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (RELEASE_KEYS.indexOf(event.text) !== -1) {
|
||||
var that = this;
|
||||
this.timers[event.text] = Script.setTimeout(function() {
|
||||
delete that.timers[event.text];
|
||||
|
||||
var properties = Entities.getEntityProperties(that.entityID);
|
||||
var avatarDistance = Vec3.distance(MyAvatar.position, properties.position);
|
||||
|
||||
// Move avatar in front of the chair to avoid getting stuck in collision hulls
|
||||
if (avatarDistance < MAX_RESET_DISTANCE) {
|
||||
var offset = { x: 0, y: 1.0, z: -0.5 - properties.dimensions.z * properties.registrationPoint.z };
|
||||
var position = Vec3.sum(properties.position, Vec3.multiplyQbyV(properties.rotation, offset));
|
||||
MyAvatar.position = position;
|
||||
}
|
||||
|
||||
that.sitUp();
|
||||
}, RELEASE_TIME);
|
||||
}
|
||||
}
|
||||
this.keyReleased = function(event) {
|
||||
if (RELEASE_KEYS.indexOf(event.text) !== -1) {
|
||||
if (this.timers[event.text]) {
|
||||
Script.clearTimeout(this.timers[event.text]);
|
||||
delete this.timers[event.text];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.canSitDesktop = function() {
|
||||
var properties = Entities.getEntityProperties(this.entityID, ["position"]);
|
||||
var distanceFromSeat = Vec3.distance(MyAvatar.position, properties.position);
|
||||
|
|
Loading…
Reference in a new issue