mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 04:03:35 +02:00
Merge pull request #6476 from AndrewMeadows/arrow
fix for objects suffering from very small updates to physics properties
This commit is contained in:
commit
dde01b2071
9 changed files with 180 additions and 166 deletions
|
@ -679,7 +679,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
}));
|
}));
|
||||||
|
|
||||||
userInputMapper->registerDevice(_applicationStateDevice);
|
userInputMapper->registerDevice(_applicationStateDevice);
|
||||||
|
|
||||||
// Setup the keyboardMouseDevice and the user input mapper with the default bindings
|
// Setup the keyboardMouseDevice and the user input mapper with the default bindings
|
||||||
userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice());
|
userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice());
|
||||||
|
|
||||||
|
@ -749,7 +749,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
_oldHandRightClick[0] = false;
|
_oldHandRightClick[0] = false;
|
||||||
_oldHandLeftClick[1] = false;
|
_oldHandLeftClick[1] = false;
|
||||||
_oldHandRightClick[1] = false;
|
_oldHandRightClick[1] = false;
|
||||||
|
|
||||||
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||||
applicationUpdater->checkForUpdate();
|
applicationUpdater->checkForUpdate();
|
||||||
|
@ -768,7 +768,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
|
|
||||||
// If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it
|
// If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity,
|
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity,
|
||||||
[this, entityScriptingInterface](const EntityItemID& entityItemID, const MouseEvent& event) {
|
[this, entityScriptingInterface](const EntityItemID& entityItemID, const MouseEvent& event) {
|
||||||
if (_keyboardFocusedItem != entityItemID) {
|
if (_keyboardFocusedItem != entityItemID) {
|
||||||
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||||
|
@ -817,7 +817,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
});
|
});
|
||||||
|
|
||||||
// If the user clicks somewhere where there is NO entity at all, we will release focus
|
// If the user clicks somewhere where there is NO entity at all, we will release focus
|
||||||
connect(getEntities(), &EntityTreeRenderer::mousePressOffEntity,
|
connect(getEntities(), &EntityTreeRenderer::mousePressOffEntity,
|
||||||
[=](const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId) {
|
[=](const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId) {
|
||||||
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
|
||||||
if (_keyboardFocusHighlight) {
|
if (_keyboardFocusHighlight) {
|
||||||
|
@ -826,17 +826,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &Application::applicationStateChanged, this, &Application::activeChanged);
|
connect(this, &Application::applicationStateChanged, this, &Application::activeChanged);
|
||||||
|
|
||||||
qCDebug(interfaceapp, "Startup time: %4.2f seconds.", (double)startupTimer.elapsed() / 1000.0);
|
qCDebug(interfaceapp, "Startup time: %4.2f seconds.", (double)startupTimer.elapsed() / 1000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::aboutToQuit() {
|
void Application::aboutToQuit() {
|
||||||
emit beforeAboutToQuit();
|
emit beforeAboutToQuit();
|
||||||
|
|
||||||
getActiveDisplayPlugin()->deactivate();
|
getActiveDisplayPlugin()->deactivate();
|
||||||
|
|
||||||
_aboutToQuit = true;
|
_aboutToQuit = true;
|
||||||
|
|
||||||
cleanupBeforeQuit();
|
cleanupBeforeQuit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,16 +860,16 @@ void Application::cleanupBeforeQuit() {
|
||||||
_keyboardFocusHighlight = nullptr;
|
_keyboardFocusHighlight = nullptr;
|
||||||
|
|
||||||
_entities.clear(); // this will allow entity scripts to properly shutdown
|
_entities.clear(); // this will allow entity scripts to properly shutdown
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
// send the domain a disconnect packet, force stoppage of domain-server check-ins
|
// send the domain a disconnect packet, force stoppage of domain-server check-ins
|
||||||
nodeList->getDomainHandler().disconnect();
|
nodeList->getDomainHandler().disconnect();
|
||||||
nodeList->setIsShuttingDown(true);
|
nodeList->setIsShuttingDown(true);
|
||||||
|
|
||||||
// tell the packet receiver we're shutting down, so it can drop packets
|
// tell the packet receiver we're shutting down, so it can drop packets
|
||||||
nodeList->getPacketReceiver().setShouldDropPackets(true);
|
nodeList->getPacketReceiver().setShouldDropPackets(true);
|
||||||
|
|
||||||
_entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
|
_entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
|
||||||
ScriptEngine::stopAllScripts(this); // stop all currently running global scripts
|
ScriptEngine::stopAllScripts(this); // stop all currently running global scripts
|
||||||
|
|
||||||
|
@ -947,7 +947,7 @@ Application::~Application() {
|
||||||
DependencyManager::destroy<GeometryCache>();
|
DependencyManager::destroy<GeometryCache>();
|
||||||
DependencyManager::destroy<ScriptCache>();
|
DependencyManager::destroy<ScriptCache>();
|
||||||
DependencyManager::destroy<SoundCache>();
|
DependencyManager::destroy<SoundCache>();
|
||||||
|
|
||||||
// cleanup the AssetClient thread
|
// cleanup the AssetClient thread
|
||||||
QThread* assetThread = DependencyManager::get<AssetClient>()->thread();
|
QThread* assetThread = DependencyManager::get<AssetClient>()->thread();
|
||||||
DependencyManager::destroy<AssetClient>();
|
DependencyManager::destroy<AssetClient>();
|
||||||
|
@ -955,14 +955,14 @@ Application::~Application() {
|
||||||
assetThread->wait();
|
assetThread->wait();
|
||||||
|
|
||||||
QThread* nodeThread = DependencyManager::get<NodeList>()->thread();
|
QThread* nodeThread = DependencyManager::get<NodeList>()->thread();
|
||||||
|
|
||||||
// remove the NodeList from the DependencyManager
|
// remove the NodeList from the DependencyManager
|
||||||
DependencyManager::destroy<NodeList>();
|
DependencyManager::destroy<NodeList>();
|
||||||
|
|
||||||
// ask the node thread to quit and wait until it is done
|
// ask the node thread to quit and wait until it is done
|
||||||
nodeThread->quit();
|
nodeThread->quit();
|
||||||
nodeThread->wait();
|
nodeThread->wait();
|
||||||
|
|
||||||
Leapmotion::destroy();
|
Leapmotion::destroy();
|
||||||
RealSense::destroy();
|
RealSense::destroy();
|
||||||
|
|
||||||
|
@ -1058,7 +1058,7 @@ void Application::initializeUi() {
|
||||||
resizeGL();
|
resizeGL();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// This will set up the input plugins UI
|
// This will set up the input plugins UI
|
||||||
_activeInputPlugins.clear();
|
_activeInputPlugins.clear();
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
|
@ -1100,8 +1100,8 @@ void Application::paintGL() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some plugins process message events, potentially leading to
|
// Some plugins process message events, potentially leading to
|
||||||
// re-entering a paint event. don't allow further processing if this
|
// re-entering a paint event. don't allow further processing if this
|
||||||
// happens
|
// happens
|
||||||
if (_inPaint) {
|
if (_inPaint) {
|
||||||
return;
|
return;
|
||||||
|
@ -1137,17 +1137,17 @@ void Application::paintGL() {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||||
PerformanceTimer perfTimer("Mirror");
|
PerformanceTimer perfTimer("Mirror");
|
||||||
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
|
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
|
||||||
|
|
||||||
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||||
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
||||||
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
||||||
|
|
||||||
{
|
{
|
||||||
float ratio = ((float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale());
|
float ratio = ((float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale());
|
||||||
// Flip the src and destination rect horizontally to do the mirror
|
// Flip the src and destination rect horizontally to do the mirror
|
||||||
auto mirrorRect = glm::ivec4(0, 0, _mirrorViewRect.width() * ratio, _mirrorViewRect.height() * ratio);
|
auto mirrorRect = glm::ivec4(0, 0, _mirrorViewRect.width() * ratio, _mirrorViewRect.height() * ratio);
|
||||||
auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w);
|
auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w);
|
||||||
|
|
||||||
auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
|
auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
|
||||||
gpu::doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
|
gpu::doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
|
||||||
batch.setFramebuffer(selfieFbo);
|
batch.setFramebuffer(selfieFbo);
|
||||||
|
@ -1169,9 +1169,9 @@ void Application::paintGL() {
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("CameraUpdates");
|
PerformanceTimer perfTimer("CameraUpdates");
|
||||||
|
|
||||||
auto myAvatar = getMyAvatar();
|
auto myAvatar = getMyAvatar();
|
||||||
|
|
||||||
myAvatar->startCapture();
|
myAvatar->startCapture();
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
|
||||||
|
@ -1208,26 +1208,26 @@ void Application::paintGL() {
|
||||||
* (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)));
|
* (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)));
|
||||||
} else {
|
} else {
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
+ myAvatar->getOrientation()
|
+ myAvatar->getOrientation()
|
||||||
* (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)));
|
* (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
|
glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
|
||||||
_myCamera.setRotation(myAvatar->getWorldAlignedOrientation()
|
_myCamera.setRotation(myAvatar->getWorldAlignedOrientation()
|
||||||
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation);
|
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation);
|
||||||
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
|
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
+ glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0)
|
+ glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0)
|
||||||
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
||||||
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
||||||
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset);
|
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset);
|
||||||
} else {
|
} else {
|
||||||
_myCamera.setRotation(myAvatar->getWorldAlignedOrientation()
|
_myCamera.setRotation(myAvatar->getWorldAlignedOrientation()
|
||||||
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
+ glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0)
|
+ glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0)
|
||||||
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
||||||
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||||
}
|
}
|
||||||
|
@ -1246,7 +1246,7 @@ void Application::paintGL() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update camera position
|
// Update camera position
|
||||||
if (!isHMDMode()) {
|
if (!isHMDMode()) {
|
||||||
_myCamera.update(1.0f / _fps);
|
_myCamera.update(1.0f / _fps);
|
||||||
}
|
}
|
||||||
|
@ -1264,12 +1264,12 @@ void Application::paintGL() {
|
||||||
if (displayPlugin->isStereo()) {
|
if (displayPlugin->isStereo()) {
|
||||||
// Stereo modes will typically have a larger projection matrix overall,
|
// Stereo modes will typically have a larger projection matrix overall,
|
||||||
// so we ask for the 'mono' projection matrix, which for stereo and HMD
|
// so we ask for the 'mono' projection matrix, which for stereo and HMD
|
||||||
// plugins will imply the combined projection for both eyes.
|
// plugins will imply the combined projection for both eyes.
|
||||||
//
|
//
|
||||||
// This is properly implemented for the Oculus plugins, but for OpenVR
|
// This is properly implemented for the Oculus plugins, but for OpenVR
|
||||||
// and Stereo displays I'm not sure how to get / calculate it, so we're
|
// and Stereo displays I'm not sure how to get / calculate it, so we're
|
||||||
// just relying on the left FOV in each case and hoping that the
|
// just relying on the left FOV in each case and hoping that the
|
||||||
// overall culling margin of error doesn't cause popping in the
|
// overall culling margin of error doesn't cause popping in the
|
||||||
// right eye. There are FIXMEs in the relevant plugins
|
// right eye. There are FIXMEs in the relevant plugins
|
||||||
_myCamera.setProjection(displayPlugin->getProjection(Mono, _myCamera.getProjection()));
|
_myCamera.setProjection(displayPlugin->getProjection(Mono, _myCamera.getProjection()));
|
||||||
renderArgs._context->enableStereo(true);
|
renderArgs._context->enableStereo(true);
|
||||||
|
@ -1279,11 +1279,11 @@ void Application::paintGL() {
|
||||||
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
auto hmdInterface = DependencyManager::get<HMDScriptingInterface>();
|
||||||
float IPDScale = hmdInterface->getIPDScale();
|
float IPDScale = hmdInterface->getIPDScale();
|
||||||
// FIXME we probably don't need to set the projection matrix every frame,
|
// FIXME we probably don't need to set the projection matrix every frame,
|
||||||
// only when the display plugin changes (or in non-HMD modes when the user
|
// only when the display plugin changes (or in non-HMD modes when the user
|
||||||
// changes the FOV manually, which right now I don't think they can.
|
// changes the FOV manually, which right now I don't think they can.
|
||||||
for_each_eye([&](Eye eye) {
|
for_each_eye([&](Eye eye) {
|
||||||
// For providing the stereo eye views, the HMD head pose has already been
|
// For providing the stereo eye views, the HMD head pose has already been
|
||||||
// applied to the avatar, so we need to get the difference between the head
|
// applied to the avatar, so we need to get the difference between the head
|
||||||
// pose applied to the avatar and the per eye pose, and use THAT as
|
// pose applied to the avatar and the per eye pose, and use THAT as
|
||||||
// the per-eye stereo matrix adjustment.
|
// the per-eye stereo matrix adjustment.
|
||||||
mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye);
|
mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye);
|
||||||
|
@ -1293,10 +1293,10 @@ void Application::paintGL() {
|
||||||
mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale);
|
mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale);
|
||||||
eyeOffsets[eye] = eyeOffsetTransform;
|
eyeOffsets[eye] = eyeOffsetTransform;
|
||||||
|
|
||||||
// Tell the plugin what pose we're using to render. In this case we're just using the
|
// Tell the plugin what pose we're using to render. In this case we're just using the
|
||||||
// unmodified head pose because the only plugin that cares (the Oculus plugin) uses it
|
// unmodified head pose because the only plugin that cares (the Oculus plugin) uses it
|
||||||
// for rotational timewarp. If we move to support positonal timewarp, we need to
|
// for rotational timewarp. If we move to support positonal timewarp, we need to
|
||||||
// ensure this contains the full pose composed with the eye offsets.
|
// ensure this contains the full pose composed with the eye offsets.
|
||||||
mat4 headPose = displayPlugin->getHeadPose();
|
mat4 headPose = displayPlugin->getHeadPose();
|
||||||
displayPlugin->setEyeRenderPose(eye, headPose);
|
displayPlugin->setEyeRenderPose(eye, headPose);
|
||||||
|
|
||||||
|
@ -1343,7 +1343,7 @@ void Application::paintGL() {
|
||||||
PerformanceTimer perfTimer("pluginOutput");
|
PerformanceTimer perfTimer("pluginOutput");
|
||||||
auto primaryFbo = framebufferCache->getPrimaryFramebuffer();
|
auto primaryFbo = framebufferCache->getPrimaryFramebuffer();
|
||||||
GLuint finalTexture = gpu::GLBackend::getTextureID(primaryFbo->getRenderBuffer(0));
|
GLuint finalTexture = gpu::GLBackend::getTextureID(primaryFbo->getRenderBuffer(0));
|
||||||
// Ensure the rendering context commands are completed when rendering
|
// Ensure the rendering context commands are completed when rendering
|
||||||
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
// Ensure the sync object is flushed to the driver thread before releasing the context
|
// Ensure the sync object is flushed to the driver thread before releasing the context
|
||||||
// CRITICAL for the mac driver apparently.
|
// CRITICAL for the mac driver apparently.
|
||||||
|
@ -1394,7 +1394,7 @@ void Application::audioMuteToggled() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::faceTrackerMuteToggled() {
|
void Application::faceTrackerMuteToggled() {
|
||||||
|
|
||||||
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking);
|
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking);
|
||||||
Q_CHECK_PTR(muteAction);
|
Q_CHECK_PTR(muteAction);
|
||||||
bool isMuted = getSelectedFaceTracker()->isMuted();
|
bool isMuted = getSelectedFaceTracker()->isMuted();
|
||||||
|
@ -1427,7 +1427,7 @@ void Application::resizeGL() {
|
||||||
if (nullptr == _displayPlugin) {
|
if (nullptr == _displayPlugin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto displayPlugin = getActiveDisplayPlugin();
|
auto displayPlugin = getActiveDisplayPlugin();
|
||||||
// Set the desired FBO texture size. If it hasn't changed, this does nothing.
|
// Set the desired FBO texture size. If it hasn't changed, this does nothing.
|
||||||
// Otherwise, it must rebuild the FBOs
|
// Otherwise, it must rebuild the FBOs
|
||||||
|
@ -1437,14 +1437,14 @@ void Application::resizeGL() {
|
||||||
_renderResolution = renderSize;
|
_renderResolution = renderSize;
|
||||||
DependencyManager::get<FramebufferCache>()->setFrameBufferSize(fromGlm(renderSize));
|
DependencyManager::get<FramebufferCache>()->setFrameBufferSize(fromGlm(renderSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME the aspect ratio for stereo displays is incorrect based on this.
|
// FIXME the aspect ratio for stereo displays is incorrect based on this.
|
||||||
float aspectRatio = displayPlugin->getRecommendedAspectRatio();
|
float aspectRatio = displayPlugin->getRecommendedAspectRatio();
|
||||||
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio,
|
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio,
|
||||||
DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||||
// Possible change in aspect ratio
|
// Possible change in aspect ratio
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
loadViewFrustum(_myCamera, _viewFrustum);
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
auto uiSize = displayPlugin->getRecommendedUiSize();
|
auto uiSize = displayPlugin->getRecommendedUiSize();
|
||||||
// Bit of a hack since there's no device pixel ratio change event I can find.
|
// Bit of a hack since there's no device pixel ratio change event I can find.
|
||||||
|
@ -1613,7 +1613,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
if (isMeta) {
|
if (isMeta) {
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
offscreenUi->load("Browser.qml");
|
offscreenUi->load("Browser.qml");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_X:
|
case Qt::Key_X:
|
||||||
|
@ -2109,7 +2109,7 @@ void Application::wheelEvent(QWheelEvent* event) {
|
||||||
if (_controllerScriptingInterface->isWheelCaptured()) {
|
if (_controllerScriptingInterface->isWheelCaptured()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->wheelEvent(event);
|
_keyboardMouseDevice->wheelEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -2227,7 +2227,7 @@ void Application::idle(uint64_t now) {
|
||||||
_idleLoopStdev.reset();
|
_idleLoopStdev.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_overlayConductor.update(secondsSinceLastUpdate);
|
_overlayConductor.update(secondsSinceLastUpdate);
|
||||||
|
|
||||||
// check for any requested background downloads.
|
// check for any requested background downloads.
|
||||||
|
@ -2481,7 +2481,7 @@ void Application::init() {
|
||||||
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
|
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
|
||||||
|
|
||||||
qCDebug(interfaceapp) << "Loaded settings";
|
qCDebug(interfaceapp) << "Loaded settings";
|
||||||
|
|
||||||
Leapmotion::init();
|
Leapmotion::init();
|
||||||
RealSense::init();
|
RealSense::init();
|
||||||
|
|
||||||
|
@ -2539,7 +2539,7 @@ void Application::setAvatarUpdateThreading(bool isThreaded) {
|
||||||
if (_avatarUpdate && (_avatarUpdate->isThreaded() == isThreaded)) {
|
if (_avatarUpdate && (_avatarUpdate->isThreaded() == isThreaded)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto myAvatar = getMyAvatar();
|
auto myAvatar = getMyAvatar();
|
||||||
bool isRigEnabled = myAvatar->getEnableRigAnimations();
|
bool isRigEnabled = myAvatar->getEnableRigAnimations();
|
||||||
bool isGraphEnabled = myAvatar->getEnableAnimGraph();
|
bool isGraphEnabled = myAvatar->getEnableAnimGraph();
|
||||||
|
@ -2756,7 +2756,7 @@ void Application::updateDialogs(float deltaTime) {
|
||||||
if(audioStatsDialog) {
|
if(audioStatsDialog) {
|
||||||
audioStatsDialog->update();
|
audioStatsDialog->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update bandwidth dialog, if any
|
// Update bandwidth dialog, if any
|
||||||
BandwidthDialog* bandwidthDialog = dialogsManager->getBandwidthDialog();
|
BandwidthDialog* bandwidthDialog = dialogsManager->getBandwidthDialog();
|
||||||
if (bandwidthDialog) {
|
if (bandwidthDialog) {
|
||||||
|
@ -2892,7 +2892,7 @@ void Application::update(float deltaTime) {
|
||||||
_entities.getTree()->withWriteLock([&] {
|
_entities.getTree()->withWriteLock([&] {
|
||||||
_physicsEngine->stepSimulation();
|
_physicsEngine->stepSimulation();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_physicsEngine->hasOutgoingChanges()) {
|
if (_physicsEngine->hasOutgoingChanges()) {
|
||||||
_entities.getTree()->withWriteLock([&] {
|
_entities.getTree()->withWriteLock([&] {
|
||||||
_entitySimulation.handleOutgoingChanges(_physicsEngine->getOutgoingChanges(), _physicsEngine->getSessionID());
|
_entitySimulation.handleOutgoingChanges(_physicsEngine->getOutgoingChanges(), _physicsEngine->getSessionID());
|
||||||
|
@ -3026,10 +3026,10 @@ int Application::sendNackPackets() {
|
||||||
foreach(const OCTREE_PACKET_SEQUENCE& missingNumber, missingSequenceNumbers) {
|
foreach(const OCTREE_PACKET_SEQUENCE& missingNumber, missingSequenceNumbers) {
|
||||||
nackPacketList->writePrimitive(missingNumber);
|
nackPacketList->writePrimitive(missingNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nackPacketList->getNumPackets()) {
|
if (nackPacketList->getNumPackets()) {
|
||||||
packetsSent += nackPacketList->getNumPackets();
|
packetsSent += nackPacketList->getNumPackets();
|
||||||
|
|
||||||
// send the packet list
|
// send the packet list
|
||||||
nodeList->sendPacketList(std::move(nackPacketList), *node);
|
nodeList->sendPacketList(std::move(nackPacketList), *node);
|
||||||
}
|
}
|
||||||
|
@ -3635,7 +3635,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
|
||||||
float fov = MIRROR_FIELD_OF_VIEW;
|
float fov = MIRROR_FIELD_OF_VIEW;
|
||||||
|
|
||||||
auto myAvatar = getMyAvatar();
|
auto myAvatar = getMyAvatar();
|
||||||
|
|
||||||
// bool eyeRelativeCamera = false;
|
// bool eyeRelativeCamera = false;
|
||||||
if (billboard) {
|
if (billboard) {
|
||||||
fov = BILLBOARD_FIELD_OF_VIEW; // degees
|
fov = BILLBOARD_FIELD_OF_VIEW; // degees
|
||||||
|
@ -3843,7 +3843,7 @@ void Application::nodeKilled(SharedNodePointer node) {
|
||||||
Menu::getInstance()->getActionForOption(MenuOption::UploadAsset)->setEnabled(false);
|
Menu::getInstance()->getActionForOption(MenuOption::UploadAsset)->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) {
|
void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) {
|
||||||
|
|
||||||
// Attempt to identify the sender from its address.
|
// Attempt to identify the sender from its address.
|
||||||
|
@ -3868,7 +3868,7 @@ int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingN
|
||||||
int statsMessageLength = 0;
|
int statsMessageLength = 0;
|
||||||
|
|
||||||
const QUuid& nodeUUID = sendingNode->getUUID();
|
const QUuid& nodeUUID = sendingNode->getUUID();
|
||||||
|
|
||||||
// now that we know the node ID, let's add these stats to the stats for that node...
|
// now that we know the node ID, let's add these stats to the stats for that node...
|
||||||
_octreeServerSceneStats.withWriteLock([&] {
|
_octreeServerSceneStats.withWriteLock([&] {
|
||||||
OctreeSceneStats& octreeStats = _octreeServerSceneStats[nodeUUID];
|
OctreeSceneStats& octreeStats = _octreeServerSceneStats[nodeUUID];
|
||||||
|
@ -4069,7 +4069,7 @@ bool Application::acceptURL(const QString& urlString, bool defaultUpload) {
|
||||||
Qt::AutoConnection, Q_ARG(const QString&, urlString));
|
Qt::AutoConnection, Q_ARG(const QString&, urlString));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl url(urlString);
|
QUrl url(urlString);
|
||||||
QHashIterator<QString, AcceptURLMethod> i(_acceptedExtensions);
|
QHashIterator<QString, AcceptURLMethod> i(_acceptedExtensions);
|
||||||
QString lowerPath = url.path().toLower();
|
QString lowerPath = url.path().toLower();
|
||||||
|
@ -4080,7 +4080,7 @@ bool Application::acceptURL(const QString& urlString, bool defaultUpload) {
|
||||||
return (this->*method)(urlString);
|
return (this->*method)(urlString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultUpload && askToUploadAsset(urlString);
|
return defaultUpload && askToUploadAsset(urlString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4162,10 +4162,10 @@ bool Application::askToUploadAsset(const QString& filename) {
|
||||||
QString("You don't have upload rights on that domain.\n\n"));
|
QString("You don't have upload rights on that domain.\n\n"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl url { filename };
|
QUrl url { filename };
|
||||||
if (auto upload = DependencyManager::get<AssetClient>()->createUpload(url.toLocalFile())) {
|
if (auto upload = DependencyManager::get<AssetClient>()->createUpload(url.toLocalFile())) {
|
||||||
|
|
||||||
QMessageBox messageBox;
|
QMessageBox messageBox;
|
||||||
messageBox.setWindowTitle("Asset upload");
|
messageBox.setWindowTitle("Asset upload");
|
||||||
messageBox.setText("You are about to upload the following file to the asset server:\n" +
|
messageBox.setText("You are about to upload the following file to the asset server:\n" +
|
||||||
|
@ -4173,19 +4173,19 @@ bool Application::askToUploadAsset(const QString& filename) {
|
||||||
messageBox.setInformativeText("Do you want to continue?");
|
messageBox.setInformativeText("Do you want to continue?");
|
||||||
messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||||
messageBox.setDefaultButton(QMessageBox::Ok);
|
messageBox.setDefaultButton(QMessageBox::Ok);
|
||||||
|
|
||||||
// Option to drop model in world for models
|
// Option to drop model in world for models
|
||||||
if (filename.endsWith(FBX_EXTENSION) || filename.endsWith(OBJ_EXTENSION)) {
|
if (filename.endsWith(FBX_EXTENSION) || filename.endsWith(OBJ_EXTENSION)) {
|
||||||
auto checkBox = new QCheckBox(&messageBox);
|
auto checkBox = new QCheckBox(&messageBox);
|
||||||
checkBox->setText("Add to scene");
|
checkBox->setText("Add to scene");
|
||||||
messageBox.setCheckBox(checkBox);
|
messageBox.setCheckBox(checkBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageBox.exec() != QMessageBox::Ok) {
|
if (messageBox.exec() != QMessageBox::Ok) {
|
||||||
upload->deleteLater();
|
upload->deleteLater();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to the finished signal so we know when the AssetUpload is done
|
// connect to the finished signal so we know when the AssetUpload is done
|
||||||
if (messageBox.checkBox() && (messageBox.checkBox()->checkState() == Qt::Checked)) {
|
if (messageBox.checkBox() && (messageBox.checkBox()->checkState() == Qt::Checked)) {
|
||||||
// Custom behavior for models
|
// Custom behavior for models
|
||||||
|
@ -4195,12 +4195,12 @@ bool Application::askToUploadAsset(const QString& filename) {
|
||||||
&AssetUploadDialogFactory::getInstance(),
|
&AssetUploadDialogFactory::getInstance(),
|
||||||
&AssetUploadDialogFactory::handleUploadFinished);
|
&AssetUploadDialogFactory::handleUploadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start the upload now
|
// start the upload now
|
||||||
upload->start();
|
upload->start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// display a message box with the error
|
// display a message box with the error
|
||||||
QMessageBox::warning(_window, "Failed Upload", QString("Failed to upload %1.\n\n").arg(filename));
|
QMessageBox::warning(_window, "Failed Upload", QString("Failed to upload %1.\n\n").arg(filename));
|
||||||
return false;
|
return false;
|
||||||
|
@ -4208,20 +4208,20 @@ bool Application::askToUploadAsset(const QString& filename) {
|
||||||
|
|
||||||
void Application::modelUploadFinished(AssetUpload* upload, const QString& hash) {
|
void Application::modelUploadFinished(AssetUpload* upload, const QString& hash) {
|
||||||
auto filename = QFileInfo(upload->getFilename()).fileName();
|
auto filename = QFileInfo(upload->getFilename()).fileName();
|
||||||
|
|
||||||
if ((upload->getError() == AssetUpload::NoError) &&
|
if ((upload->getError() == AssetUpload::NoError) &&
|
||||||
(filename.endsWith(FBX_EXTENSION) || filename.endsWith(OBJ_EXTENSION))) {
|
(filename.endsWith(FBX_EXTENSION) || filename.endsWith(OBJ_EXTENSION))) {
|
||||||
|
|
||||||
auto entities = DependencyManager::get<EntityScriptingInterface>();
|
auto entities = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
|
||||||
EntityItemProperties properties;
|
EntityItemProperties properties;
|
||||||
properties.setType(EntityTypes::Model);
|
properties.setType(EntityTypes::Model);
|
||||||
properties.setModelURL(QString("%1:%2.%3").arg(URL_SCHEME_ATP).arg(hash).arg(upload->getExtension()));
|
properties.setModelURL(QString("%1:%2.%3").arg(URL_SCHEME_ATP).arg(hash).arg(upload->getExtension()));
|
||||||
properties.setPosition(_myCamera.getPosition() + _myCamera.getOrientation() * Vectors::FRONT * 2.0f);
|
properties.setPosition(_myCamera.getPosition() + _myCamera.getOrientation() * Vectors::FRONT * 2.0f);
|
||||||
properties.setName(QUrl(upload->getFilename()).fileName());
|
properties.setName(QUrl(upload->getFilename()).fileName());
|
||||||
|
|
||||||
entities->addEntity(properties);
|
entities->addEntity(properties);
|
||||||
|
|
||||||
upload->deleteLater();
|
upload->deleteLater();
|
||||||
} else {
|
} else {
|
||||||
AssetUploadDialogFactory::getInstance().handleUploadFinished(upload, hash);
|
AssetUploadDialogFactory::getInstance().handleUploadFinished(upload, hash);
|
||||||
|
@ -4510,7 +4510,7 @@ void Application::takeSnapshot() {
|
||||||
_snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget);
|
_snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget);
|
||||||
}
|
}
|
||||||
_snapshotShareDialog->show();
|
_snapshotShareDialog->show();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Application::getRenderResolutionScale() const {
|
float Application::getRenderResolutionScale() const {
|
||||||
|
@ -4755,8 +4755,8 @@ void Application::updateDisplayMode() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some plugins *cough* Oculus *cough* process message events from inside their
|
// Some plugins *cough* Oculus *cough* process message events from inside their
|
||||||
// display function, and we don't want to change the display plugin underneath
|
// display function, and we don't want to change the display plugin underneath
|
||||||
// the paintGL call, so we need to guard against that
|
// the paintGL call, so we need to guard against that
|
||||||
if (_inPaint) {
|
if (_inPaint) {
|
||||||
qDebug() << "Deferring plugin switch until out of painting";
|
qDebug() << "Deferring plugin switch until out of painting";
|
||||||
|
@ -4790,14 +4790,14 @@ void Application::updateDisplayMode() {
|
||||||
|
|
||||||
oldDisplayPlugin = _displayPlugin;
|
oldDisplayPlugin = _displayPlugin;
|
||||||
_displayPlugin = newDisplayPlugin;
|
_displayPlugin = newDisplayPlugin;
|
||||||
|
|
||||||
// If the displayPlugin is a screen based HMD, then it will want the HMDTools displayed
|
// If the displayPlugin is a screen based HMD, then it will want the HMDTools displayed
|
||||||
// Direct Mode HMDs (like windows Oculus) will be isHmd() but will have a screen of -1
|
// Direct Mode HMDs (like windows Oculus) will be isHmd() but will have a screen of -1
|
||||||
bool newPluginWantsHMDTools = newDisplayPlugin ?
|
bool newPluginWantsHMDTools = newDisplayPlugin ?
|
||||||
(newDisplayPlugin->isHmd() && (newDisplayPlugin->getHmdScreen() >= 0)) : false;
|
(newDisplayPlugin->isHmd() && (newDisplayPlugin->getHmdScreen() >= 0)) : false;
|
||||||
bool oldPluginWantedHMDTools = oldDisplayPlugin ?
|
bool oldPluginWantedHMDTools = oldDisplayPlugin ?
|
||||||
(oldDisplayPlugin->isHmd() && (oldDisplayPlugin->getHmdScreen() >= 0)) : false;
|
(oldDisplayPlugin->isHmd() && (oldDisplayPlugin->getHmdScreen() >= 0)) : false;
|
||||||
|
|
||||||
// Only show the hmd tools after the correct plugin has
|
// Only show the hmd tools after the correct plugin has
|
||||||
// been activated so that it's UI is setup correctly
|
// been activated so that it's UI is setup correctly
|
||||||
if (newPluginWantsHMDTools) {
|
if (newPluginWantsHMDTools) {
|
||||||
|
@ -4807,7 +4807,7 @@ void Application::updateDisplayMode() {
|
||||||
if (oldDisplayPlugin) {
|
if (oldDisplayPlugin) {
|
||||||
oldDisplayPlugin->deactivate();
|
oldDisplayPlugin->deactivate();
|
||||||
_offscreenContext->makeCurrent();
|
_offscreenContext->makeCurrent();
|
||||||
|
|
||||||
// if the old plugin was HMD and the new plugin is not HMD, then hide our hmdtools
|
// if the old plugin was HMD and the new plugin is not HMD, then hide our hmdtools
|
||||||
if (oldPluginWantedHMDTools && !newPluginWantsHMDTools) {
|
if (oldPluginWantedHMDTools && !newPluginWantsHMDTools) {
|
||||||
DependencyManager::get<DialogsManager>()->hmdTools(false);
|
DependencyManager::get<DialogsManager>()->hmdTools(false);
|
||||||
|
@ -4940,7 +4940,7 @@ void Application::setPalmData(Hand* hand, const controller::Pose& pose, float de
|
||||||
rawVelocity = glm::vec3(0.0f);
|
rawVelocity = glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
palm.setRawVelocity(rawVelocity); // meters/sec
|
palm.setRawVelocity(rawVelocity); // meters/sec
|
||||||
|
|
||||||
// Angular Velocity of Palm
|
// Angular Velocity of Palm
|
||||||
glm::quat deltaRotation = rotation * glm::inverse(palm.getRawRotation());
|
glm::quat deltaRotation = rotation * glm::inverse(palm.getRawRotation());
|
||||||
glm::vec3 angularVelocity(0.0f);
|
glm::vec3 angularVelocity(0.0f);
|
||||||
|
@ -5020,7 +5020,7 @@ void Application::emulateMouse(Hand* hand, float click, float shift, HandData::H
|
||||||
pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
|
pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we are off screen then we should stop processing, and if a trigger or bumper is pressed,
|
//If we are off screen then we should stop processing, and if a trigger or bumper is pressed,
|
||||||
//we should unpress them.
|
//we should unpress them.
|
||||||
if (pos.x() == INT_MAX) {
|
if (pos.x() == INT_MAX) {
|
||||||
|
|
|
@ -35,4 +35,4 @@ namespace AudioConstants {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_AudioConstants_h
|
#endif // hifi_AudioConstants_h
|
||||||
|
|
|
@ -622,7 +622,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
const QUuid& myNodeID = nodeList->getSessionUUID();
|
const QUuid& myNodeID = nodeList->getSessionUUID();
|
||||||
bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
|
bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
|
||||||
|
|
||||||
|
|
||||||
if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) {
|
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
|
||||||
|
@ -799,17 +799,11 @@ void EntityItem::setDensity(float density) {
|
||||||
_density = glm::max(glm::min(density, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
_density = glm::max(glm::min(density, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float ACTIVATION_RELATIVE_DENSITY_DELTA = 0.01f; // 1 percent
|
|
||||||
|
|
||||||
void EntityItem::updateDensity(float density) {
|
void EntityItem::updateDensity(float density) {
|
||||||
float clampedDensity = glm::max(glm::min(density, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
float clampedDensity = glm::max(glm::min(density, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
||||||
if (_density != clampedDensity) {
|
if (_density != clampedDensity) {
|
||||||
_density = clampedDensity;
|
_density = clampedDensity;
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_MASS;
|
||||||
if (fabsf(_density - clampedDensity) / _density > ACTIVATION_RELATIVE_DENSITY_DELTA) {
|
|
||||||
// the density has changed enough that we should update the physics simulation
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_MASS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,11 +816,16 @@ void EntityItem::setMass(float mass) {
|
||||||
|
|
||||||
// compute new density
|
// compute new density
|
||||||
const float MIN_VOLUME = 1.0e-6f; // 0.001mm^3
|
const float MIN_VOLUME = 1.0e-6f; // 0.001mm^3
|
||||||
|
float newDensity = 1.0f;
|
||||||
if (volume < 1.0e-6f) {
|
if (volume < 1.0e-6f) {
|
||||||
// avoid divide by zero
|
// avoid divide by zero
|
||||||
_density = glm::min(mass / MIN_VOLUME, ENTITY_ITEM_MAX_DENSITY);
|
newDensity = glm::min(mass / MIN_VOLUME, ENTITY_ITEM_MAX_DENSITY);
|
||||||
} else {
|
} else {
|
||||||
_density = glm::max(glm::min(mass / volume, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
newDensity = glm::max(glm::min(mass / volume, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
||||||
|
}
|
||||||
|
if (_density != newDensity) {
|
||||||
|
_density = newDensity;
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_MASS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,12 +883,12 @@ void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) {
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
qCDebug(entities) << "EntityItem::simulateKinematicMotion timeElapsed" << timeElapsed;
|
qCDebug(entities) << "EntityItem::simulateKinematicMotion timeElapsed" << timeElapsed;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const float MIN_TIME_SKIP = 0.0f;
|
const float MIN_TIME_SKIP = 0.0f;
|
||||||
const float MAX_TIME_SKIP = 1.0f; // in seconds
|
const float MAX_TIME_SKIP = 1.0f; // in seconds
|
||||||
|
|
||||||
timeElapsed = glm::clamp(timeElapsed, MIN_TIME_SKIP, MAX_TIME_SKIP);
|
timeElapsed = glm::clamp(timeElapsed, MIN_TIME_SKIP, MAX_TIME_SKIP);
|
||||||
|
|
||||||
if (hasActions()) {
|
if (hasActions()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1312,24 +1311,16 @@ void EntityItem::updatePosition(const glm::vec3& value) {
|
||||||
if (shouldSuppressLocationEdits()) {
|
if (shouldSuppressLocationEdits()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto delta = glm::distance(getPosition(), value);
|
if (getPosition() != value) {
|
||||||
if (delta > IGNORE_POSITION_DELTA) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_POSITION;
|
|
||||||
setPosition(value);
|
setPosition(value);
|
||||||
if (delta > ACTIVATION_POSITION_DELTA) {
|
_dirtyFlags |= Simulation::DIRTY_POSITION;
|
||||||
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::updateDimensions(const glm::vec3& value) {
|
void EntityItem::updateDimensions(const glm::vec3& value) {
|
||||||
auto delta = glm::distance(getDimensions(), value);
|
if (getDimensions() != value) {
|
||||||
if (delta > IGNORE_DIMENSIONS_DELTA) {
|
|
||||||
setDimensions(value);
|
setDimensions(value);
|
||||||
if (delta > ACTIVATION_DIMENSIONS_DELTA) {
|
_dirtyFlags |= (Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
// rebuilding the shape will always activate
|
|
||||||
_dirtyFlags |= (Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1339,14 +1330,7 @@ void EntityItem::updateRotation(const glm::quat& rotation) {
|
||||||
}
|
}
|
||||||
if (getRotation() != rotation) {
|
if (getRotation() != rotation) {
|
||||||
setRotation(rotation);
|
setRotation(rotation);
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_ROTATION;
|
||||||
auto alignmentDot = glm::abs(glm::dot(getRotation(), rotation));
|
|
||||||
if (alignmentDot < IGNORE_ALIGNMENT_DOT) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_ROTATION;
|
|
||||||
}
|
|
||||||
if (alignmentDot < ACTIVATION_ALIGNMENT_DOT) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,11 +1351,8 @@ void EntityItem::updateMass(float mass) {
|
||||||
newDensity = glm::max(glm::min(mass / volume, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
newDensity = glm::max(glm::min(mass / volume, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
float oldDensity = _density;
|
if (_density != newDensity) {
|
||||||
_density = newDensity;
|
_density = newDensity;
|
||||||
|
|
||||||
if (fabsf(_density - oldDensity) / _density > ACTIVATION_RELATIVE_DENSITY_DELTA) {
|
|
||||||
// the density has changed enough that we should update the physics simulation
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_MASS;
|
_dirtyFlags |= Simulation::DIRTY_MASS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1380,38 +1361,29 @@ void EntityItem::updateVelocity(const glm::vec3& value) {
|
||||||
if (shouldSuppressLocationEdits()) {
|
if (shouldSuppressLocationEdits()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto delta = glm::distance(_velocity, value);
|
if (_velocity != value) {
|
||||||
if (delta > IGNORE_LINEAR_VELOCITY_DELTA) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_LINEAR_VELOCITY;
|
|
||||||
const float MIN_LINEAR_SPEED = 0.001f;
|
const float MIN_LINEAR_SPEED = 0.001f;
|
||||||
if (glm::length(value) < MIN_LINEAR_SPEED) {
|
if (glm::length(value) < MIN_LINEAR_SPEED) {
|
||||||
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
_velocity = ENTITY_ITEM_ZERO_VEC3;
|
||||||
} else {
|
} else {
|
||||||
_velocity = value;
|
_velocity = value;
|
||||||
// only activate when setting non-zero velocity
|
|
||||||
if (delta > ACTIVATION_LINEAR_VELOCITY_DELTA) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_LINEAR_VELOCITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::updateDamping(float value) {
|
void EntityItem::updateDamping(float value) {
|
||||||
auto clampedDamping = glm::clamp(value, 0.0f, 1.0f);
|
auto clampedDamping = glm::clamp(value, 0.0f, 1.0f);
|
||||||
if (fabsf(_damping - clampedDamping) > IGNORE_DAMPING_DELTA) {
|
if (_damping != clampedDamping) {
|
||||||
_damping = clampedDamping;
|
_damping = clampedDamping;
|
||||||
_dirtyFlags |= Simulation::DIRTY_MATERIAL;
|
_dirtyFlags |= Simulation::DIRTY_MATERIAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::updateGravity(const glm::vec3& value) {
|
void EntityItem::updateGravity(const glm::vec3& value) {
|
||||||
auto delta = glm::distance(_gravity, value);
|
if (_gravity != value) {
|
||||||
if (delta > IGNORE_GRAVITY_DELTA) {
|
|
||||||
_gravity = value;
|
_gravity = value;
|
||||||
_dirtyFlags |= Simulation::DIRTY_LINEAR_VELOCITY;
|
_dirtyFlags |= Simulation::DIRTY_LINEAR_VELOCITY;
|
||||||
if (delta > ACTIVATION_GRAVITY_DELTA) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1419,25 +1391,20 @@ void EntityItem::updateAngularVelocity(const glm::vec3& value) {
|
||||||
if (shouldSuppressLocationEdits()) {
|
if (shouldSuppressLocationEdits()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto delta = glm::distance(_angularVelocity, value);
|
if (_angularVelocity != value) {
|
||||||
if (delta > IGNORE_ANGULAR_VELOCITY_DELTA) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_ANGULAR_VELOCITY;
|
|
||||||
const float MIN_ANGULAR_SPEED = 0.0002f;
|
const float MIN_ANGULAR_SPEED = 0.0002f;
|
||||||
if (glm::length(value) < MIN_ANGULAR_SPEED) {
|
if (glm::length(value) < MIN_ANGULAR_SPEED) {
|
||||||
_angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
_angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
||||||
} else {
|
} else {
|
||||||
_angularVelocity = value;
|
_angularVelocity = value;
|
||||||
// only activate when setting non-zero velocity
|
|
||||||
if (delta > ACTIVATION_ANGULAR_VELOCITY_DELTA) {
|
|
||||||
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_dirtyFlags |= Simulation::DIRTY_ANGULAR_VELOCITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::updateAngularDamping(float value) {
|
void EntityItem::updateAngularDamping(float value) {
|
||||||
auto clampedDamping = glm::clamp(value, 0.0f, 1.0f);
|
auto clampedDamping = glm::clamp(value, 0.0f, 1.0f);
|
||||||
if (fabsf(_angularDamping - clampedDamping) > IGNORE_DAMPING_DELTA) {
|
if (_angularDamping != clampedDamping) {
|
||||||
_angularDamping = clampedDamping;
|
_angularDamping = clampedDamping;
|
||||||
_dirtyFlags |= Simulation::DIRTY_MATERIAL;
|
_dirtyFlags |= Simulation::DIRTY_MATERIAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace render {
|
||||||
class PendingChanges;
|
class PendingChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// these thesholds determine what updates will be ignored (client and server)
|
// these thesholds determine what updates will be ignored (client and server)
|
||||||
const float IGNORE_POSITION_DELTA = 0.0001f;
|
const float IGNORE_POSITION_DELTA = 0.0001f;
|
||||||
const float IGNORE_DIMENSIONS_DELTA = 0.0005f;
|
const float IGNORE_DIMENSIONS_DELTA = 0.0005f;
|
||||||
|
@ -64,6 +65,7 @@ const float ACTIVATION_ALIGNMENT_DOT = 0.99990f;
|
||||||
const float ACTIVATION_LINEAR_VELOCITY_DELTA = 0.01f;
|
const float ACTIVATION_LINEAR_VELOCITY_DELTA = 0.01f;
|
||||||
const float ACTIVATION_GRAVITY_DELTA = 0.1f;
|
const float ACTIVATION_GRAVITY_DELTA = 0.1f;
|
||||||
const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f;
|
const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f;
|
||||||
|
*/
|
||||||
|
|
||||||
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
|
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
|
||||||
#define ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() { };
|
#define ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() { };
|
||||||
|
|
|
@ -95,7 +95,7 @@ void EntityMotionState::updateServerPhysicsVariables(const QUuid& sessionID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
bool EntityMotionState::handleEasyChanges(uint32_t flags, PhysicsEngine* engine) {
|
bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
updateServerPhysicsVariables(engine->getSessionID());
|
updateServerPhysicsVariables(engine->getSessionID());
|
||||||
ObjectMotionState::handleEasyChanges(flags, engine);
|
ObjectMotionState::handleEasyChanges(flags, engine);
|
||||||
|
@ -120,7 +120,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t flags, PhysicsEngine* engine)
|
||||||
}
|
}
|
||||||
if (flags & Simulation::DIRTY_SIMULATOR_OWNERSHIP) {
|
if (flags & Simulation::DIRTY_SIMULATOR_OWNERSHIP) {
|
||||||
// (DIRTY_SIMULATOR_OWNERSHIP really means "we should bid for ownership with SCRIPT priority")
|
// (DIRTY_SIMULATOR_OWNERSHIP really means "we should bid for ownership with SCRIPT priority")
|
||||||
// we're manipulating this object directly via script, so we artificially
|
// we're manipulating this object directly via script, so we artificially
|
||||||
// manipulate the logic to trigger an immediate bid for ownership
|
// manipulate the logic to trigger an immediate bid for ownership
|
||||||
setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY);
|
setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t flags, PhysicsEngine* engine)
|
||||||
|
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
bool EntityMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine) {
|
bool EntityMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
||||||
updateServerPhysicsVariables(engine->getSessionID());
|
updateServerPhysicsVariables(engine->getSessionID());
|
||||||
return ObjectMotionState::handleHardAndEasyChanges(flags, engine);
|
return ObjectMotionState::handleHardAndEasyChanges(flags, engine);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ public:
|
||||||
virtual ~EntityMotionState();
|
virtual ~EntityMotionState();
|
||||||
|
|
||||||
void updateServerPhysicsVariables(const QUuid& sessionID);
|
void updateServerPhysicsVariables(const QUuid& sessionID);
|
||||||
virtual bool handleEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
virtual bool handleEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||||
virtual bool handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||||
|
|
||||||
/// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem
|
/// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem
|
||||||
virtual MotionType computeObjectMotionType() const;
|
virtual MotionType computeObjectMotionType() const;
|
||||||
|
|
|
@ -17,6 +17,14 @@
|
||||||
#include "PhysicsHelpers.h"
|
#include "PhysicsHelpers.h"
|
||||||
#include "PhysicsLogging.h"
|
#include "PhysicsLogging.h"
|
||||||
|
|
||||||
|
// these thresholds determine what updates (object-->body) will activate the physical object
|
||||||
|
const float ACTIVATION_POSITION_DELTA = 0.005f;
|
||||||
|
const float ACTIVATION_ALIGNMENT_DOT = 0.99990f;
|
||||||
|
const float ACTIVATION_LINEAR_VELOCITY_DELTA = 0.01f;
|
||||||
|
const float ACTIVATION_GRAVITY_DELTA = 0.1f;
|
||||||
|
const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f;
|
||||||
|
|
||||||
|
|
||||||
// origin of physics simulation in world-frame
|
// origin of physics simulation in world-frame
|
||||||
glm::vec3 _worldOffset(0.0f);
|
glm::vec3 _worldOffset(0.0f);
|
||||||
|
|
||||||
|
@ -128,28 +136,65 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectMotionState::handleEasyChanges(uint32_t flags, PhysicsEngine* engine) {
|
bool ObjectMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
||||||
if (flags & Simulation::DIRTY_POSITION) {
|
if (flags & Simulation::DIRTY_POSITION) {
|
||||||
btTransform worldTrans;
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
if (flags & Simulation::DIRTY_ROTATION) {
|
btVector3 newPosition = glmToBullet(getObjectPosition());
|
||||||
worldTrans.setRotation(glmToBullet(getObjectRotation()));
|
float delta = (newPosition - worldTrans.getOrigin()).length();
|
||||||
} else {
|
if (delta > ACTIVATION_POSITION_DELTA) {
|
||||||
worldTrans = _body->getWorldTransform();
|
flags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
}
|
||||||
|
worldTrans.setOrigin(newPosition);
|
||||||
|
|
||||||
|
if (flags & Simulation::DIRTY_ROTATION) {
|
||||||
|
btQuaternion newRotation = glmToBullet(getObjectRotation());
|
||||||
|
float alignmentDot = fabsf(worldTrans.getRotation().dot(newRotation));
|
||||||
|
if (alignmentDot < ACTIVATION_ALIGNMENT_DOT) {
|
||||||
|
flags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
}
|
||||||
|
worldTrans.setRotation(newRotation);
|
||||||
}
|
}
|
||||||
worldTrans.setOrigin(glmToBullet(getObjectPosition()));
|
|
||||||
_body->setWorldTransform(worldTrans);
|
_body->setWorldTransform(worldTrans);
|
||||||
} else if (flags & Simulation::DIRTY_ROTATION) {
|
} else if (flags & Simulation::DIRTY_ROTATION) {
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
worldTrans.setRotation(glmToBullet(getObjectRotation()));
|
btQuaternion newRotation = glmToBullet(getObjectRotation());
|
||||||
|
float alignmentDot = fabsf(worldTrans.getRotation().dot(newRotation));
|
||||||
|
if (alignmentDot < ACTIVATION_ALIGNMENT_DOT) {
|
||||||
|
flags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
}
|
||||||
|
worldTrans.setRotation(newRotation);
|
||||||
_body->setWorldTransform(worldTrans);
|
_body->setWorldTransform(worldTrans);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & Simulation::DIRTY_LINEAR_VELOCITY) {
|
if (flags & Simulation::DIRTY_LINEAR_VELOCITY) {
|
||||||
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
|
btVector3 newLinearVelocity = glmToBullet(getObjectLinearVelocity());
|
||||||
_body->setGravity(glmToBullet(getObjectGravity()));
|
if (!(flags & Simulation::DIRTY_PHYSICS_ACTIVATION)) {
|
||||||
|
float delta = (newLinearVelocity - _body->getLinearVelocity()).length();
|
||||||
|
if (delta > ACTIVATION_LINEAR_VELOCITY_DELTA) {
|
||||||
|
flags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_body->setLinearVelocity(newLinearVelocity);
|
||||||
|
|
||||||
|
btVector3 newGravity = glmToBullet(getObjectGravity());
|
||||||
|
if (!(flags & Simulation::DIRTY_PHYSICS_ACTIVATION)) {
|
||||||
|
float delta = (newGravity - _body->getGravity()).length();
|
||||||
|
if (delta > ACTIVATION_GRAVITY_DELTA ||
|
||||||
|
(delta > 0.0f && _body->getGravity().length2() == 0.0f)) {
|
||||||
|
flags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_body->setGravity(newGravity);
|
||||||
}
|
}
|
||||||
if (flags & Simulation::DIRTY_ANGULAR_VELOCITY) {
|
if (flags & Simulation::DIRTY_ANGULAR_VELOCITY) {
|
||||||
_body->setAngularVelocity(glmToBullet(getObjectAngularVelocity()));
|
btVector3 newAngularVelocity = glmToBullet(getObjectAngularVelocity());
|
||||||
|
if (!(flags & Simulation::DIRTY_PHYSICS_ACTIVATION)) {
|
||||||
|
float delta = (newAngularVelocity - _body->getAngularVelocity()).length();
|
||||||
|
if (delta > ACTIVATION_ANGULAR_VELOCITY_DELTA) {
|
||||||
|
flags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_body->setAngularVelocity(newAngularVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & Simulation::DIRTY_MATERIAL) {
|
if (flags & Simulation::DIRTY_MATERIAL) {
|
||||||
|
@ -163,7 +208,7 @@ bool ObjectMotionState::handleEasyChanges(uint32_t flags, PhysicsEngine* engine)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine) {
|
bool ObjectMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
|
||||||
if (flags & Simulation::DIRTY_SHAPE) {
|
if (flags & Simulation::DIRTY_SHAPE) {
|
||||||
// make sure the new shape is valid
|
// make sure the new shape is valid
|
||||||
if (!isReadyToComputeShape()) {
|
if (!isReadyToComputeShape()) {
|
||||||
|
@ -195,8 +240,8 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine*
|
||||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
handleEasyChanges(flags, engine);
|
handleEasyChanges(flags, engine);
|
||||||
}
|
}
|
||||||
// it is possible that there are no HARD flags at this point (if DIRTY_SHAPE was removed)
|
// it is possible there are no HARD flags at this point (if DIRTY_SHAPE was removed)
|
||||||
// so we check again befoe we reinsert:
|
// so we check again before we reinsert:
|
||||||
if (flags & HARD_DIRTY_PHYSICS_FLAGS) {
|
if (flags & HARD_DIRTY_PHYSICS_FLAGS) {
|
||||||
engine->reinsertObject(this);
|
engine->reinsertObject(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,8 @@ public:
|
||||||
ObjectMotionState(btCollisionShape* shape);
|
ObjectMotionState(btCollisionShape* shape);
|
||||||
~ObjectMotionState();
|
~ObjectMotionState();
|
||||||
|
|
||||||
virtual bool handleEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
virtual bool handleEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||||
virtual bool handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine);
|
||||||
|
|
||||||
void updateBodyMaterialProperties();
|
void updateBodyMaterialProperties();
|
||||||
void updateBodyVelocities();
|
void updateBodyVelocities();
|
||||||
|
|
|
@ -244,14 +244,14 @@ void PhysicsEngine::stepSimulation() {
|
||||||
float timeStep = btMin(dt, MAX_TIMESTEP);
|
float timeStep = btMin(dt, MAX_TIMESTEP);
|
||||||
|
|
||||||
if (_myAvatarController) {
|
if (_myAvatarController) {
|
||||||
// ADEBUG TODO: move this stuff outside and in front of stepSimulation, because
|
// TODO: move this stuff outside and in front of stepSimulation, because
|
||||||
// the updateShapeIfNecessary() call needs info from MyAvatar and should
|
// the updateShapeIfNecessary() call needs info from MyAvatar and should
|
||||||
// be done on the main thread during the pre-simulation stuff
|
// be done on the main thread during the pre-simulation stuff
|
||||||
if (_myAvatarController->needsRemoval()) {
|
if (_myAvatarController->needsRemoval()) {
|
||||||
_myAvatarController->setDynamicsWorld(nullptr);
|
_myAvatarController->setDynamicsWorld(nullptr);
|
||||||
|
|
||||||
// We must remove any existing contacts for the avatar so that any new contacts will have
|
// We must remove any existing contacts for the avatar so that any new contacts will have
|
||||||
// valid data. MyAvatar's RigidBody is the ONLY one in the simulation that does not yet
|
// valid data. MyAvatar's RigidBody is the ONLY one in the simulation that does not yet
|
||||||
// have a MotionState so we pass nullptr to removeContacts().
|
// have a MotionState so we pass nullptr to removeContacts().
|
||||||
removeContacts(nullptr);
|
removeContacts(nullptr);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue