Merge branch 'master' of https://github.com/highfidelity/hifi into controllers

This commit is contained in:
samcake 2015-12-09 16:58:56 -08:00
commit f9269523a1
61 changed files with 785 additions and 643 deletions

View file

@ -221,3 +221,36 @@ if (HIFI_MEMORY_DEBUGGING)
MESSAGE("-- Memory debugging is enabled") MESSAGE("-- Memory debugging is enabled")
endif (UNIX) endif (UNIX)
endif () endif ()
include_application_version()
if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE)
message(STATUS "+++++ Package for deployment will be generated on this build +++++")
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment)
set(ICONPATH_INTERFACE "$INSTDIR/${PATH_INSTALL_DATA}/interface.ico")
set(ICONPATH_STACK_MANAGER "$INSTDIR/${PATH_INSTALL_DATA}/stack-manager.ico")
string(REPLACE "/" "\\\\" ICONPATH_INTERFACE ${ICONPATH_INTERFACE})
string(REPLACE "/" "\\\\" ICONPATH_STACK_MANAGER ${ICONPATH_STACK_MANAGER})
set(CPACK_PACKAGE_NAME "High Fidelity")
set(CPACK_PACKAGE_VENDOR "High Fidelity, Inc")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High Fidelity Interface and Stack")
set(CPACK_PACKAGE_VERSION "${BUILD_SEQ}")
set(CPACK_PACKAGE_VERSION_MAJOR "${BUILD_SEQ}")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "0")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity-${BUILD_SEQ}")
set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
set(CPACK_PACKAGE_EXECUTABLES
stack-manager "Stack Manager"
interface "Interface"
)
if (WIN32)
install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./")
endif (WIN32)
include(CPack)
endif ()

View file

@ -11,3 +11,4 @@ link_hifi_libraries(
include_application_version() include_application_version()
package_libraries_for_deployment() package_libraries_for_deployment()
consolidate_stack_components()

View file

@ -0,0 +1,27 @@
macro(CONSOLIDATE_STACK_COMPONENTS)
if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE AND WIN32)
# Copy all the output for this target into the common deployment location
add_custom_command(
TARGET ${TARGET_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory $<TARGET_FILE_DIR:${TARGET_NAME}> ${CMAKE_BINARY_DIR}/full-stack-deployment
)
# Copy icon files for interface and stack manager
if (TARGET_NAME STREQUAL "interface" OR TARGET_NAME STREQUAL "stack-manager")
if (TARGET_NAME STREQUAL "interface")
set (ICON_FILE_PATH "${PROJECT_SOURCE_DIR}/icon/interface.ico")
set (ICON_DESTINATION_NAME "interface.ico")
elseif (TARGET_NAME STREQUAL "stack-manager")
set (ICON_FILE_PATH "${PROJECT_SOURCE_DIR}/assets/icon.ico")
set (ICON_DESTINATION_NAME "stack-manager.ico")
endif ()
add_custom_command(
TARGET ${TARGET_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy ${ICON_FILE_PATH} ${CMAKE_BINARY_DIR}/full-stack-deployment/${ICON_DESTINATION_NAME}
)
endif ()
endif ()
endmacro()

View file

@ -10,10 +10,15 @@
# #
macro(INCLUDE_APPLICATION_VERSION) macro(INCLUDE_APPLICATION_VERSION)
#
# We are relying on Jenkins defined environment variables to determine the origin of this build
# and will only package if this is a PR or Release build
if (DEFINED ENV{JOB_ID}) if (DEFINED ENV{JOB_ID})
set (DEPLOY_PACKAGE 1)
set (BUILD_SEQ $ENV{JOB_ID}) set (BUILD_SEQ $ENV{JOB_ID})
elseif (DEFINED ENV{ghprbPullId}) elseif (DEFINED ENV{ghprbPullId})
set (BUILD_SEQ "PR: $ENV{ghprbPullId} - Commit: $ENV{ghprbActualCommit}") set (DEPLOY_PACKAGE 1)
set (BUILD_SEQ "PR-$ENV{ghprbPullId}")
else () else ()
set(BUILD_SEQ "dev") set(BUILD_SEQ "dev")
endif () endif ()

View file

@ -1,5 +1,5 @@
# #
# CopyDllsBesideWindowsExecutable.cmake # PackageLibrariesForDeployment.cmake
# cmake/macros # cmake/macros
# #
# Copyright 2015 High Fidelity, Inc. # Copyright 2015 High Fidelity, Inc.

View file

@ -107,7 +107,7 @@ if (WIN32 AND NOT CYGWIN)
select_library_configurations(SSL_EAY) select_library_configurations(SSL_EAY)
set(OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY}) set(OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY})
find_path(OPENSSL_DLL_PATH NAMES ssleay32.dll PATH_SUFFIXES "bin" ${_OPENSSL_ROOT_HINTS_AND_PATHS}) find_path(OPENSSL_DLL_PATH NAMES ssleay32.dll PATH_SUFFIXES "bin" ${_OPENSSL_ROOT_HINTS_AND_PATHS})
elseif (MINGW) elseif (MINGW)
@ -252,6 +252,15 @@ endif ()
if (WIN32) if (WIN32)
add_paths_to_fixup_libs(${OPENSSL_DLL_PATH}) add_paths_to_fixup_libs(${OPENSSL_DLL_PATH})
#
# For some reason fixup misses the following DLL and only copies libeay32. There's gotta be a better way to handle this
# but for now resorting to the following interm solution
if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE)
add_custom_command(
TARGET ${TARGET_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy ${OPENSSL_DLL_PATH}/ssleay32.dll ${CMAKE_BINARY_DIR}/full-stack-deployment/
)
endif ()
endif () endif ()
mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES OPENSSL_SEARCH_DIRS) mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES OPENSSL_SEARCH_DIRS)

View file

@ -53,4 +53,4 @@ else()
endif() endif()
file(GLOB RUNTIME_PLUGINS "${BUNDLE_PLUGIN_DIR}/*.${PLUGIN_EXTENSION}") file(GLOB RUNTIME_PLUGINS "${BUNDLE_PLUGIN_DIR}/*.${PLUGIN_EXTENSION}")
fixup_bundle("${BUNDLE_EXECUTABLE}" "${RUNTIME_PLUGINS}" "@FIXUP_LIBS@") fixup_bundle("${BUNDLE_EXECUTABLE}" "${RUNTIME_PLUGINS}" "@FIXUP_LIBS@")

View file

@ -38,3 +38,4 @@ endif (UNIX)
include_application_version() include_application_version()
package_libraries_for_deployment() package_libraries_for_deployment()
consolidate_stack_components()

View file

@ -226,6 +226,7 @@
var elRescaleDimensionsButton = document.getElementById("dimension-rescale-button"); var elRescaleDimensionsButton = document.getElementById("dimension-rescale-button");
var elParentID = document.getElementById("property-parent-id"); var elParentID = document.getElementById("property-parent-id");
var elParentJointIndex = document.getElementById("property-parent-joint-index");
var elRegistrationX = document.getElementById("property-reg-x"); var elRegistrationX = document.getElementById("property-reg-x");
var elRegistrationY = document.getElementById("property-reg-y"); var elRegistrationY = document.getElementById("property-reg-y");
@ -456,6 +457,7 @@
elDimensionsZ.value = properties.dimensions.z.toFixed(2); elDimensionsZ.value = properties.dimensions.z.toFixed(2);
elParentID.value = properties.parentID; elParentID.value = properties.parentID;
elParentJointIndex.value = properties.parentJointIndex;
elRegistrationX.value = properties.registrationPoint.x.toFixed(2); elRegistrationX.value = properties.registrationPoint.x.toFixed(2);
elRegistrationY.value = properties.registrationPoint.y.toFixed(2); elRegistrationY.value = properties.registrationPoint.y.toFixed(2);
@ -671,6 +673,7 @@
elDimensionsZ.addEventListener('change', dimensionsChangeFunction); elDimensionsZ.addEventListener('change', dimensionsChangeFunction);
elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID')); elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID'));
elParentJointIndex.addEventListener('change', createEmitNumberPropertyUpdateFunction('parentJointIndex'));
var registrationChangeFunction = createEmitVec3PropertyUpdateFunction( var registrationChangeFunction = createEmitVec3PropertyUpdateFunction(
'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ); 'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ);
@ -1067,6 +1070,12 @@
<input type="text" id="property-parent-id"> <input type="text" id="property-parent-id">
</div> </div>
</div> </div>
<div class="property">
<span class="label" style="float: left; margin-right: 6px">ParentJointIndex</span>
<div class="value" style="overflow: hidden;">
<input type="text" id="property-parent-joint-index">
</div>
</div>
<div class="property"> <div class="property">
<div class="label">Registration</div> <div class="label">Registration</div>

View file

@ -12,31 +12,57 @@
Script.include("cookies.js"); Script.include("cookies.js");
var audioOptions = new AudioEffectOptions({ var audioOptions = new AudioEffectOptions({
maxRoomSize: 50, bandwidth: 10000,
preDelay: 20,
lateDelay: 0,
reverbTime: 2,
earlyDiffusion: 100,
lateDiffusion: 100,
roomSize: 50, roomSize: 50,
reverbTime: 4, density: 100,
damping: 0.50, bassMult: 1.5,
inputBandwidth: 0.8, bassFreq: 250,
earlyLevel: 0, highGain: -6,
tailLevel: 0, highFreq: 3000,
dryLevel: -6, modRate: 2.3,
wetLevel: -6 modDepth: 50,
earlyGain: 0,
lateGain: 0,
earlyMixLeft: 20,
earlyMixRight: 20,
lateMixLeft: 90,
lateMixRight: 90,
wetDryMix: 50,
}); });
AudioDevice.setReverbOptions(audioOptions); AudioDevice.setReverbOptions(audioOptions);
AudioDevice.setReverb(true); AudioDevice.setReverb(true);
print("Reverb is ON."); print("Reverb is ON.");
var panel = new Panel(10, 200); var panel = new Panel(10, 160);
var parameters = [ var parameters = [
{ name: "roomSize", min: 0, max: 100, units: " feet" }, { name: "bandwidth", min: 1000, max: 12000, units: " Hz" },
{ name: "reverbTime", min: 0, max: 10, units: " sec" }, { name: "preDelay", min: 0, max: 333, units: " ms" },
{ name: "damping", min: 0, max: 1, units: " " }, { name: "lateDelay", min: 0, max: 166, units: " ms" },
{ name: "inputBandwidth", min: 0, max: 1, units: " " }, { name: "reverbTime", min: 0.1, max: 10, units: " seconds" },
{ name: "earlyLevel", min: -48, max: 0, units: " dB" }, { name: "earlyDiffusion", min: 0, max: 100, units: " percent" },
{ name: "tailLevel", min: -48, max: 0, units: " dB" }, { name: "lateDiffusion", min: 0, max: 100, units: " percent" },
{ name: "wetLevel", min: -48, max: 0, units: " dB" }, { name: "roomSize", min: 0, max: 100, units: " percent" },
{ name: "density", min: 0, max: 100, units: " percent" },
{ name: "bassMult", min: 0.1, max: 4, units: " ratio" },
{ name: "bassFreq", min: 10, max: 500, units: " Hz" },
{ name: "highGain", min: -24, max: 0, units: " dB" },
{ name: "highFreq", min: 1000, max: 12000, units: " Hz" },
{ name: "modRate", min: 0.1, max: 10, units: " Hz" },
{ name: "modDepth", min: 0, max: 100, units: " percent" },
{ name: "earlyGain", min: -96, max: 24, units: " dB" },
{ name: "lateGain", min: -96, max: 24, units: " dB" },
{ name: "earlyMixLeft", min: 0, max: 100, units: " percent" },
{ name: "earlyMixRight", min: 0, max: 100, units: " percent" },
{ name: "lateMixLeft", min: 0, max: 100, units: " percent" },
{ name: "lateMixRight", min: 0, max: 100, units: " percent" },
{ name: "wetDryMix", min: 0, max: 100, units: " percent" },
] ]
function setter(name) { function setter(name) {
@ -48,7 +74,7 @@ function getter(name) {
} }
function displayer(units) { function displayer(units) {
return function(value) { return (value).toFixed(1) + units; }; return function(value) { return (value).toFixed(1) + units; }
} }
// create a slider for each parameter // create a slider for each parameter

View file

@ -194,7 +194,6 @@ else (APPLE)
# link target to external libraries # link target to external libraries
if (WIN32) if (WIN32)
# target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib)
target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib) target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib)
else (WIN32) else (WIN32)
# Nothing else required on linux apparently # Nothing else required on linux apparently
@ -202,3 +201,4 @@ else (APPLE)
endif (APPLE) endif (APPLE)
package_libraries_for_deployment() package_libraries_for_deployment()
consolidate_stack_components()

View file

@ -195,6 +195,8 @@ static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html";
static const unsigned int THROTTLED_SIM_FRAMERATE = 15; static const unsigned int THROTTLED_SIM_FRAMERATE = 15;
static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE; static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE;
static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check for entities that aren't ready for simulation
#ifndef __APPLE__ #ifndef __APPLE__
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
#else #else
@ -1122,29 +1124,6 @@ void Application::paintGL() {
_inPaint = true; _inPaint = true;
Finally clearFlagLambda([this] { _inPaint = false; }); Finally clearFlagLambda([this] { _inPaint = false; });
// Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't
// include time waiting for vsync, and which can report a number above target if we've got the headroom.
// For example, if we're shooting for 75fps and paintWait is 3.3333ms (= 75% * 13.33ms), our deducedNonVSyncFps
// would be 100fps. In principle, a paintWait of zero would have deducedNonVSyncFps=75.
// Here we make a guess for deducedNonVSyncFps = 1 / deducedNonVSyncPeriod.
//
// Time between previous paintGL call and this one, which can vary not only with vSync misses, but also with QT timing.
// We're using this as a proxy for the time between vsync and displayEnd, below. (Not exact, but tends to be the same over time.)
// This is not the same as update(deltaTime), because the latter attempts to throttle to 60hz and also clamps to 1/4 second.
const float actualPeriod = diff / (float)USECS_PER_SECOND; // same as 1/instantaneousFps but easier for compiler to optimize
// Note that _lastPaintWait (stored at end of last call) is for the same paint cycle.
float deducedNonVSyncPeriod = actualPeriod - _lastPaintWait + _marginForDeducedFramePeriod; // plus a some non-zero time for machinery we can't measure
// We don't know how much time to allow for that, but if we went over the target period, we know it's at least the portion
// of paintWait up to the next vSync. This gives us enough of a penalty so that when actualPeriod crosses two cycles,
// the key part (and not an exagerated part) of _lastPaintWait is accounted for.
const float targetPeriod = getTargetFramePeriod();
if (_lastPaintWait > EPSILON && actualPeriod > targetPeriod) {
// Don't use C++ remainder(). It's authors are mathematically insane.
deducedNonVSyncPeriod += fmod(actualPeriod, _lastPaintWait);
}
_lastDeducedNonVSyncFps = 1.0f / deducedNonVSyncPeriod;
_lastInstantaneousFps = instantaneousFps;
auto displayPlugin = getActiveDisplayPlugin(); auto displayPlugin = getActiveDisplayPlugin();
// FIXME not needed anymore? // FIXME not needed anymore?
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
@ -1401,7 +1380,6 @@ void Application::paintGL() {
Q_ASSERT(!_lockedFramebufferMap.contains(finalTexture)); Q_ASSERT(!_lockedFramebufferMap.contains(finalTexture));
_lockedFramebufferMap[finalTexture] = scratchFramebuffer; _lockedFramebufferMap[finalTexture] = scratchFramebuffer;
uint64_t displayStart = usecTimestampNow();
Q_ASSERT(isCurrentContext(_offscreenContext->getContext())); Q_ASSERT(isCurrentContext(_offscreenContext->getContext()));
{ {
PROFILE_RANGE(__FUNCTION__ "/pluginSubmitScene"); PROFILE_RANGE(__FUNCTION__ "/pluginSubmitScene");
@ -1410,9 +1388,6 @@ void Application::paintGL() {
} }
Q_ASSERT(isCurrentContext(_offscreenContext->getContext())); Q_ASSERT(isCurrentContext(_offscreenContext->getContext()));
uint64_t displayEnd = usecTimestampNow();
const float displayPeriodUsec = (float)(displayEnd - displayStart); // usecs
_lastPaintWait = displayPeriodUsec / (float)USECS_PER_SECOND;
} }
{ {
@ -1423,6 +1398,14 @@ void Application::paintGL() {
batch.resetStages(); batch.resetStages();
}); });
} }
// Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't
// include time waiting for sync, and which can report a number above target if we've got the headroom.
// In my tests, the following is mostly less than 0.5ms, and never more than 3ms. I don't think its worth measuring during runtime.
const float paintWaitAndQTTimerAllowance = 0.001f; // seconds
// Store both values now for use by next cycle.
_lastInstantaneousFps = instantaneousFps;
_lastUnsynchronizedFps = 1.0f / (((usecTimestampNow() - now) / (float)USECS_PER_SECOND) + paintWaitAndQTTimerAllowance);
} }
void Application::runTests() { void Application::runTests() {
@ -2419,6 +2402,9 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
exportTree->addEntity(entityItem->getEntityItemID(), properties); exportTree->addEntity(entityItem->getEntityItemID(), properties);
} }
// remap IDs on export so that we aren't publishing the IDs of entities in our domain
exportTree->remapIDs();
exportTree->writeToJSONFile(filename.toLocal8Bit().constData()); exportTree->writeToJSONFile(filename.toLocal8Bit().constData());
// restore the main window's active state // restore the main window's active state
@ -2441,6 +2427,10 @@ bool Application::exportEntities(const QString& filename, float x, float y, floa
properties.setPosition(properties.getPosition() - root); properties.setPosition(properties.getPosition() - root);
exportTree->addEntity(id, properties); exportTree->addEntity(id, properties);
} }
// remap IDs on export so that we aren't publishing the IDs of entities in our domain
exportTree->remapIDs();
exportTree->writeToSVOFile(filename.toLocal8Bit().constData()); exportTree->writeToSVOFile(filename.toLocal8Bit().constData());
} else { } else {
qCDebug(interfaceapp) << "No models were selected"; qCDebug(interfaceapp) << "No models were selected";
@ -2485,6 +2475,7 @@ bool Application::importEntities(const QString& urlOrFilename) {
bool success = _entityClipboard->readFromURL(url.toString()); bool success = _entityClipboard->readFromURL(url.toString());
if (success) { if (success) {
_entityClipboard->remapIDs();
_entityClipboard->reaverageOctreeElements(); _entityClipboard->reaverageOctreeElements();
} }
return success; return success;
@ -2897,7 +2888,7 @@ void Application::update(float deltaTime) {
_avatarUpdate->synchronousProcess(); _avatarUpdate->synchronousProcess();
{ if (true || _physicsEnabled) {
PerformanceTimer perfTimer("physics"); PerformanceTimer perfTimer("physics");
static VectorOfMotionStates motionStates; static VectorOfMotionStates motionStates;
@ -3778,6 +3769,8 @@ void Application::domainChanged(const QString& domainHostname) {
updateWindowTitle(); updateWindowTitle();
clearDomainOctreeDetails(); clearDomainOctreeDetails();
_domainConnectionRefusals.clear(); _domainConnectionRefusals.clear();
// disable physics until we have enough information about our new location to not cause craziness.
_physicsEnabled = false;
} }
void Application::handleDomainConnectionDeniedPacket(QSharedPointer<ReceivedMessage> message) { void Application::handleDomainConnectionDeniedPacket(QSharedPointer<ReceivedMessage> message) {
@ -3885,6 +3878,31 @@ void Application::trackIncomingOctreePacket(ReceivedMessage& message, SharedNode
} }
} }
bool Application::nearbyEntitiesAreReadyForPhysics() {
// this is used to avoid the following scenario:
// A table has some items sitting on top of it. The items are at rest, meaning they aren't active in bullet.
// Someone logs in close to the table. They receive information about the items on the table before they
// receive information about the table. The items are very close to the avatar's capsule, so they become
// activated in bullet. This causes them to fall to the floor, because the table's shape isn't yet in bullet.
EntityTreePointer entityTree = _entities.getTree();
if (!entityTree) {
return false;
}
QVector<EntityItemPointer> entities;
entityTree->withReadLock([&] {
AABox box(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE));
entityTree->findEntities(box, entities);
});
foreach (EntityItemPointer entity, entities) {
if (!entity->isReadyToComputeShape()) {
return false;
}
}
return true;
}
int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode) { int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode) {
// But, also identify the sender, and keep track of the contained jurisdiction root for this server // But, also identify the sender, and keep track of the contained jurisdiction root for this server
@ -3930,7 +3948,12 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer
}); });
}); });
if (!_physicsEnabled && nearbyEntitiesAreReadyForPhysics()) {
// These stats packets are sent in between full sends of a scene.
// We keep physics disabled until we've recieved a full scene and everything near the avatar in that
// scene is ready to compute its collision shape.
_physicsEnabled = true;
}
return statsMessageLength; return statsMessageLength;
} }

View file

@ -163,11 +163,8 @@ public:
float const HMD_TARGET_FRAME_RATE = 75.0f; float const HMD_TARGET_FRAME_RATE = 75.0f;
float const DESKTOP_TARGET_FRAME_RATE = 60.0f; float const DESKTOP_TARGET_FRAME_RATE = 60.0f;
float getTargetFrameRate() { return isHMDMode() ? HMD_TARGET_FRAME_RATE : DESKTOP_TARGET_FRAME_RATE; } float getTargetFrameRate() { return isHMDMode() ? HMD_TARGET_FRAME_RATE : DESKTOP_TARGET_FRAME_RATE; }
float getTargetFramePeriod() { return isHMDMode() ? 1.0f / HMD_TARGET_FRAME_RATE : 1.0f / DESKTOP_TARGET_FRAME_RATE; } // same as 1/getTargetFrameRate, but w/compile-time division
float getLastInstanteousFps() const { return _lastInstantaneousFps; } float getLastInstanteousFps() const { return _lastInstantaneousFps; }
float getLastPaintWait() const { return _lastPaintWait; }; float getLastUnsynchronizedFps() const { return _lastUnsynchronizedFps; }
float getLastDeducedNonVSyncFps() const { return _lastDeducedNonVSyncFps; }
void setMarginForDeducedFramePeriod(float newValue) { _marginForDeducedFramePeriod = newValue; }
float getFieldOfView() { return _fieldOfView.get(); } float getFieldOfView() { return _fieldOfView.get(); }
void setFieldOfView(float fov); void setFieldOfView(float fov);
@ -395,6 +392,7 @@ private:
bool importSVOFromURL(const QString& urlString); bool importSVOFromURL(const QString& urlString);
bool nearbyEntitiesAreReadyForPhysics();
int processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode); int processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode);
void trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket); void trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket);
@ -442,9 +440,7 @@ private:
QElapsedTimer _timerStart; QElapsedTimer _timerStart;
QElapsedTimer _lastTimeUpdated; QElapsedTimer _lastTimeUpdated;
float _lastInstantaneousFps { 0.0f }; float _lastInstantaneousFps { 0.0f };
float _lastPaintWait { 0.0f }; float _lastUnsynchronizedFps { 0.0f };
float _lastDeducedNonVSyncFps { 0.0f };
float _marginForDeducedFramePeriod{ 0.002f }; // 2ms, adjustable
ShapeManager _shapeManager; ShapeManager _shapeManager;
PhysicalEntitySimulation _entitySimulation; PhysicalEntitySimulation _entitySimulation;
@ -564,6 +560,7 @@ private:
bool _isForeground = true; // starts out assumed to be in foreground bool _isForeground = true; // starts out assumed to be in foreground
bool _inPaint = false; bool _inPaint = false;
bool _isGLInitialized { false }; bool _isGLInitialized { false };
bool _physicsEnabled { false };
}; };
#endif // hifi_Application_h #endif // hifi_Application_h

View file

@ -201,6 +201,7 @@ void Avatar::simulate(float deltaTime) {
_skeletonModel.getRig()->copyJointsFromJointData(_jointData); _skeletonModel.getRig()->copyJointsFromJointData(_jointData);
_skeletonModel.simulate(deltaTime, _hasNewJointRotations || _hasNewJointTranslations); _skeletonModel.simulate(deltaTime, _hasNewJointRotations || _hasNewJointTranslations);
simulateAttachments(deltaTime); simulateAttachments(deltaTime);
locationChanged(); // joints changed, so if there are any children, update them.
_hasNewJointRotations = false; _hasNewJointRotations = false;
_hasNewJointTranslations = false; _hasNewJointTranslations = false;
} }
@ -868,6 +869,17 @@ glm::vec3 Avatar::getJointTranslation(int index) const {
return translation; return translation;
} }
glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
glm::quat rotation;
_skeletonModel.getAbsoluteJointRotationInRigFrame(index, rotation);
return Quaternions::Y_180 * rotation;
}
glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
glm::vec3 translation;
_skeletonModel.getAbsoluteJointTranslationInRigFrame(index, translation);
return Quaternions::Y_180 * translation;
}
int Avatar::getJointIndex(const QString& name) const { int Avatar::getJointIndex(const QString& name) const {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
@ -1145,12 +1157,12 @@ glm::quat Avatar::getRightPalmRotation() {
return rightRotation; return rightRotation;
} }
void Avatar::setPosition(const glm::vec3 position) { void Avatar::setPosition(const glm::vec3& position) {
AvatarData::setPosition(position); AvatarData::setPosition(position);
updateAttitude(); updateAttitude();
} }
void Avatar::setOrientation(const glm::quat orientation) { void Avatar::setOrientation(const glm::quat& orientation) {
AvatarData::setOrientation(orientation); AvatarData::setOrientation(orientation);
updateAttitude(); updateAttitude();
} }

View file

@ -108,6 +108,9 @@ public:
virtual int getJointIndex(const QString& name) const; virtual int getJointIndex(const QString& name) const;
virtual QStringList getJointNames() const; virtual QStringList getJointNames() const;
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override;
virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setFaceModelURL(const QUrl& faceModelURL);
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData); virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData);
@ -155,8 +158,8 @@ public:
void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; }
AvatarMotionState* getMotionState() { return _motionState; } AvatarMotionState* getMotionState() { return _motionState; }
virtual void setPosition(glm::vec3 position); virtual void setPosition(const glm::vec3& position) override;
virtual void setOrientation(glm::quat orientation); virtual void setOrientation(const glm::quat& orientation) override;
public slots: public slots:

View file

@ -111,7 +111,6 @@ void AvatarManager::init() {
_renderDistanceController.setKP(0.0008f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0. _renderDistanceController.setKP(0.0008f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0.
_renderDistanceController.setKI(0.0006f); // Big enough to bring us to target with the above KP. _renderDistanceController.setKI(0.0006f); // Big enough to bring us to target with the above KP.
_renderDistanceController.setKD(0.000001f); // A touch of kd increases the speed by which we get there. _renderDistanceController.setKD(0.000001f); // A touch of kd increases the speed by which we get there.
} }
void AvatarManager::updateMyAvatar(float deltaTime) { void AvatarManager::updateMyAvatar(float deltaTime) {
@ -151,7 +150,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
// The measured value is frame rate. When the controlled value (1 / render cutoff distance) // The measured value is frame rate. When the controlled value (1 / render cutoff distance)
// goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate // goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate
// goes up. // goes up.
const float deduced = qApp->getLastDeducedNonVSyncFps(); const float deduced = qApp->getLastUnsynchronizedFps();
const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime); const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime);
_renderDistanceAverage.updateAverage(distance); _renderDistanceAverage.updateAverage(distance);
_renderDistance = _renderDistanceAverage.getAverage(); _renderDistance = _renderDistanceAverage.getAverage();

View file

@ -622,7 +622,8 @@ QScriptValue WindowScriptingInterface::showBrowse(const QString& title, const QS
fileDialog.setAcceptMode(acceptMode); fileDialog.setAcceptMode(acceptMode);
QUrl fileUrl(directory); QUrl fileUrl(directory);
if (acceptMode == QFileDialog::AcceptSave) { if (acceptMode == QFileDialog::AcceptSave) {
fileDialog.setFileMode(QFileDialog::Directory); // TODO -- Setting this breaks the dialog on Linux. Does it help something on other platforms?
// fileDialog.setFileMode(QFileDialog::Directory);
fileDialog.selectFile(fileUrl.fileName()); fileDialog.selectFile(fileUrl.fileName());
} }
if (fileDialog.exec()) { if (fileDialog.exec()) {

View file

@ -374,6 +374,16 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const {
} }
} }
bool Rig::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const {
QReadLocker readLock(&_externalPoseSetLock);
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) {
rotation = _externalPoseSet._absolutePoses[jointIndex].rot;
return true;
} else {
return false;
}
}
bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const { bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const {
QReadLocker readLock(&_externalPoseSetLock); QReadLocker readLock(&_externalPoseSetLock);
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._relativePoses.size()) { if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._relativePoses.size()) {
@ -384,6 +394,16 @@ bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const {
} }
} }
bool Rig::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const {
QReadLocker readLock(&_externalPoseSetLock);
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) {
translation = _externalPoseSet._absolutePoses[jointIndex].trans;
return true;
} else {
return false;
}
}
bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const { bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const {
// AJT: TODO: used by attachments // AJT: TODO: used by attachments
ASSERT(false); ASSERT(false);

View file

@ -129,10 +129,12 @@ public:
// geometry space (thread-safe) // geometry space (thread-safe)
bool getJointRotation(int jointIndex, glm::quat& rotation) const; bool getJointRotation(int jointIndex, glm::quat& rotation) const;
// geometry space (thread-safe)
bool getJointTranslation(int jointIndex, glm::vec3& translation) const; bool getJointTranslation(int jointIndex, glm::vec3& translation) const;
// rig space (thread-safe)
bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const;
bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const;
// legacy // legacy
bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const;

View file

@ -541,26 +541,40 @@ bool AudioClient::switchOutputToAudioDevice(const QString& outputDeviceName) {
void AudioClient::configureReverb() { void AudioClient::configureReverb() {
ReverbParameters p; ReverbParameters p;
_listenerReverb.getParameters(&p);
// for now, reuse the gverb parameters
p.sampleRate = _outputFormat.sampleRate(); p.sampleRate = _outputFormat.sampleRate();
p.roomSize = _reverbOptions->getRoomSize();
p.bandwidth = _reverbOptions->getBandwidth();
p.preDelay = _reverbOptions->getPreDelay();
p.lateDelay = _reverbOptions->getLateDelay();
p.reverbTime = _reverbOptions->getReverbTime(); p.reverbTime = _reverbOptions->getReverbTime();
p.highGain = -24.0f * (1.0f - _reverbOptions->getDamping()); p.earlyDiffusion = _reverbOptions->getEarlyDiffusion();
p.bandwidth = 10000.0f * _reverbOptions->getInputBandwidth(); p.lateDiffusion = _reverbOptions->getLateDiffusion();
p.earlyGain = _reverbOptions->getEarlyLevel(); p.roomSize = _reverbOptions->getRoomSize();
p.lateGain = _reverbOptions->getTailLevel(); p.density = _reverbOptions->getDensity();
p.wetDryMix = 100.0f * powf(10.0f, _reverbOptions->getWetLevel() * (1/20.0f)); p.bassMult = _reverbOptions->getBassMult();
p.bassFreq = _reverbOptions->getBassFreq();
p.highGain = _reverbOptions->getHighGain();
p.highFreq = _reverbOptions->getHighFreq();
p.modRate = _reverbOptions->getModRate();
p.modDepth = _reverbOptions->getModDepth();
p.earlyGain = _reverbOptions->getEarlyGain();
p.lateGain = _reverbOptions->getLateGain();
p.earlyMixLeft = _reverbOptions->getEarlyMixLeft();
p.earlyMixRight = _reverbOptions->getEarlyMixRight();
p.lateMixLeft = _reverbOptions->getLateMixLeft();
p.lateMixRight = _reverbOptions->getLateMixRight();
p.wetDryMix = _reverbOptions->getWetDryMix();
_listenerReverb.setParameters(&p); _listenerReverb.setParameters(&p);
// used for adding self-reverb to loopback audio // used only for adding self-reverb to loopback audio
p.wetDryMix = 100.0f; p.wetDryMix = 100.0f;
p.preDelay = 0.0f; p.preDelay = 0.0f;
p.earlyGain = -96.0f; // disable ER p.earlyGain = -96.0f; // disable ER
p.lateGain -= 12.0f; // quieter than listener reverb p.lateGain -= 12.0f; // quieter than listener reverb
p.lateMixLeft = 0.0f; p.lateMixLeft = 0.0f;
p.lateMixRight = 0.0f; p.lateMixRight = 0.0f;
_sourceReverb.setParameters(&p); _sourceReverb.setParameters(&p);
} }
@ -572,10 +586,10 @@ void AudioClient::updateReverbOptions() {
_zoneReverbOptions.setReverbTime(_receivedAudioStream.getRevebTime()); _zoneReverbOptions.setReverbTime(_receivedAudioStream.getRevebTime());
reverbChanged = true; reverbChanged = true;
} }
if (_zoneReverbOptions.getWetLevel() != _receivedAudioStream.getWetLevel()) { //if (_zoneReverbOptions.getWetLevel() != _receivedAudioStream.getWetLevel()) {
_zoneReverbOptions.setWetLevel(_receivedAudioStream.getWetLevel()); // _zoneReverbOptions.setWetLevel(_receivedAudioStream.getWetLevel());
reverbChanged = true; // reverbChanged = true;
} //}
if (_reverbOptions != &_zoneReverbOptions) { if (_reverbOptions != &_zoneReverbOptions) {
_reverbOptions = &_zoneReverbOptions; _reverbOptions = &_zoneReverbOptions;
@ -602,17 +616,27 @@ void AudioClient::setReverb(bool reverb) {
void AudioClient::setReverbOptions(const AudioEffectOptions* options) { void AudioClient::setReverbOptions(const AudioEffectOptions* options) {
// Save the new options // Save the new options
_scriptReverbOptions.setMaxRoomSize(options->getMaxRoomSize()); _scriptReverbOptions.setBandwidth(options->getBandwidth());
_scriptReverbOptions.setRoomSize(options->getRoomSize()); _scriptReverbOptions.setPreDelay(options->getPreDelay());
_scriptReverbOptions.setLateDelay(options->getLateDelay());
_scriptReverbOptions.setReverbTime(options->getReverbTime()); _scriptReverbOptions.setReverbTime(options->getReverbTime());
_scriptReverbOptions.setDamping(options->getDamping()); _scriptReverbOptions.setEarlyDiffusion(options->getEarlyDiffusion());
_scriptReverbOptions.setSpread(options->getSpread()); _scriptReverbOptions.setLateDiffusion(options->getLateDiffusion());
_scriptReverbOptions.setInputBandwidth(options->getInputBandwidth()); _scriptReverbOptions.setRoomSize(options->getRoomSize());
_scriptReverbOptions.setEarlyLevel(options->getEarlyLevel()); _scriptReverbOptions.setDensity(options->getDensity());
_scriptReverbOptions.setTailLevel(options->getTailLevel()); _scriptReverbOptions.setBassMult(options->getBassMult());
_scriptReverbOptions.setBassFreq(options->getBassFreq());
_scriptReverbOptions.setDryLevel(options->getDryLevel()); _scriptReverbOptions.setHighGain(options->getHighGain());
_scriptReverbOptions.setWetLevel(options->getWetLevel()); _scriptReverbOptions.setHighFreq(options->getHighFreq());
_scriptReverbOptions.setModRate(options->getModRate());
_scriptReverbOptions.setModDepth(options->getModDepth());
_scriptReverbOptions.setEarlyGain(options->getEarlyGain());
_scriptReverbOptions.setLateGain(options->getLateGain());
_scriptReverbOptions.setEarlyMixLeft(options->getEarlyMixLeft());
_scriptReverbOptions.setEarlyMixRight(options->getEarlyMixRight());
_scriptReverbOptions.setLateMixLeft(options->getLateMixLeft());
_scriptReverbOptions.setLateMixRight(options->getLateMixRight());
_scriptReverbOptions.setWetDryMix(options->getWetDryMix());
if (_reverbOptions == &_scriptReverbOptions) { if (_reverbOptions == &_scriptReverbOptions) {
// Apply them to the reverb instances // Apply them to the reverb instances

View file

@ -10,58 +10,76 @@
#include "AudioEffectOptions.h" #include "AudioEffectOptions.h"
static const QString MAX_ROOM_SIZE_HANDLE = "maxRoomSize"; static const QString BANDWIDTH_HANDLE = "bandwidth";
static const QString ROOM_SIZE_HANDLE = "roomSize"; static const QString PRE_DELAY_HANDLE = "preDelay";
static const QString LATE_DELAY_HANDLE = "lateDelay";
static const QString REVERB_TIME_HANDLE = "reverbTime"; static const QString REVERB_TIME_HANDLE = "reverbTime";
static const QString DAMPIMG_HANDLE = "damping"; static const QString EARLY_DIFFUSION_HANDLE = "earlyDiffusion";
static const QString SPREAD_HANDLE = "spread"; static const QString LATE_DIFFUSION_HANDLE = "lateDiffusion";
static const QString INPUT_BANDWIDTH_HANDLE = "inputBandwidth"; static const QString ROOM_SIZE_HANDLE = "roomSize";
static const QString EARLY_LEVEL_HANDLE = "earlyLevel"; static const QString DENSITY_HANDLE = "density";
static const QString TAIL_LEVEL_HANDLE = "tailLevel"; static const QString BASS_MULT_HANDLE = "bassMult";
static const QString DRY_LEVEL_HANDLE = "dryLevel"; static const QString BASS_FREQ_HANDLE = "bassFreq";
static const QString WET_LEVEL_HANDLE = "wetLevel"; static const QString HIGH_GAIN_HANDLE = "highGain";
static const QString HIGH_FREQ_HANDLE = "highFreq";
static const QString MOD_RATE_HANDLE = "modRate";
static const QString MOD_DEPTH_HANDLE = "modDepth";
static const QString EARLY_GAIN_HANDLE = "earlyGain";
static const QString LATE_GAIN_HANDLE = "lateGain";
static const QString EARLY_MIX_LEFT_HANDLE = "earlyMixLeft";
static const QString EARLY_MIX_RIGHT_HANDLE = "earlyMixRight";
static const QString LATE_MIX_LEFT_HANDLE = "lateMixLeft";
static const QString LATE_MIX_RIGHT_HANDLE = "lateMixRight";
static const QString WET_DRY_MIX_HANDLE = "wetDryMix";
AudioEffectOptions::AudioEffectOptions(QScriptValue arguments) : static const float BANDWIDTH_DEFAULT = 10000.0f;
_maxRoomSize(50.0f), static const float PRE_DELAY_DEFAULT = 20.0f;
_roomSize(50.0f), static const float LATE_DELAY_DEFAULT = 0.0f;
_reverbTime(4.0f), static const float REVERB_TIME_DEFAULT = 2.0f;
_damping(0.5f), static const float EARLY_DIFFUSION_DEFAULT = 100.0f;
_spread(15.0f), static const float LATE_DIFFUSION_DEFAULT = 100.0f;
_inputBandwidth(0.75f), static const float ROOM_SIZE_DEFAULT = 50.0f;
_earlyLevel(-12.0f), static const float DENSITY_DEFAULT = 100.0f;
_tailLevel(-18.0f), static const float BASS_MULT_DEFAULT = 1.5f;
_dryLevel(0.0f), static const float BASS_FREQ_DEFAULT = 250.0f;
_wetLevel(0.0f) { static const float HIGH_GAIN_DEFAULT = -6.0f;
if (arguments.property(MAX_ROOM_SIZE_HANDLE).isNumber()) { static const float HIGH_FREQ_DEFAULT = 3000.0f;
_maxRoomSize = arguments.property(MAX_ROOM_SIZE_HANDLE).toNumber(); static const float MOD_RATE_DEFAULT = 2.3f;
} static const float MOD_DEPTH_DEFAULT = 50.0f;
if (arguments.property(ROOM_SIZE_HANDLE).isNumber()) { static const float EARLY_GAIN_DEFAULT = 0.0f;
_roomSize = arguments.property(ROOM_SIZE_HANDLE).toNumber(); static const float LATE_GAIN_DEFAULT = 0.0f;
} static const float EARLY_MIX_LEFT_DEFAULT = 20.0f;
if (arguments.property(REVERB_TIME_HANDLE).isNumber()) { static const float EARLY_MIX_RIGHT_DEFAULT = 20.0f;
_reverbTime = arguments.property(REVERB_TIME_HANDLE).toNumber(); static const float LATE_MIX_LEFT_DEFAULT = 90.0f;
} static const float LATE_MIX_RIGHT_DEFAULT = 90.0f;
if (arguments.property(DAMPIMG_HANDLE).isNumber()) { static const float WET_DRY_MIX_DEFAULT = 50.0f;
_damping = arguments.property(DAMPIMG_HANDLE).toNumber();
} static void setOption(QScriptValue arguments, const QString name, float defaultValue, float& variable) {
if (arguments.property(SPREAD_HANDLE).isNumber()) { variable = arguments.property(name).isNumber() ? arguments.property(name).toNumber() : defaultValue;
_spread = arguments.property(SPREAD_HANDLE).toNumber(); }
}
if (arguments.property(INPUT_BANDWIDTH_HANDLE).isNumber()) { AudioEffectOptions::AudioEffectOptions(QScriptValue arguments) {
_inputBandwidth = arguments.property(INPUT_BANDWIDTH_HANDLE).toNumber(); setOption(arguments, BANDWIDTH_HANDLE, BANDWIDTH_DEFAULT, _bandwidth);
} setOption(arguments, PRE_DELAY_HANDLE, PRE_DELAY_DEFAULT, _preDelay);
if (arguments.property(EARLY_LEVEL_HANDLE).isNumber()) { setOption(arguments, LATE_DELAY_HANDLE, LATE_DELAY_DEFAULT, _lateDelay);
_earlyLevel = arguments.property(EARLY_LEVEL_HANDLE).toNumber(); setOption(arguments, REVERB_TIME_HANDLE, REVERB_TIME_DEFAULT, _reverbTime);
} setOption(arguments, EARLY_DIFFUSION_HANDLE, EARLY_DIFFUSION_DEFAULT, _earlyDiffusion);
if (arguments.property(TAIL_LEVEL_HANDLE).isNumber()) { setOption(arguments, LATE_DIFFUSION_HANDLE, LATE_DIFFUSION_DEFAULT, _lateDiffusion);
_tailLevel = arguments.property(TAIL_LEVEL_HANDLE).toNumber(); setOption(arguments, ROOM_SIZE_HANDLE, ROOM_SIZE_DEFAULT, _roomSize);
} setOption(arguments, DENSITY_HANDLE, DENSITY_DEFAULT, _density);
if (arguments.property(DRY_LEVEL_HANDLE).isNumber()) { setOption(arguments, BASS_MULT_HANDLE, BASS_MULT_DEFAULT, _bassMult);
_dryLevel = arguments.property(DRY_LEVEL_HANDLE).toNumber(); setOption(arguments, BASS_FREQ_HANDLE, BASS_FREQ_DEFAULT, _bassFreq);
} setOption(arguments, HIGH_GAIN_HANDLE, HIGH_GAIN_DEFAULT, _highGain);
if (arguments.property(WET_LEVEL_HANDLE).isNumber()) { setOption(arguments, HIGH_FREQ_HANDLE, HIGH_FREQ_DEFAULT, _highFreq);
_wetLevel = arguments.property(WET_LEVEL_HANDLE).toNumber(); setOption(arguments, MOD_RATE_HANDLE, MOD_RATE_DEFAULT, _modRate);
} setOption(arguments, MOD_DEPTH_HANDLE, MOD_DEPTH_DEFAULT, _modDepth);
setOption(arguments, EARLY_GAIN_HANDLE, EARLY_GAIN_DEFAULT, _earlyGain);
setOption(arguments, LATE_GAIN_HANDLE, LATE_GAIN_DEFAULT, _lateGain);
setOption(arguments, EARLY_MIX_LEFT_HANDLE, EARLY_MIX_LEFT_DEFAULT, _earlyMixLeft);
setOption(arguments, EARLY_MIX_RIGHT_HANDLE, EARLY_MIX_RIGHT_DEFAULT, _earlyMixRight);
setOption(arguments, LATE_MIX_LEFT_HANDLE, LATE_MIX_LEFT_DEFAULT, _lateMixLeft);
setOption(arguments, LATE_MIX_RIGHT_HANDLE, LATE_MIX_RIGHT_DEFAULT, _lateMixRight);
setOption(arguments, WET_DRY_MIX_HANDLE, WET_DRY_MIX_DEFAULT, _wetDryMix);
} }
AudioEffectOptions::AudioEffectOptions(const AudioEffectOptions &other) : QObject() { AudioEffectOptions::AudioEffectOptions(const AudioEffectOptions &other) : QObject() {
@ -69,17 +87,28 @@ AudioEffectOptions::AudioEffectOptions(const AudioEffectOptions &other) : QObjec
} }
AudioEffectOptions& AudioEffectOptions::operator=(const AudioEffectOptions &other) { AudioEffectOptions& AudioEffectOptions::operator=(const AudioEffectOptions &other) {
_maxRoomSize = other._maxRoomSize; _bandwidth = other._bandwidth;
_roomSize = other._roomSize; _preDelay = other._preDelay;
_lateDelay = other._lateDelay;
_reverbTime = other._reverbTime; _reverbTime = other._reverbTime;
_damping = other._damping; _earlyDiffusion = other._earlyDiffusion;
_spread = other._spread; _lateDiffusion = other._lateDiffusion;
_inputBandwidth = other._inputBandwidth; _roomSize = other._roomSize;
_earlyLevel = other._earlyLevel; _density = other._density;
_tailLevel = other._tailLevel; _bassMult = other._bassMult;
_dryLevel = other._dryLevel; _bassFreq = other._bassFreq;
_wetLevel = other._wetLevel; _highGain = other._highGain;
_highFreq = other._highFreq;
_modRate = other._modRate;
_modDepth = other._modDepth;
_earlyGain = other._earlyGain;
_lateGain = other._lateGain;
_earlyMixLeft = other._earlyMixLeft;
_earlyMixRight = other._earlyMixRight;
_lateMixLeft = other._lateMixLeft;
_lateMixRight = other._lateMixRight;
_wetDryMix = other._wetDryMix;
return *this; return *this;
} }

View file

@ -15,32 +15,30 @@
#include <QtScript/QScriptContext> #include <QtScript/QScriptContext>
#include <QtScript/QScriptEngine> #include <QtScript/QScriptEngine>
#include "AudioReverb.h"
class AudioEffectOptions : public QObject { class AudioEffectOptions : public QObject {
Q_OBJECT Q_OBJECT
// Meters Square Q_PROPERTY(float bandwidth READ getBandwidth WRITE setBandwidth)
Q_PROPERTY(float maxRoomSize READ getMaxRoomSize WRITE setMaxRoomSize) Q_PROPERTY(float preDelay READ getPreDelay WRITE setPreDelay)
Q_PROPERTY(float roomSize READ getRoomSize WRITE setRoomSize) Q_PROPERTY(float lateDelay READ getLateDelay WRITE setLateDelay)
// Seconds
Q_PROPERTY(float reverbTime READ getReverbTime WRITE setReverbTime) Q_PROPERTY(float reverbTime READ getReverbTime WRITE setReverbTime)
Q_PROPERTY(float earlyDiffusion READ getEarlyDiffusion WRITE setEarlyDiffusion)
// Ratio between 0 and 1 Q_PROPERTY(float lateDiffusion READ getLateDiffusion WRITE setLateDiffusion)
Q_PROPERTY(float damping READ getDamping WRITE setDamping) Q_PROPERTY(float roomSize READ getRoomSize WRITE setRoomSize)
Q_PROPERTY(float density READ getDensity WRITE setDensity)
// (?) Does not appear to be set externally very often Q_PROPERTY(float bassMult READ getBassMult WRITE setBassMult)
Q_PROPERTY(float spread READ getSpread WRITE setSpread) Q_PROPERTY(float bassFreq READ getBassFreq WRITE setBassFreq)
Q_PROPERTY(float highGain READ getHighGain WRITE setHighGain)
// Ratio between 0 and 1 Q_PROPERTY(float highFreq READ getHighFreq WRITE setHighFreq)
Q_PROPERTY(float inputBandwidth READ getInputBandwidth WRITE setInputBandwidth) Q_PROPERTY(float modRate READ getModRate WRITE setModRate)
Q_PROPERTY(float modDepth READ getModDepth WRITE setModDepth)
// in dB Q_PROPERTY(float earlyGain READ getEarlyGain WRITE setEarlyGain)
Q_PROPERTY(float earlyLevel READ getEarlyLevel WRITE setEarlyLevel) Q_PROPERTY(float lateGain READ getLateGain WRITE setLateGain)
Q_PROPERTY(float tailLevel READ getTailLevel WRITE setTailLevel) Q_PROPERTY(float earlyMixLeft READ getEarlyMixLeft WRITE setEarlyMixLeft)
Q_PROPERTY(float dryLevel READ getDryLevel WRITE setDryLevel) Q_PROPERTY(float earlyMixRight READ getEarlyMixRight WRITE setEarlyMixRight)
Q_PROPERTY(float wetLevel READ getWetLevel WRITE setWetLevel) Q_PROPERTY(float lateMixLeft READ getLateMixLeft WRITE setLateMixLeft)
Q_PROPERTY(float lateMixRight READ getLateMixRight WRITE setLateMixRight)
Q_PROPERTY(float wetDryMix READ getWetDryMix WRITE setWetDryMix)
public: public:
AudioEffectOptions(QScriptValue arguments = QScriptValue()); AudioEffectOptions(QScriptValue arguments = QScriptValue());
@ -49,60 +47,100 @@ public:
static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine); static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine);
float getRoomSize() const { return _roomSize; } float getBandwidth() const { return _bandwidth; }
void setRoomSize(float roomSize ) { _roomSize = roomSize; } void setBandwidth(float bandwidth) { _bandwidth = bandwidth; }
float getMaxRoomSize() const { return _maxRoomSize; } float getPreDelay() const { return _preDelay; }
void setMaxRoomSize(float maxRoomSize ) { _maxRoomSize = maxRoomSize; } void setPreDelay(float preDelay) { _preDelay = preDelay; }
float getLateDelay() const { return _lateDelay; }
void setLateDelay(float lateDelay) { _lateDelay = lateDelay; }
float getReverbTime() const { return _reverbTime; } float getReverbTime() const { return _reverbTime; }
void setReverbTime(float reverbTime ) { _reverbTime = reverbTime; } void setReverbTime(float reverbTime) { _reverbTime = reverbTime; }
float getDamping() const { return _damping; } float getEarlyDiffusion() const { return _earlyDiffusion; }
void setDamping(float damping ) { _damping = damping; } void setEarlyDiffusion(float earlyDiffusion) { _earlyDiffusion = earlyDiffusion; }
float getSpread() const { return _spread; } float getLateDiffusion() const { return _lateDiffusion; }
void setSpread(float spread ) { _spread = spread; } void setLateDiffusion(float lateDiffusion) { _lateDiffusion = lateDiffusion; }
float getInputBandwidth() const { return _inputBandwidth; } float getRoomSize() const { return _roomSize; }
void setInputBandwidth(float inputBandwidth ) { _inputBandwidth = inputBandwidth; } void setRoomSize(float roomSize) { _roomSize = roomSize; }
float getEarlyLevel() const { return _earlyLevel; } float getDensity() const { return _density; }
void setEarlyLevel(float earlyLevel ) { _earlyLevel = earlyLevel; } void setDensity(float density) { _density = density; }
float getTailLevel() const { return _tailLevel; } float getBassMult() const { return _bassMult; }
void setTailLevel(float tailLevel ) { _tailLevel = tailLevel; } void setBassMult(float bassMult) { _bassMult = bassMult; }
float getDryLevel() const { return _dryLevel; } float getBassFreq() const { return _bassFreq; }
void setDryLevel(float dryLevel) { _dryLevel = dryLevel; } void setBassFreq(float bassFreq) { _bassFreq = bassFreq; }
float getWetLevel() const { return _wetLevel; } float getHighGain() const { return _highGain; }
void setWetLevel(float wetLevel) { _wetLevel = wetLevel; } void setHighGain(float highGain) { _highGain = highGain; }
float getHighFreq() const { return _highFreq; }
void setHighFreq(float highFreq) { _highFreq = highFreq; }
float getModRate() const { return _modRate; }
void setModRate(float modRate) { _modRate = modRate; }
float getModDepth() const { return _modDepth; }
void setModDepth(float modDepth) { _modDepth = modDepth; }
float getEarlyGain() const { return _earlyGain; }
void setEarlyGain(float earlyGain) { _earlyGain = earlyGain; }
float getLateGain() const { return _lateGain; }
void setLateGain(float lateGain) { _lateGain = lateGain; }
float getEarlyMixLeft() const { return _earlyMixLeft; }
void setEarlyMixLeft(float earlyMixLeft) { _earlyMixLeft = earlyMixLeft; }
float getEarlyMixRight() const { return _earlyMixRight; }
void setEarlyMixRight(float earlyMixRight) { _earlyMixRight = earlyMixRight; }
float getLateMixLeft() const { return _lateMixLeft; }
void setLateMixLeft(float lateMixLeft) { _lateMixLeft = lateMixLeft; }
float getLateMixRight() const { return _lateMixRight; }
void setLateMixRight(float lateMixRight) { _lateMixRight = lateMixRight; }
float getWetDryMix() const { return _wetDryMix; }
void setWetDryMix(float wetDryMix) { _wetDryMix = wetDryMix; }
private: private:
// http://wiki.audacityteam.org/wiki/GVerb#Instant_Reverberb_settings float _bandwidth; // [20, 24000] Hz
// Meters Square float _preDelay; // [0, 333] ms
float _maxRoomSize; float _lateDelay; // [0, 166] ms
float _roomSize;
// Seconds float _reverbTime; // [0.1, 100] seconds
float _reverbTime;
// Ratio between 0 and 1 float _earlyDiffusion; // [0, 100] percent
float _damping; float _lateDiffusion; // [0, 100] percent
// ? (Does not appear to be set externally very often) float _roomSize; // [0, 100] percent
float _spread; float _density; // [0, 100] percent
// Ratio between 0 and 1 float _bassMult; // [0.1, 10] ratio
float _inputBandwidth; float _bassFreq; // [10, 500] Hz
float _highGain; // [-24, 0] dB
float _highFreq; // [1000, 12000] Hz
// dB float _modRate; // [0.1, 10] Hz
float _earlyLevel; float _modDepth; // [0, 100] percent
float _tailLevel;
float _dryLevel; float _earlyGain; // [-96, +24] dB
float _wetLevel; float _lateGain; // [-96, +24] dB
float _earlyMixLeft; // [0, 100] percent
float _earlyMixRight; // [0, 100] percent
float _lateMixLeft; // [0, 100] percent
float _lateMixRight; // [0, 100] percent
float _wetDryMix; // [0, 100] percent
}; };
#endif // hifi_AudioEffectOptions_h #endif // hifi_AudioEffectOptions_h

View file

@ -1625,10 +1625,10 @@ void AvatarData::setBodyRoll(float bodyRoll) {
setOrientation(glm::quat(glm::radians(eulerAngles))); setOrientation(glm::quat(glm::radians(eulerAngles)));
} }
void AvatarData::setPosition(const glm::vec3 position) { void AvatarData::setPosition(const glm::vec3& position) {
SpatiallyNestable::setPosition(position); SpatiallyNestable::setPosition(position);
} }
void AvatarData::setOrientation(const glm::quat orientation) { void AvatarData::setOrientation(const glm::quat& orientation) {
SpatiallyNestable::setOrientation(orientation); SpatiallyNestable::setOrientation(orientation);
} }

View file

@ -201,8 +201,8 @@ public:
float getBodyRoll() const; float getBodyRoll() const;
void setBodyRoll(float bodyRoll); void setBodyRoll(float bodyRoll);
virtual void setPosition(glm::vec3 position); virtual void setPosition(const glm::vec3& position) override;
virtual void setOrientation(glm::quat orientation); virtual void setOrientation(const glm::quat& orientation) override;
void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time. void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time.
void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc. void startCapture(); // start/end of the period in which the latest values are about to be captured for camera, etc.

View file

@ -54,6 +54,7 @@ public:
} }
virtual void run() override { virtual void run() override {
OpenGLDisplayPlugin* currentPlugin{ nullptr };
Q_ASSERT(_context); Q_ASSERT(_context);
while (!_shutdown) { while (!_shutdown) {
if (_pendingMainThreadOperation) { if (_pendingMainThreadOperation) {
@ -81,12 +82,13 @@ public:
// Check if we have a new plugin to activate // Check if we have a new plugin to activate
if (_newPlugin != nullptr) { if (_newPlugin != nullptr) {
// Deactivate the old plugin // Deactivate the old plugin
if (_activePlugin != nullptr) { if (currentPlugin != nullptr) {
_activePlugin->uncustomizeContext(); currentPlugin->uncustomizeContext();
currentPlugin->enableDeactivate();
} }
_newPlugin->customizeContext(); _newPlugin->customizeContext();
_activePlugin = _newPlugin; currentPlugin = _newPlugin;
_newPlugin = nullptr; _newPlugin = nullptr;
} }
_context->doneCurrent(); _context->doneCurrent();
@ -94,20 +96,21 @@ public:
} }
// If there's no active plugin, just sleep // If there's no active plugin, just sleep
if (_activePlugin == nullptr) { if (currentPlugin == nullptr) {
QThread::usleep(100); QThread::usleep(100);
continue; continue;
} }
// take the latest texture and present it // take the latest texture and present it
_context->makeCurrent(); _context->makeCurrent();
_activePlugin->present(); currentPlugin->present();
_context->doneCurrent(); _context->doneCurrent();
} }
_context->makeCurrent(); _context->makeCurrent();
if (_activePlugin) { if (currentPlugin) {
_activePlugin->uncustomizeContext(); currentPlugin->uncustomizeContext();
currentPlugin->enableDeactivate();
} }
_context->doneCurrent(); _context->doneCurrent();
_context->moveToThread(qApp->thread()); _context->moveToThread(qApp->thread());
@ -147,7 +150,6 @@ private:
bool _finishedMainThreadOperation { false }; bool _finishedMainThreadOperation { false };
QThread* _mainThread { nullptr }; QThread* _mainThread { nullptr };
OpenGLDisplayPlugin* _newPlugin { nullptr }; OpenGLDisplayPlugin* _newPlugin { nullptr };
OpenGLDisplayPlugin* _activePlugin { nullptr };
QGLContext* _context { nullptr }; QGLContext* _context { nullptr };
}; };
@ -208,11 +210,16 @@ void OpenGLDisplayPlugin::stop() {
} }
void OpenGLDisplayPlugin::deactivate() { void OpenGLDisplayPlugin::deactivate() {
{
Lock lock(_mutex);
_deactivateWait.wait(lock, [&]{ return _uncustomized; });
}
_timer.stop(); _timer.stop();
DisplayPlugin::deactivate(); DisplayPlugin::deactivate();
} }
void OpenGLDisplayPlugin::customizeContext() { void OpenGLDisplayPlugin::customizeContext() {
_uncustomized = false;
auto presentThread = DependencyManager::get<PresentThread>(); auto presentThread = DependencyManager::get<PresentThread>();
Q_ASSERT(thread() == presentThread->thread()); Q_ASSERT(thread() == presentThread->thread());
@ -233,6 +240,7 @@ void OpenGLDisplayPlugin::uncustomizeContext() {
_plane.reset(); _plane.reset();
} }
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the // Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to // SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
// receive keyPress events for the Alt (and Meta) key in a reliable manner. // receive keyPress events for the Alt (and Meta) key in a reliable manner.
@ -380,3 +388,9 @@ QImage OpenGLDisplayPlugin::getScreenshot() const {
}); });
return result; return result;
} }
void OpenGLDisplayPlugin::enableDeactivate() {
Lock lock(_mutex);
_uncustomized = true;
_deactivateWait.notify_one();
}

View file

@ -9,6 +9,8 @@
#include "DisplayPlugin.h" #include "DisplayPlugin.h"
#include <condition_variable>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <GLMHelpers.h> #include <GLMHelpers.h>
@ -18,8 +20,9 @@
class OpenGLDisplayPlugin : public DisplayPlugin { class OpenGLDisplayPlugin : public DisplayPlugin {
protected: protected:
using Mutex = std::recursive_mutex; using Mutex = std::mutex;
using Lock = std::unique_lock<Mutex>; using Lock = std::unique_lock<Mutex>;
using Condition = std::condition_variable;
public: public:
OpenGLDisplayPlugin(); OpenGLDisplayPlugin();
virtual void activate() override; virtual void activate() override;
@ -82,6 +85,12 @@ protected:
GLTextureEscrow _sceneTextureEscrow; GLTextureEscrow _sceneTextureEscrow;
bool _vsyncSupported { false }; bool _vsyncSupported { false };
private:
void enableDeactivate();
Condition _deactivateWait;
bool _uncustomized{ false };
}; };

View file

@ -41,6 +41,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
Q_ASSERT(getType() == EntityTypes::Box); Q_ASSERT(getType() == EntityTypes::Box);
Q_ASSERT(args->_batch); Q_ASSERT(args->_batch);
if (!_procedural) { if (!_procedural) {
_procedural.reset(new Procedural(this->getUserData())); _procedural.reset(new Procedural(this->getUserData()));
_procedural->_vertexSource = simple_vert; _procedural->_vertexSource = simple_vert;
@ -64,4 +65,6 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
} else { } else {
DependencyManager::get<DeferredLightingEffect>()->renderSolidCubeInstance(batch, getTransformToCenter(), cubeColor); DependencyManager::get<DeferredLightingEffect>()->renderSolidCubeInstance(batch, getTransformToCenter(), cubeColor);
} }
}; static const auto triCount = DependencyManager::get<GeometryCache>()->getCubeTriangleCount();
args->_details._trianglesRendered += triCount;
}

View file

@ -44,7 +44,7 @@ RenderableModelEntityItem::~RenderableModelEntityItem() {
} }
} }
void RenderableModelEntityItem::setDimensions(const glm::vec3 value) { void RenderableModelEntityItem::setDimensions(const glm::vec3& value) {
_dimensionsInitialized = true; _dimensionsInitialized = true;
ModelEntityItem::setDimensions(value); ModelEntityItem::setDimensions(value);
} }
@ -565,20 +565,20 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
return false; return false;
} }
glm::quat RenderableModelEntityItem::getJointRotation(int index) const { glm::quat RenderableModelEntityItem::getAbsoluteJointRotationInObjectFrame(int index) const {
if (_model) { if (_model) {
glm::quat result; glm::quat result;
if (_model->getJointRotation(index, result)) { if (_model->getAbsoluteJointRotationInRigFrame(index, result)) {
return result; return result;
} }
} }
return glm::quat(); return glm::quat();
} }
glm::vec3 RenderableModelEntityItem::getJointTranslation(int index) const { glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(int index) const {
if (_model) { if (_model) {
glm::vec3 result; glm::vec3 result;
if (_model->getJointTranslation(index, result)) { if (_model->getAbsoluteJointTranslationInRigFrame(index, result)) {
return result; return result;
} }
} }

View file

@ -28,7 +28,7 @@ public:
virtual ~RenderableModelEntityItem(); virtual ~RenderableModelEntityItem();
virtual void setDimensions(const glm::vec3 value) override; virtual void setDimensions(const glm::vec3& value) override;
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
virtual bool setProperties(const EntityItemProperties& properties) override; virtual bool setProperties(const EntityItemProperties& properties) override;
@ -67,9 +67,9 @@ public:
virtual bool contains(const glm::vec3& point) const override; virtual bool contains(const glm::vec3& point) const override;
// these are in the frame of this object // these are in the frame of this object (model space)
virtual glm::quat getJointRotation(int index) const override; virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
virtual glm::vec3 getJointTranslation(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override;
private: private:
void remapTextures(); void remapTextures();

View file

@ -71,4 +71,6 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
batch.setModelTransform(Transform()); batch.setModelTransform(Transform());
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, modelTransform, sphereColor); DependencyManager::get<DeferredLightingEffect>()->renderSolidSphereInstance(batch, modelTransform, sphereColor);
} }
}; static const auto triCount = DependencyManager::get<GeometryCache>()->getSphereTriangleCount();
args->_details._trianglesRendered += triCount;
}

View file

@ -628,71 +628,50 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID); bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) { // pack SimulationOwner and terse update properties near each other
// pack SimulationOwner and terse update properties near each other
// NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data // NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data
// even when we would otherwise ignore the rest of the packet. // even when we would otherwise ignore the rest of the packet.
if (propertyFlags.getHasProperty(PROP_SIMULATION_OWNER)) { if (propertyFlags.getHasProperty(PROP_SIMULATION_OWNER)) {
QByteArray simOwnerData; QByteArray simOwnerData;
int bytes = OctreePacketData::unpackDataFromBytes(dataAt, simOwnerData); int bytes = OctreePacketData::unpackDataFromBytes(dataAt, simOwnerData);
SimulationOwner newSimOwner; SimulationOwner newSimOwner;
newSimOwner.fromByteArray(simOwnerData); newSimOwner.fromByteArray(simOwnerData);
dataAt += bytes; dataAt += bytes;
bytesRead += bytes; bytesRead += bytes;
if (wantTerseEditLogging() && _simulationOwner != newSimOwner) { if (wantTerseEditLogging() && _simulationOwner != newSimOwner) {
qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << newSimOwner; qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << newSimOwner;
}
if (_simulationOwner.set(newSimOwner)) {
_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
}
} }
{ // When we own the simulation we don't accept updates to the entity's transform/velocities if (_simulationOwner.set(newSimOwner)) {
// but since we're using macros below we have to temporarily modify overwriteLocalData. _dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
bool oldOverwrite = overwriteLocalData;
overwriteLocalData = overwriteLocalData && !weOwnSimulation;
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition);
READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation);
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity);
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration);
overwriteLocalData = oldOverwrite;
} }
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions);
READ_ENTITY_PROPERTY(PROP_DENSITY, float, updateDensity);
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity);
READ_ENTITY_PROPERTY(PROP_DAMPING, float, updateDamping);
READ_ENTITY_PROPERTY(PROP_RESTITUTION, float, updateRestitution);
READ_ENTITY_PROPERTY(PROP_FRICTION, float, updateFriction);
READ_ENTITY_PROPERTY(PROP_LIFETIME, float, updateLifetime);
READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript);
READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp);
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint);
} else {
// legacy order of packing here
// TODO: purge this logic in a few months from now (2015.07)
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition);
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions);
READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation);
READ_ENTITY_PROPERTY(PROP_DENSITY, float, updateDensity);
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity);
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity);
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration);
READ_ENTITY_PROPERTY(PROP_DAMPING, float, updateDamping);
READ_ENTITY_PROPERTY(PROP_RESTITUTION, float, updateRestitution);
READ_ENTITY_PROPERTY(PROP_FRICTION, float, updateFriction);
READ_ENTITY_PROPERTY(PROP_LIFETIME, float, updateLifetime);
READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript);
READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp);
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint);
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
} }
{ // When we own the simulation we don't accept updates to the entity's transform/velocities
// but since we're using macros below we have to temporarily modify overwriteLocalData.
bool oldOverwrite = overwriteLocalData;
overwriteLocalData = overwriteLocalData && !weOwnSimulation;
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition);
READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation);
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity);
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration);
overwriteLocalData = oldOverwrite;
}
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions);
READ_ENTITY_PROPERTY(PROP_DENSITY, float, updateDensity);
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity);
READ_ENTITY_PROPERTY(PROP_DAMPING, float, updateDamping);
READ_ENTITY_PROPERTY(PROP_RESTITUTION, float, updateRestitution);
READ_ENTITY_PROPERTY(PROP_FRICTION, float, updateFriction);
READ_ENTITY_PROPERTY(PROP_LIFETIME, float, updateLifetime);
READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript);
READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp);
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint);
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, updateAngularDamping); READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, updateAngularDamping);
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible); READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
@ -701,17 +680,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked); READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked);
READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData); READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData);
if (args.bitstreamVersion < VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) {
// this code for when there is only simulatorID and no simulation priority
// we always accept the server's notion of simulatorID, so we fake overwriteLocalData as true
// before we try to READ_ENTITY_PROPERTY it
bool temp = overwriteLocalData;
overwriteLocalData = true;
READ_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, QUuid, updateSimulatorID);
overwriteLocalData = temp;
}
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_MARKETPLACE_ID) { if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_MARKETPLACE_ID) {
READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
} }
@ -1104,7 +1072,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false; bool somethingChanged = false;
// these affect TerseUpdate properties // these affect TerseUpdate properties
SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulationOwner, setSimulationOwner); SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulationOwner, updateSimulationOwner);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, updatePosition); SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, updatePosition);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, updateRotation); SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, updateRotation);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocity, updateVelocity); SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocity, updateVelocity);
@ -1192,7 +1160,7 @@ const Transform EntityItem::getTransformToCenter() const {
return result; return result;
} }
void EntityItem::setDimensions(const glm::vec3 value) { void EntityItem::setDimensions(const glm::vec3& value) {
if (value.x <= 0.0f || value.y <= 0.0f || value.z <= 0.0f) { if (value.x <= 0.0f || value.y <= 0.0f || value.z <= 0.0f) {
return; return;
} }
@ -1324,6 +1292,13 @@ void EntityItem::updatePosition(const glm::vec3& value) {
} }
if (getLocalPosition() != value) { if (getLocalPosition() != value) {
setLocalPosition(value); setLocalPosition(value);
_dirtyFlags |= Simulation::DIRTY_POSITION;
forEachDescendant([&](SpatiallyNestablePointer object) {
if (object->getNestableType() == NestableTypes::Entity) {
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
entity->_dirtyFlags |= Simulation::DIRTY_POSITION;
}
});
} }
} }
@ -1496,12 +1471,12 @@ void EntityItem::setSimulationOwner(const SimulationOwner& owner) {
_simulationOwner.set(owner); _simulationOwner.set(owner);
} }
void EntityItem::updateSimulatorID(const QUuid& value) { void EntityItem::updateSimulationOwner(const SimulationOwner& owner) {
if (wantTerseEditLogging() && _simulationOwner.getID() != value) { if (wantTerseEditLogging() && _simulationOwner != owner) {
qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << value; qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << owner;
} }
if (_simulationOwner.setID(value)) { if (_simulationOwner.set(owner)) {
_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID; _dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
} }
} }

View file

@ -178,7 +178,7 @@ public:
/// Dimensions in meters (0.0 - TREE_SCALE) /// Dimensions in meters (0.0 - TREE_SCALE)
inline const glm::vec3 getDimensions() const { return getScale(); } inline const glm::vec3 getDimensions() const { return getScale(); }
virtual void setDimensions(const glm::vec3 value); virtual void setDimensions(const glm::vec3& value);
float getGlowLevel() const { return _glowLevel; } float getGlowLevel() const { return _glowLevel; }
void setGlowLevel(float glowLevel) { _glowLevel = glowLevel; } void setGlowLevel(float glowLevel) { _glowLevel = glowLevel; }
@ -288,7 +288,7 @@ public:
quint8 getSimulationPriority() const { return _simulationOwner.getPriority(); } quint8 getSimulationPriority() const { return _simulationOwner.getPriority(); }
QUuid getSimulatorID() const { return _simulationOwner.getID(); } QUuid getSimulatorID() const { return _simulationOwner.getID(); }
void updateSimulatorID(const QUuid& value); void updateSimulationOwner(const SimulationOwner& owner);
void clearSimulationOwnership(); void clearSimulationOwnership();
const QString& getMarketplaceID() const { return _marketplaceID; } const QString& getMarketplaceID() const { return _marketplaceID; }
@ -379,8 +379,8 @@ public:
QList<EntityActionPointer> getActionsOfType(EntityActionType typeToGet); QList<EntityActionPointer> getActionsOfType(EntityActionType typeToGet);
// these are in the frame of this object // these are in the frame of this object
virtual glm::quat getJointRotation(int index) const { return glm::quat(); } virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override { return glm::quat(); }
virtual glm::vec3 getJointTranslation(int index) const { return glm::vec3(0.0f); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override { return glm::vec3(0.0f); }
protected: protected:

View file

@ -1780,6 +1780,12 @@ QList<QString> EntityItemProperties::listChangedProperties() {
if (zPNeighborIDChanged()) { if (zPNeighborIDChanged()) {
out += "zPNeighborID"; out += "zPNeighborID";
} }
if (parentIDChanged()) {
out += "parentID";
}
if (parentJointIndexChanged()) {
out += "parentJointIndex";
}
getAnimation().listChangedProperties(out); getAnimation().listChangedProperties(out);
getKeyLight().listChangedProperties(out); getKeyLight().listChangedProperties(out);
@ -1790,6 +1796,6 @@ QList<QString> EntityItemProperties::listChangedProperties() {
return out; return out;
} }
bool EntityItemProperties::parentDependentPropertyChanged() { bool EntityItemProperties::parentDependentPropertyChanged() const {
return localPositionChanged() || positionChanged() || localRotationChanged() || rotationChanged(); return localPositionChanged() || positionChanged() || localRotationChanged() || rotationChanged();
} }

View file

@ -83,7 +83,7 @@ public:
{ return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; } { return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; }
EntityPropertyFlags getChangedProperties() const; EntityPropertyFlags getChangedProperties() const;
bool parentDependentPropertyChanged(); // was there a changed in a property that requires parent info to interpret? bool parentDependentPropertyChanged() const; // was there a changed in a property that requires parent info to interpret?
AACube getMaximumAACube() const; AACube getMaximumAACube() const;
AABox getAABox() const; AABox getAABox() const;

View file

@ -64,7 +64,7 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
} }
} }
EntityItemProperties convertLocationToScriptSemantics(EntityItemProperties entitySideProperties) { EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties& entitySideProperties) {
// In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript, // In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript,
// they are in world-space. The local versions are put into localPosition and localRotation and position and // they are in world-space. The local versions are put into localPosition and localRotation and position and
// rotation are converted from local to world space. // rotation are converted from local to world space.
@ -85,7 +85,7 @@ EntityItemProperties convertLocationToScriptSemantics(EntityItemProperties entit
} }
EntityItemProperties convertLocationFromScriptSemantics(EntityItemProperties scriptSideProperties) { EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperties& scriptSideProperties) {
// convert position and rotation properties from world-space to local, unless localPosition and localRotation // convert position and rotation properties from world-space to local, unless localPosition and localRotation
// are set. If they are set, they overwrite position and rotation. // are set. If they are set, they overwrite position and rotation.
EntityItemProperties entitySideProperties = scriptSideProperties; EntityItemProperties entitySideProperties = scriptSideProperties;
@ -190,7 +190,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
return convertLocationToScriptSemantics(results); return convertLocationToScriptSemantics(results);
} }
QUuid EntityScriptingInterface::editEntity(QUuid id, EntityItemProperties scriptSideProperties) { QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) {
EntityItemProperties properties = scriptSideProperties; EntityItemProperties properties = scriptSideProperties;
EntityItemID entityID(id); EntityItemID entityID(id);
// If we have a local entity tree set, then also update it. // If we have a local entity tree set, then also update it.
@ -201,17 +201,25 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, EntityItemProperties script
bool updatedEntity = false; bool updatedEntity = false;
_entityTree->withWriteLock([&] { _entityTree->withWriteLock([&] {
if (scriptSideProperties.parentDependentPropertyChanged()) { if (scriptSideProperties.parentDependentPropertyChanged() ||
// if the script sets a location property but didn't include parent information, grab the needed scriptSideProperties.parentIDChanged() || scriptSideProperties.parentJointIndexChanged()) {
// properties from the entity. // All of parentID, parentJointIndex, position, rotation are needed to make sense of any of them.
if (!scriptSideProperties.parentIDChanged() || !scriptSideProperties.parentJointIndexChanged()) { // If any of these changed, pull any missing properties from the entity.
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
if (entity && !scriptSideProperties.parentIDChanged()) { if (!entity) {
properties.setParentID(entity->getParentID()); return;
} }
if (entity && !scriptSideProperties.parentJointIndexChanged()) { if (!scriptSideProperties.parentIDChanged()) {
properties.setParentJointIndex(entity->getParentJointIndex()); properties.setParentID(entity->getParentID());
} }
if (!scriptSideProperties.parentJointIndexChanged()) {
properties.setParentJointIndex(entity->getParentJointIndex());
}
if (!scriptSideProperties.localPositionChanged() && !scriptSideProperties.positionChanged()) {
properties.setPosition(entity->getPosition());
}
if (!scriptSideProperties.localRotationChanged() && !scriptSideProperties.rotationChanged()) {
properties.setRotation(entity->getOrientation());
} }
} }
properties = convertLocationFromScriptSemantics(properties); properties = convertLocationFromScriptSemantics(properties);
@ -801,19 +809,19 @@ glm::vec3 EntityScriptingInterface::localCoordsToVoxelCoords(const QUuid& entity
} }
} }
glm::vec3 EntityScriptingInterface::getJointTranslation(const QUuid& entityID, int jointIndex) { glm::vec3 EntityScriptingInterface::getAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex) {
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity); auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
return modelEntity->getJointTranslation(jointIndex); return modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex);
} else { } else {
return glm::vec3(0.0f); return glm::vec3(0.0f);
} }
} }
glm::quat EntityScriptingInterface::getJointRotation(const QUuid& entityID, int jointIndex) { glm::quat EntityScriptingInterface::getAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex) {
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity); auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
return modelEntity->getJointRotation(jointIndex); return modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex);
} else { } else {
return glm::quat(); return glm::quat();
} }

View file

@ -86,7 +86,7 @@ public slots:
/// edits a model updating only the included properties, will return the identified EntityItemID in case of /// edits a model updating only the included properties, will return the identified EntityItemID in case of
/// successful edit, if the input entityID is for an unknown model this function will have no effect /// successful edit, if the input entityID is for an unknown model this function will have no effect
Q_INVOKABLE QUuid editEntity(QUuid entityID, EntityItemProperties properties); Q_INVOKABLE QUuid editEntity(QUuid entityID, const EntityItemProperties& properties);
/// deletes a model /// deletes a model
Q_INVOKABLE void deleteEntity(QUuid entityID); Q_INVOKABLE void deleteEntity(QUuid entityID);
@ -148,9 +148,9 @@ public slots:
Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords); Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords);
Q_INVOKABLE glm::vec3 voxelCoordsToLocalCoords(const QUuid& entityID, glm::vec3 voxelCoords); Q_INVOKABLE glm::vec3 voxelCoordsToLocalCoords(const QUuid& entityID, glm::vec3 voxelCoords);
Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords); Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords);
Q_INVOKABLE glm::vec3 getJointTranslation(const QUuid& entityID, int jointIndex); Q_INVOKABLE glm::vec3 getAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex);
Q_INVOKABLE glm::quat getJointRotation(const QUuid& entityID, int jointIndex); Q_INVOKABLE glm::quat getAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex);
signals: signals:
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);

View file

@ -24,6 +24,7 @@
#include "EntitiesLogging.h" #include "EntitiesLogging.h"
#include "RecurseOctreeToMapOperator.h" #include "RecurseOctreeToMapOperator.h"
#include "LogHandler.h" #include "LogHandler.h"
#include "RemapIDOperator.h"
static const quint64 DELETED_ENTITIES_EXTRA_USECS_TO_CONSIDER = USECS_PER_MSEC * 50; static const quint64 DELETED_ENTITIES_EXTRA_USECS_TO_CONSIDER = USECS_PER_MSEC * 50;
@ -740,6 +741,14 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList<Q
changedProperties[index] = QString("userData:") + changeHint; changedProperties[index] = QString("userData:") + changeHint;
} }
} }
if (properties.parentJointIndexChanged()) {
int index = changedProperties.indexOf("parentJointIndex");
if (index >= 0) {
quint16 value = properties.getParentJointIndex();
changedProperties[index] = QString("parentJointIndex:") + QString::number((int)value);
}
}
} }
int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength,
@ -1186,6 +1195,11 @@ bool EntityTree::sendEntitiesOperation(OctreeElementPointer element, void* extra
return true; return true;
} }
void EntityTree::remapIDs() {
RemapIDOperator theOperator;
recurseTreeWithOperator(&theOperator);
}
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) { bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) {
if (! entityDescription.contains("Entities")) { if (! entityDescription.contains("Entities")) {
entityDescription["Entities"] = QVariantList(); entityDescription["Entities"] = QVariantList();

View file

@ -196,6 +196,8 @@ public:
bool wantTerseEditLogging() const { return _wantTerseEditLogging; } bool wantTerseEditLogging() const { return _wantTerseEditLogging; }
void setWantTerseEditLogging(bool value) { _wantTerseEditLogging = value; } void setWantTerseEditLogging(bool value) { _wantTerseEditLogging = value; }
void remapIDs();
bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues); bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues);
bool readFromMap(QVariantMap& entityDescription); bool readFromMap(QVariantMap& entityDescription);

View file

@ -40,7 +40,7 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID) : EntityItem(
_cutoff = PI; _cutoff = PI;
} }
void LightEntityItem::setDimensions(const glm::vec3 value) { void LightEntityItem::setDimensions(const glm::vec3& value) {
if (_isSpotlight) { if (_isSpotlight) {
// If we are a spotlight, treat the z value as our radius or length, and // If we are a spotlight, treat the z value as our radius or length, and
// recalculate the x/y dimensions to properly encapsulate the spotlight. // recalculate the x/y dimensions to properly encapsulate the spotlight.

View file

@ -23,7 +23,7 @@ public:
ALLOW_INSTANTIATION // This class can be instantiated ALLOW_INSTANTIATION // This class can be instantiated
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
virtual void setDimensions(const glm::vec3 value); virtual void setDimensions(const glm::vec3& value);
// methods for getting/setting all properties of an entity // methods for getting/setting all properties of an entity
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const; virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;

View file

@ -0,0 +1,33 @@
//
// RemapIDOperator.cpp
// libraries/entities/src
//
// Created by Seth Alves on 2015-12-6.
// 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 "EntityTree.h"
#include "RemapIDOperator.h"
QUuid RemapIDOperator::remap(const QUuid& oldID) {
if (oldID.isNull()) {
return oldID;
}
if (!_oldToNew.contains(oldID)) {
_oldToNew[oldID] = QUuid::createUuid();
}
return _oldToNew[oldID];
}
bool RemapIDOperator::postRecursion(OctreeElementPointer element) {
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
entityTreeElement->forEachEntity([&](EntityItemPointer entityItem) {
entityItem->setID(remap(entityItem->getID()));
entityItem->setParentID(remap(entityItem->getParentID()));
});
return true;
}

View file

@ -0,0 +1,30 @@
//
// RemapIDOperator.h
// libraries/entities/src
//
// Created by Seth Alves on 2015-12-6.
// 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_RemapIDOperator_h
#define hifi_RemapIDOperator_h
#include "Octree.h"
// this will change all the IDs in an EntityTree. Parent/Child relationships are maintained.
class RemapIDOperator : public RecurseOctreeOperator {
public:
RemapIDOperator() : RecurseOctreeOperator() {}
~RemapIDOperator() {}
virtual bool preRecursion(OctreeElementPointer element) { return true; }
virtual bool postRecursion(OctreeElementPointer element);
private:
QUuid remap(const QUuid& oldID);
QHash<QUuid, QUuid> _oldToNew;
};
#endif // hifi_RemapIDOperator_h

View file

@ -41,7 +41,7 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID) : EntityItem(en
const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f; const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
void TextEntityItem::setDimensions(const glm::vec3 value) { void TextEntityItem::setDimensions(const glm::vec3& value) {
// NOTE: Text Entities always have a "depth" of 1cm. // NOTE: Text Entities always have a "depth" of 1cm.
EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH)); EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
} }

View file

@ -23,7 +23,7 @@ public:
ALLOW_INSTANTIATION // This class can be instantiated ALLOW_INSTANTIATION // This class can be instantiated
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
virtual void setDimensions(const glm::vec3 value); virtual void setDimensions(const glm::vec3& value);
virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; } virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
// methods for getting/setting all properties of an entity // methods for getting/setting all properties of an entity

View file

@ -34,7 +34,7 @@ WebEntityItem::WebEntityItem(const EntityItemID& entityItemID) : EntityItem(enti
const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f; const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
void WebEntityItem::setDimensions(const glm::vec3 value) { void WebEntityItem::setDimensions(const glm::vec3& value) {
// NOTE: Web Entities always have a "depth" of 1cm. // NOTE: Web Entities always have a "depth" of 1cm.
EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH)); EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
} }

View file

@ -22,7 +22,7 @@ public:
ALLOW_INSTANTIATION // This class can be instantiated ALLOW_INSTANTIATION // This class can be instantiated
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
virtual void setDimensions(const glm::vec3 value); virtual void setDimensions(const glm::vec3& value);
virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; } virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
// methods for getting/setting all properties of an entity // methods for getting/setting all properties of an entity

View file

@ -296,8 +296,6 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
if (matchingNode) { if (matchingNode) {
emit dataReceived(matchingNode->getType(), receivedMessage->getSize()); emit dataReceived(matchingNode->getType(), receivedMessage->getSize());
matchingNode->recordBytesReceived(receivedMessage->getSize()); matchingNode->recordBytesReceived(receivedMessage->getSize());
Node* n = matchingNode.data();
auto addr = n->getActiveSocket();
QMetaMethod metaMethod = listener.method; QMetaMethod metaMethod = listener.method;

View file

@ -22,8 +22,8 @@ static const int HEAD_DATA_SIZE = 512;
ReceivedMessage::ReceivedMessage(const NLPacketList& packetList) ReceivedMessage::ReceivedMessage(const NLPacketList& packetList)
: _data(packetList.getMessage()), : _data(packetList.getMessage()),
_headData(_data.mid(0, HEAD_DATA_SIZE)), _headData(_data.mid(0, HEAD_DATA_SIZE)),
_sourceID(packetList.getSourceID()),
_numPackets(packetList.getNumPackets()), _numPackets(packetList.getNumPackets()),
_sourceID(packetList.getSourceID()),
_packetType(packetList.getType()), _packetType(packetList.getType()),
_packetVersion(packetList.getVersion()), _packetVersion(packetList.getVersion()),
_senderSockAddr(packetList.getSenderSockAddr()), _senderSockAddr(packetList.getSenderSockAddr()),
@ -34,8 +34,8 @@ ReceivedMessage::ReceivedMessage(const NLPacketList& packetList)
ReceivedMessage::ReceivedMessage(NLPacket& packet) ReceivedMessage::ReceivedMessage(NLPacket& packet)
: _data(packet.readAll()), : _data(packet.readAll()),
_headData(_data.mid(0, HEAD_DATA_SIZE)), _headData(_data.mid(0, HEAD_DATA_SIZE)),
_sourceID(packet.getSourceID()),
_numPackets(1), _numPackets(1),
_sourceID(packet.getSourceID()),
_packetType(packet.getType()), _packetType(packet.getType()),
_packetVersion(packet.getVersion()), _packetVersion(packet.getVersion()),
_senderSockAddr(packet.getSenderSockAddr()), _senderSockAddr(packet.getSenderSockAddr()),

View file

@ -214,6 +214,19 @@ VertexVector tesselate(const VertexVector& startingTriangles, int count) {
return triangles; return triangles;
} }
size_t GeometryCache::getShapeTriangleCount(Shape shape) {
return _shapes[shape]._indexCount / VERTICES_PER_TRIANGLE;
}
size_t GeometryCache::getSphereTriangleCount() {
return getShapeTriangleCount(Sphere);
}
size_t GeometryCache::getCubeTriangleCount() {
return getShapeTriangleCount(Cube);
}
// FIXME solids need per-face vertices, but smooth shaded // FIXME solids need per-face vertices, but smooth shaded
// components do not. Find a way to support using draw elements // components do not. Find a way to support using draw elements
// or draw arrays as appropriate // or draw arrays as appropriate
@ -1727,3 +1740,4 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) {
batch.setPipeline(_standardDrawPipeline); batch.setPipeline(_standardDrawPipeline);
} }
} }

View file

@ -151,16 +151,19 @@ public:
void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer); void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer);
void renderShape(gpu::Batch& batch, Shape shape); void renderShape(gpu::Batch& batch, Shape shape);
void renderWireShape(gpu::Batch& batch, Shape shape); void renderWireShape(gpu::Batch& batch, Shape shape);
size_t getShapeTriangleCount(Shape shape);
void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
void renderCube(gpu::Batch& batch); void renderCube(gpu::Batch& batch);
void renderWireCube(gpu::Batch& batch); void renderWireCube(gpu::Batch& batch);
size_t getCubeTriangleCount();
void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer);
void renderSphere(gpu::Batch& batch); void renderSphere(gpu::Batch& batch);
void renderWireSphere(gpu::Batch& batch); void renderWireSphere(gpu::Batch& batch);
size_t getSphereTriangleCount();
void renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color); void renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color);
void renderGrid(gpu::Batch& batch, int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id = UNKNOWN_ID); void renderGrid(gpu::Batch& batch, int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id = UNKNOWN_ID);

View file

@ -766,6 +766,14 @@ bool Model::getJointTranslation(int jointIndex, glm::vec3& translation) const {
return _rig->getJointTranslation(jointIndex, translation); return _rig->getJointTranslation(jointIndex, translation);
} }
bool Model::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const {
return _rig->getAbsoluteJointRotationInRigFrame(jointIndex, rotation);
}
bool Model::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const {
return _rig->getAbsoluteJointTranslationInRigFrame(jointIndex, translation);
}
bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const { bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const {
return _rig->getJointCombinedRotation(jointIndex, rotation, _rotation); return _rig->getJointCombinedRotation(jointIndex, rotation, _rotation);
} }

View file

@ -166,6 +166,10 @@ public:
bool getJointRotation(int jointIndex, glm::quat& rotation) const; bool getJointRotation(int jointIndex, glm::quat& rotation) const;
bool getJointTranslation(int jointIndex, glm::vec3& translation) const; bool getJointTranslation(int jointIndex, glm::vec3& translation) const;
// model frame
bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const;
bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const;
/// Returns the index of the parent of the indexed joint, or -1 if not found. /// Returns the index of the parent of the indexed joint, or -1 if not found.
int getParentJointIndex(int jointIndex) const; int getParentJointIndex(int jointIndex) const;

View file

@ -65,7 +65,7 @@ void PIDController::updateHistory(float measuredValue, float dt, float error, fl
} }
} }
void PIDController::reportHistory() { void PIDController::reportHistory() {
qCDebug(shared) << _label << "measured dt FIXME || error accumulated changed || p i d controlled"; qCDebug(shared) << _label << "measured dt || error accumulated changed || p i d controlled";
for (int i = 0; i < _history.size(); i++) { for (int i = 0; i < _history.size(); i++) {
Row& row = _history[i]; Row& row = _history[i];
qCDebug(shared) << row.measured << row.dt << qCDebug(shared) << row.measured << row.dt <<

View file

@ -91,7 +91,7 @@ void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const {
}); });
} }
void SpatiallyNestable::setParentID(const QUuid parentID) { void SpatiallyNestable::setParentID(const QUuid& parentID) {
if (_parentID != parentID) { if (_parentID != parentID) {
_parentID = parentID; _parentID = parentID;
_parentKnowsMe = false; _parentKnowsMe = false;
@ -99,7 +99,7 @@ void SpatiallyNestable::setParentID(const QUuid parentID) {
parentChanged(); parentChanged();
} }
glm::vec3 SpatiallyNestable::worldToLocal(glm::vec3 position, QUuid parentID, int parentJointIndex) { glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex) {
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
Transform parentTransform; Transform parentTransform;
if (parentFinder) { if (parentFinder) {
@ -122,7 +122,7 @@ glm::vec3 SpatiallyNestable::worldToLocal(glm::vec3 position, QUuid parentID, in
return result.getTranslation(); return result.getTranslation();
} }
glm::quat SpatiallyNestable::worldToLocal(glm::quat orientation, QUuid parentID, int parentJointIndex) { glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex) {
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
Transform parentTransform; Transform parentTransform;
if (parentFinder) { if (parentFinder) {
@ -144,7 +144,7 @@ glm::quat SpatiallyNestable::worldToLocal(glm::quat orientation, QUuid parentID,
return result.getRotation(); return result.getRotation();
} }
glm::vec3 SpatiallyNestable::localToWorld(glm::vec3 position, QUuid parentID, int parentJointIndex) { glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex) {
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
Transform parentTransform; Transform parentTransform;
if (parentFinder) { if (parentFinder) {
@ -162,7 +162,7 @@ glm::vec3 SpatiallyNestable::localToWorld(glm::vec3 position, QUuid parentID, in
return result.getTranslation(); return result.getTranslation();
} }
glm::quat SpatiallyNestable::localToWorld(glm::quat orientation, QUuid parentID, int parentJointIndex) { glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex) {
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
Transform parentTransform; Transform parentTransform;
if (parentFinder) { if (parentFinder) {
@ -188,7 +188,7 @@ glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const {
return getTransform(jointIndex).getTranslation(); return getTransform(jointIndex).getTranslation();
} }
void SpatiallyNestable::setPosition(glm::vec3 position) { void SpatiallyNestable::setPosition(const glm::vec3& position) {
Transform parentTransform = getParentTransform(); Transform parentTransform = getParentTransform();
Transform myWorldTransform; Transform myWorldTransform;
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
@ -207,7 +207,7 @@ glm::quat SpatiallyNestable::getOrientation(int jointIndex) const {
return getTransform(jointIndex).getRotation(); return getTransform(jointIndex).getRotation();
} }
void SpatiallyNestable::setOrientation(glm::quat orientation) { void SpatiallyNestable::setOrientation(const glm::quat& orientation) {
Transform parentTransform = getParentTransform(); Transform parentTransform = getParentTransform();
Transform myWorldTransform; Transform myWorldTransform;
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
@ -232,13 +232,13 @@ const Transform SpatiallyNestable::getTransform(int jointIndex) const {
// this returns the world-space transform for this object. It finds its parent's transform (which may // this returns the world-space transform for this object. It finds its parent's transform (which may
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it. // cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
Transform worldTransform = getTransform(); Transform worldTransform = getTransform();
Transform jointInObjectFrame = getJointTransformInObjectFrame(jointIndex); Transform jointInObjectFrame = getAbsoluteJointTransformInObjectFrame(jointIndex);
Transform jointInWorldFrame; Transform jointInWorldFrame;
Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame); Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame);
return jointInWorldFrame; return jointInWorldFrame;
} }
void SpatiallyNestable::setTransform(const Transform transform) { void SpatiallyNestable::setTransform(const Transform& transform) {
Transform parentTransform = getParentTransform(); Transform parentTransform = getParentTransform();
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
Transform::inverseMult(_transform, parentTransform, transform); Transform::inverseMult(_transform, parentTransform, transform);
@ -259,7 +259,7 @@ glm::vec3 SpatiallyNestable::getScale(int jointIndex) const {
return getScale(); return getScale();
} }
void SpatiallyNestable::setScale(glm::vec3 scale) { void SpatiallyNestable::setScale(const glm::vec3& scale) {
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
_transform.setScale(scale); _transform.setScale(scale);
}); });
@ -274,7 +274,7 @@ const Transform SpatiallyNestable::getLocalTransform() const {
return result; return result;
} }
void SpatiallyNestable::setLocalTransform(const Transform transform) { void SpatiallyNestable::setLocalTransform(const Transform& transform) {
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
_transform = transform; _transform = transform;
}); });
@ -289,7 +289,7 @@ glm::vec3 SpatiallyNestable::getLocalPosition() const {
return result; return result;
} }
void SpatiallyNestable::setLocalPosition(glm::vec3 position) { void SpatiallyNestable::setLocalPosition(const glm::vec3& position) {
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
_transform.setTranslation(position); _transform.setTranslation(position);
}); });
@ -304,7 +304,7 @@ glm::quat SpatiallyNestable::getLocalOrientation() const {
return result; return result;
} }
void SpatiallyNestable::setLocalOrientation(glm::quat orientation) { void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) {
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
_transform.setRotation(orientation); _transform.setRotation(orientation);
}); });
@ -319,7 +319,7 @@ glm::vec3 SpatiallyNestable::getLocalScale() const {
return result; return result;
} }
void SpatiallyNestable::setLocalScale(glm::vec3 scale) { void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
_transformLock.withWriteLock([&] { _transformLock.withWriteLock([&] {
_transform.setScale(scale); _transform.setScale(scale);
}); });
@ -339,13 +339,13 @@ QList<SpatiallyNestablePointer> SpatiallyNestable::getChildren() const {
return children; return children;
} }
const Transform SpatiallyNestable::getJointTransformInObjectFrame(int jointIndex) const { const Transform SpatiallyNestable::getAbsoluteJointTransformInObjectFrame(int jointIndex) const {
Transform jointInObjectFrame; Transform jointTransformInObjectFrame;
glm::vec3 position = getJointTranslation(jointIndex); glm::vec3 position = getAbsoluteJointTranslationInObjectFrame(jointIndex);
glm::quat orientation = getJointRotation(jointIndex); glm::quat orientation = getAbsoluteJointRotationInObjectFrame(jointIndex);
jointInObjectFrame.setRotation(orientation); jointTransformInObjectFrame.setRotation(orientation);
jointInObjectFrame.setTranslation(position); jointTransformInObjectFrame.setTranslation(position);
return jointInObjectFrame; return jointTransformInObjectFrame;
} }
SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const { SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const {

View file

@ -42,32 +42,32 @@ public:
virtual void setID(const QUuid& id) { _id = id; } virtual void setID(const QUuid& id) { _id = id; }
virtual const QUuid getParentID() const { return _parentID; } virtual const QUuid getParentID() const { return _parentID; }
virtual void setParentID(const QUuid parentID); virtual void setParentID(const QUuid& parentID);
virtual quint16 getParentJointIndex() const { return _parentJointIndex; } virtual quint16 getParentJointIndex() const { return _parentJointIndex; }
virtual void setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; } virtual void setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; }
static glm::vec3 worldToLocal(glm::vec3 position, QUuid parentID, int parentJointIndex); static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex);
static glm::quat worldToLocal(glm::quat orientation, QUuid parentID, int parentJointIndex); static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex);
static glm::vec3 localToWorld(glm::vec3 position, QUuid parentID, int parentJointIndex); static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex);
static glm::quat localToWorld(glm::quat orientation, QUuid parentID, int parentJointIndex); static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex);
// world frame // world frame
virtual const Transform getTransform() const; virtual const Transform getTransform() const;
virtual void setTransform(const Transform transform); virtual void setTransform(const Transform& transform);
virtual Transform getParentTransform() const; virtual Transform getParentTransform() const;
virtual glm::vec3 getPosition() const; virtual glm::vec3 getPosition() const;
virtual void setPosition(glm::vec3 position); virtual void setPosition(const glm::vec3& position);
virtual glm::quat getOrientation() const; virtual glm::quat getOrientation() const;
virtual glm::quat getOrientation(int jointIndex) const; virtual glm::quat getOrientation(int jointIndex) const;
virtual void setOrientation(glm::quat orientation); virtual void setOrientation(const glm::quat& orientation);
virtual glm::vec3 getScale() const; virtual glm::vec3 getScale() const;
virtual void setScale(glm::vec3 scale); virtual void setScale(const glm::vec3& scale);
// get world-frame values for a specific joint // get world-frame values for a specific joint
virtual const Transform getTransform(int jointIndex) const; virtual const Transform getTransform(int jointIndex) const;
@ -76,24 +76,24 @@ public:
// object's parent's frame // object's parent's frame
virtual const Transform getLocalTransform() const; virtual const Transform getLocalTransform() const;
virtual void setLocalTransform(const Transform transform); virtual void setLocalTransform(const Transform& transform);
virtual glm::vec3 getLocalPosition() const; virtual glm::vec3 getLocalPosition() const;
virtual void setLocalPosition(glm::vec3 position); virtual void setLocalPosition(const glm::vec3& position);
virtual glm::quat getLocalOrientation() const; virtual glm::quat getLocalOrientation() const;
virtual void setLocalOrientation(glm::quat orientation); virtual void setLocalOrientation(const glm::quat& orientation);
virtual glm::vec3 getLocalScale() const; virtual glm::vec3 getLocalScale() const;
virtual void setLocalScale(glm::vec3 scale); virtual void setLocalScale(const glm::vec3& scale);
QList<SpatiallyNestablePointer> getChildren() const; QList<SpatiallyNestablePointer> getChildren() const;
NestableTypes::NestableType getNestableType() const { return _nestableType; } NestableTypes::NestableType getNestableType() const { return _nestableType; }
// this object's frame // this object's frame
virtual const Transform getJointTransformInObjectFrame(int jointIndex) const; virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
virtual glm::quat getJointRotation(int index) const { assert(false); return glm::quat(); } virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { assert(false); return glm::quat(); }
virtual glm::vec3 getJointTranslation(int index) const { assert(false); return glm::vec3(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { assert(false); return glm::vec3(); }
SpatiallyNestablePointer getThisPointer() const; SpatiallyNestablePointer getThisPointer() const;

View file

@ -230,7 +230,7 @@ void OculusDisplayPlugin::internalPresent() {
viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1]; viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1];
ovrLayerHeader* layers = &_sceneLayer.Header; ovrLayerHeader* layers = &_sceneLayer.Header;
ovrResult result = ovr_SubmitFrame(_hmd, 0, &viewScaleDesc, &layers, 1); ovrResult result = ovr_SubmitFrame(_hmd, frameIndex, &viewScaleDesc, &layers, 1);
if (!OVR_SUCCESS(result)) { if (!OVR_SUCCESS(result)) {
qDebug() << result; qDebug() << result;
} }

View file

@ -1,16 +1,20 @@
set(TARGET_NAME "stack-manager") set(TARGET_NAME "stack-manager")
set(BUILD_BUNDLE YES) set(BUILD_BUNDLE YES)
setup_hifi_project(Widgets Gui Svg Core Network WebKitWidgets) setup_hifi_project(Widgets Gui Svg Core Network WebKitWidgets)
add_dependencies(${TARGET_NAME} assignment-client domain-server)
include_application_version()
if (WIN32) if (WIN32)
target_zlib() target_zlib()
endif () endif ()
target_quazip() target_quazip()
set_target_properties( if (UNIX)
${TARGET_NAME} PROPERTIES set_target_properties(
EXCLUDE_FROM_ALL TRUE ${TARGET_NAME} PROPERTIES
) EXCLUDE_FROM_ALL TRUE
)
endif (UNIX)
if (DEFINED ENV{JOB_ID}) if (DEFINED ENV{JOB_ID})
set(PR_BUILD "false") set(PR_BUILD "false")
@ -45,4 +49,5 @@ if (APPLE)
set(SM_SRCS ${SM_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/assets/icon.icns") set(SM_SRCS ${SM_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/assets/icon.icns")
endif () endif ()
package_libraries_for_deployment() package_libraries_for_deployment()
consolidate_stack_components()

View file

@ -81,10 +81,6 @@ void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const Q
AppDelegate::AppDelegate(int argc, char* argv[]) : AppDelegate::AppDelegate(int argc, char* argv[]) :
QApplication(argc, argv), QApplication(argc, argv),
_qtReady(false),
_dsReady(false),
_dsResourcesReady(false),
_acReady(false),
_domainServerProcess(NULL), _domainServerProcess(NULL),
_acMonitorProcess(NULL), _acMonitorProcess(NULL),
_domainServerName("localhost") _domainServerName("localhost")
@ -115,14 +111,15 @@ AppDelegate::AppDelegate(int argc, char* argv[]) :
_window = new MainWindow(); _window = new MainWindow();
createExecutablePath();
downloadLatestExecutablesAndRequirements();
_checkVersionTimer.setInterval(0); _checkVersionTimer.setInterval(0);
connect(&_checkVersionTimer, SIGNAL(timeout()), this, SLOT(checkVersion())); connect(&_checkVersionTimer, SIGNAL(timeout()), this, SLOT(checkVersion()));
_checkVersionTimer.start(); _checkVersionTimer.start();
connect(this, &QApplication::aboutToQuit, this, &AppDelegate::stopStack); connect(this, &QApplication::aboutToQuit, this, &AppDelegate::stopStack);
_window->setRequirementsLastChecked(QDateTime::currentDateTime().toString());
_window->show();
toggleStack(true);
} }
AppDelegate::~AppDelegate() { AppDelegate::~AppDelegate() {
@ -427,227 +424,6 @@ void AppDelegate::handleContentSetDownloadFinished() {
emit domainAddressChanged(); emit domainAddressChanged();
} }
void AppDelegate::onFileSuccessfullyInstalled(const QUrl& url) {
if (url == GlobalData::getInstance().getRequirementsURL()) {
_qtReady = true;
} else if (url == GlobalData::getInstance().getAssignmentClientURL()) {
_acReady = true;
} else if (url == GlobalData::getInstance().getDomainServerURL()) {
_dsReady = true;
} else if (url == GlobalData::getInstance().getDomainServerResourcesURL()) {
_dsResourcesReady = true;
}
if (_qtReady && _acReady && _dsReady && _dsResourcesReady) {
_window->setRequirementsLastChecked(QDateTime::currentDateTime().toString());
_window->show();
toggleStack(true);
}
}
void AppDelegate::createExecutablePath() {
QDir launchDir(GlobalData::getInstance().getClientsLaunchPath());
QDir resourcesDir(GlobalData::getInstance().getClientsResourcesPath());
QDir logsDir(GlobalData::getInstance().getLogsPath());
if (!launchDir.exists()) {
if (QDir().mkpath(launchDir.absolutePath())) {
qDebug() << "Successfully created directory: "
<< launchDir.absolutePath();
} else {
qCritical() << "Failed to create directory: "
<< launchDir.absolutePath();
}
}
if (!resourcesDir.exists()) {
if (QDir().mkpath(resourcesDir.absolutePath())) {
qDebug() << "Successfully created directory: "
<< resourcesDir.absolutePath();
} else {
qCritical() << "Failed to create directory: "
<< resourcesDir.absolutePath();
}
}
if (!logsDir.exists()) {
if (QDir().mkpath(logsDir.absolutePath())) {
qDebug() << "Successfully created directory: "
<< logsDir.absolutePath();
} else {
qCritical() << "Failed to create directory: "
<< logsDir.absolutePath();
}
}
}
void AppDelegate::downloadLatestExecutablesAndRequirements() {
// Check if Qt is already installed
if (GlobalData::getInstance().getPlatform() == "mac") {
if (QDir(GlobalData::getInstance().getClientsLaunchPath() + "QtCore.framework").exists()) {
_qtReady = true;
}
} else if (GlobalData::getInstance().getPlatform() == "win") {
if (QFileInfo(GlobalData::getInstance().getClientsLaunchPath() + "Qt5Core.dll").exists()) {
_qtReady = true;
}
} else { // linux
if (QFileInfo(GlobalData::getInstance().getClientsLaunchPath() + "libQt5Core.so.5").exists()) {
_qtReady = true;
}
}
QFile reqZipFile(GlobalData::getInstance().getRequirementsZipPath());
QByteArray reqZipData;
if (reqZipFile.open(QIODevice::ReadOnly)) {
reqZipData = reqZipFile.readAll();
reqZipFile.close();
}
QFile resZipFile(GlobalData::getInstance().getDomainServerResourcesZipPath());
QByteArray resZipData;
if (resZipFile.open(QIODevice::ReadOnly)) {
resZipData = resZipFile.readAll();
resZipFile.close();
}
QDir resourcesDir(GlobalData::getInstance().getClientsResourcesPath());
if (!(resourcesDir.entryInfoList(QDir::AllEntries).size() < 3)) {
_dsResourcesReady = true;
}
// if the user has set hifiBuildDirectory, don't attempt to download the domain-server or assignement-client
if (GlobalData::getInstance().isGetHifiBuildDirectorySet()) {
_dsReady = true;
_acReady = true;
} else {
QByteArray dsData;
QFile dsFile(GlobalData::getInstance().getDomainServerExecutablePath());
if (dsFile.open(QIODevice::ReadOnly)) {
dsData = dsFile.readAll();
dsFile.close();
}
QByteArray acData;
QFile acFile(GlobalData::getInstance().getAssignmentClientExecutablePath());
if (acFile.open(QIODevice::ReadOnly)) {
acData = acFile.readAll();
acFile.close();
}
QNetworkRequest acReq(QUrl(GlobalData::getInstance().getAssignmentClientMD5URL()));
QNetworkReply* acReply = _manager->get(acReq);
QEventLoop acLoop;
connect(acReply, SIGNAL(finished()), &acLoop, SLOT(quit()));
acLoop.exec();
QByteArray acMd5Data = acReply->readAll().trimmed();
if (GlobalData::getInstance().getPlatform() == "win") {
// fix for reading the MD5 hash from Windows-generated
// binary data of the MD5 hash
QTextStream stream(acMd5Data);
stream >> acMd5Data;
}
// fix for Mac and Linux network accessibility
if (acMd5Data.size() == 0) {
// network is not accessible
qDebug() << "Could not connect to the internet.";
_window->show();
return;
}
qDebug() << "AC MD5: " << acMd5Data;
if (acMd5Data.toLower() == QCryptographicHash::hash(acData, QCryptographicHash::Md5).toHex()) {
_acReady = true;
}
QNetworkRequest dsReq(QUrl(GlobalData::getInstance().getDomainServerMD5URL()));
QNetworkReply* dsReply = _manager->get(dsReq);
QEventLoop dsLoop;
connect(dsReply, SIGNAL(finished()), &dsLoop, SLOT(quit()));
dsLoop.exec();
QByteArray dsMd5Data = dsReply->readAll().trimmed();
if (GlobalData::getInstance().getPlatform() == "win") {
// fix for reading the MD5 hash from Windows generated
// binary data of the MD5 hash
QTextStream stream(dsMd5Data);
stream >> dsMd5Data;
}
qDebug() << "DS MD5: " << dsMd5Data;
if (dsMd5Data.toLower() == QCryptographicHash::hash(dsData, QCryptographicHash::Md5).toHex()) {
_dsReady = true;
}
}
if (_qtReady) {
// check MD5 of requirements.zip only if Qt is found
QNetworkRequest reqZipReq(QUrl(GlobalData::getInstance().getRequirementsMD5URL()));
QNetworkReply* reqZipReply = _manager->get(reqZipReq);
QEventLoop reqZipLoop;
connect(reqZipReply, SIGNAL(finished()), &reqZipLoop, SLOT(quit()));
reqZipLoop.exec();
QByteArray reqZipMd5Data = reqZipReply->readAll().trimmed();
if (GlobalData::getInstance().getPlatform() == "win") {
// fix for reading the MD5 hash from Windows generated
// binary data of the MD5 hash
QTextStream stream(reqZipMd5Data);
stream >> reqZipMd5Data;
}
qDebug() << "Requirements ZIP MD5: " << reqZipMd5Data;
if (reqZipMd5Data.toLower() != QCryptographicHash::hash(reqZipData, QCryptographicHash::Md5).toHex()) {
_qtReady = false;
}
}
if (_dsResourcesReady) {
// check MD5 of resources.zip only if Domain Server
// resources are installed
QNetworkRequest resZipReq(QUrl(GlobalData::getInstance().getDomainServerResourcesMD5URL()));
QNetworkReply* resZipReply = _manager->get(resZipReq);
QEventLoop resZipLoop;
connect(resZipReply, SIGNAL(finished()), &resZipLoop, SLOT(quit()));
resZipLoop.exec();
QByteArray resZipMd5Data = resZipReply->readAll().trimmed();
if (GlobalData::getInstance().getPlatform() == "win") {
// fix for reading the MD5 hash from Windows generated
// binary data of the MD5 hash
QTextStream stream(resZipMd5Data);
stream >> resZipMd5Data;
}
qDebug() << "Domain Server Resources ZIP MD5: " << resZipMd5Data;
if (resZipMd5Data.toLower() != QCryptographicHash::hash(resZipData, QCryptographicHash::Md5).toHex()) {
_dsResourcesReady = false;
}
}
DownloadManager* downloadManager = 0;
if (!_qtReady || !_acReady || !_dsReady || !_dsResourcesReady) {
// initialise DownloadManager
downloadManager = new DownloadManager(_manager);
downloadManager->setWindowModality(Qt::ApplicationModal);
connect(downloadManager, SIGNAL(fileSuccessfullyInstalled(QUrl)),
SLOT(onFileSuccessfullyInstalled(QUrl)));
downloadManager->show();
} else {
_window->setRequirementsLastChecked(QDateTime::currentDateTime().toString());
_window->show();
toggleStack(true);
}
if (!_qtReady) {
downloadManager->downloadFile(GlobalData::getInstance().getRequirementsURL());
}
if (!_acReady) {
downloadManager->downloadFile(GlobalData::getInstance().getAssignmentClientURL());
}
if (!_dsReady) {
downloadManager->downloadFile(GlobalData::getInstance().getDomainServerURL());
}
if (!_dsResourcesReady) {
downloadManager->downloadFile(GlobalData::getInstance().getDomainServerResourcesURL());
}
}
void AppDelegate::checkVersion() { void AppDelegate::checkVersion() {
QNetworkRequest latestVersionRequest((QUrl(CHECK_BUILDS_URL))); QNetworkRequest latestVersionRequest((QUrl(CHECK_BUILDS_URL)));
latestVersionRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); latestVersionRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);

View file

@ -53,7 +53,6 @@ signals:
void indexPathChangeResponse(bool wasSuccessful); void indexPathChangeResponse(bool wasSuccessful);
void stackStateChanged(bool isOn); void stackStateChanged(bool isOn);
private slots: private slots:
void onFileSuccessfullyInstalled(const QUrl& url);
void requestDomainServerID(); void requestDomainServerID();
void handleDomainIDReply(); void handleDomainIDReply();
void handleDomainGetReply(); void handleDomainGetReply();
@ -64,16 +63,10 @@ private slots:
private: private:
void parseCommandLine(); void parseCommandLine();
void createExecutablePath();
void downloadLatestExecutablesAndRequirements();
void changeDomainServerIndexPath(const QString& newPath); void changeDomainServerIndexPath(const QString& newPath);
QNetworkAccessManager* _manager; QNetworkAccessManager* _manager;
bool _qtReady;
bool _dsReady;
bool _dsResourcesReady;
bool _acReady;
BackgroundProcess* _domainServerProcess; BackgroundProcess* _domainServerProcess;
BackgroundProcess* _acMonitorProcess; BackgroundProcess* _acMonitorProcess;
QHash<QUuid, BackgroundProcess*> _scriptProcesses; QHash<QUuid, BackgroundProcess*> _scriptProcesses;

View file

@ -32,11 +32,8 @@ GlobalData::GlobalData() {
_resourcePath = "resources/"; _resourcePath = "resources/";
_assignmentClientExecutable = "assignment-client"; _assignmentClientExecutable = "assignment-client";
_domainServerExecutable = "domain-server"; _domainServerExecutable = "domain-server";
QString applicationSupportDirectory = QStandardPaths::writableLocation(QStandardPaths::DataLocation); QString applicationSupportDirectory = QCoreApplication::applicationDirPath();
if (PR_BUILD) {
applicationSupportDirectory += "/pr-binaries";
}
_clientsLaunchPath = QDir::toNativeSeparators(applicationSupportDirectory + "/"); _clientsLaunchPath = QDir::toNativeSeparators(applicationSupportDirectory + "/");
_clientsResourcePath = QDir::toNativeSeparators(applicationSupportDirectory + "/" + _resourcePath); _clientsResourcePath = QDir::toNativeSeparators(applicationSupportDirectory + "/" + _resourcePath);
@ -49,18 +46,6 @@ GlobalData::GlobalData() {
_domainServerExecutablePath.append(".exe"); _domainServerExecutablePath.append(".exe");
} }
_requirementsURL = urlBase + "/binaries/" + _platform + "/requirements/requirements.zip";
_requirementsZipPath = _clientsLaunchPath + "requirements.zip";
_requirementsMD5URL = urlBase + "/binaries/" + _platform + "/requirements/requirements.md5";
_assignmentClientURL = urlBase + "/binaries/" + _platform + "/assignment-client" + (_platform == "win" ? "/assignment-client.exe" : "/assignment-client");
_domainServerResourcesURL = urlBase + "/binaries/" + _platform + "/domain-server/resources.zip";
_domainServerResourcesZipPath = _clientsLaunchPath + "resources.zip";
_domainServerResourcesMD5URL = urlBase + "/binaries/" + _platform + "/domain-server/resources.md5";
_domainServerURL = urlBase + "/binaries/" + _platform + "/domain-server" + (_platform == "win" ? "/domain-server.exe" : "/domain-server");
_assignmentClientMD5URL = urlBase + "/binaries/" + _platform + "/assignment-client/assignment-client.md5";
_domainServerMD5URL = urlBase + "/binaries/" + _platform + "/domain-server/domain-server.md5";
_defaultDomain = "localhost"; _defaultDomain = "localhost";
_logsPath = QDir::toNativeSeparators(_clientsLaunchPath + "logs/"); _logsPath = QDir::toNativeSeparators(_clientsLaunchPath + "logs/");
_availableAssignmentTypes.insert("audio-mixer", 0); _availableAssignmentTypes.insert("audio-mixer", 0);

View file

@ -9,6 +9,7 @@
#ifndef hifi_GlobalData_h #ifndef hifi_GlobalData_h
#define hifi_GlobalData_h #define hifi_GlobalData_h
#include <QCoreApplication>
#include <QString> #include <QString>
#include <QHash> #include <QHash>