mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 05:27:07 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into brown
This commit is contained in:
commit
ad5c78349a
7 changed files with 243 additions and 110 deletions
|
@ -371,109 +371,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
_model->updateRenderItems();
|
||||
}
|
||||
|
||||
if (hasModel()) {
|
||||
// Prepare the current frame
|
||||
{
|
||||
if (!_model || _needsModelReload) {
|
||||
// TODO: this getModel() appears to be about 3% of model render time. We should optimize
|
||||
PerformanceTimer perfTimer("getModel");
|
||||
auto renderer = qSharedPointerCast<EntityTreeRenderer>(args->_renderer);
|
||||
getModel(renderer);
|
||||
|
||||
// Remap textures immediately after loading to avoid flicker
|
||||
remapTextures();
|
||||
}
|
||||
|
||||
if (_model) {
|
||||
if (hasRenderAnimation()) {
|
||||
if (!jointsMapped()) {
|
||||
QStringList modelJointNames = _model->getJointNames();
|
||||
mapJoints(modelJointNames);
|
||||
}
|
||||
}
|
||||
|
||||
_jointDataLock.withWriteLock([&] {
|
||||
getAnimationFrame();
|
||||
|
||||
// relay any inbound joint changes from scripts/animation/network to the model/rig
|
||||
for (int index = 0; index < _localJointRotations.size(); index++) {
|
||||
if (_localJointRotationsDirty[index]) {
|
||||
glm::quat rotation = _localJointRotations[index];
|
||||
_model->setJointRotation(index, true, rotation, 1.0f);
|
||||
_localJointRotationsDirty[index] = false;
|
||||
}
|
||||
}
|
||||
for (int index = 0; index < _localJointTranslations.size(); index++) {
|
||||
if (_localJointTranslationsDirty[index]) {
|
||||
glm::vec3 translation = _localJointTranslations[index];
|
||||
_model->setJointTranslation(index, true, translation, 1.0f);
|
||||
_localJointTranslationsDirty[index] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
updateModelBounds();
|
||||
}
|
||||
}
|
||||
|
||||
// Enqueue updates for the next frame
|
||||
if (_model) {
|
||||
|
||||
#ifdef WANT_EXTRA_RENDER_DEBUGGING
|
||||
// debugging...
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
_model->renderDebugMeshBoxes(batch);
|
||||
#endif
|
||||
|
||||
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
|
||||
// FIXME: this seems like it could be optimized if we tracked our last known visible state in
|
||||
// the renderable item. As it stands now the model checks it's visible/invisible state
|
||||
// so most of the time we don't do anything in this function.
|
||||
_model->setVisibleInScene(getVisible(), scene);
|
||||
|
||||
// Remap textures for the next frame to avoid flicker
|
||||
remapTextures();
|
||||
|
||||
// update whether the model should be showing collision mesh (this may flag for fixupInScene)
|
||||
bool showingCollisionGeometry = (bool)(args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS);
|
||||
if (showingCollisionGeometry != _showCollisionGeometry) {
|
||||
ShapeType type = getShapeType();
|
||||
_showCollisionGeometry = showingCollisionGeometry;
|
||||
if (_showCollisionGeometry && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) {
|
||||
// NOTE: it is OK if _collisionMeshKey is nullptr
|
||||
model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey);
|
||||
// NOTE: the model will render the collisionGeometry if it has one
|
||||
_model->setCollisionMesh(mesh);
|
||||
} else {
|
||||
// release mesh
|
||||
if (_collisionMeshKey) {
|
||||
collisionMeshCache.releaseMesh(_collisionMeshKey);
|
||||
}
|
||||
// clear model's collision geometry
|
||||
model::MeshPointer mesh = nullptr;
|
||||
_model->setCollisionMesh(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
if (_model->needsFixupInScene()) {
|
||||
render::PendingChanges pendingChanges;
|
||||
|
||||
_model->removeFromScene(scene, pendingChanges);
|
||||
|
||||
render::Item::Status::Getters statusGetters;
|
||||
makeEntityItemStatusGetters(getThisPointer(), statusGetters);
|
||||
_model->addToScene(scene, pendingChanges, statusGetters);
|
||||
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
auto& currentURL = getParsedModelURL();
|
||||
if (currentURL != _model->getURL()) {
|
||||
// Defer setting the url to the render thread
|
||||
getModel(_myRenderer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!hasModel() || (_model && _model->didVisualGeometryRequestFail())) {
|
||||
static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
bool success;
|
||||
|
@ -482,6 +380,109 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
batch.setModelTransform(shapeTransform); // we want to include the scale as well
|
||||
DependencyManager::get<GeometryCache>()->renderWireCubeInstance(batch, greenColor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the current frame
|
||||
{
|
||||
if (!_model || _needsModelReload) {
|
||||
// TODO: this getModel() appears to be about 3% of model render time. We should optimize
|
||||
PerformanceTimer perfTimer("getModel");
|
||||
auto renderer = qSharedPointerCast<EntityTreeRenderer>(args->_renderer);
|
||||
getModel(renderer);
|
||||
|
||||
// Remap textures immediately after loading to avoid flicker
|
||||
remapTextures();
|
||||
}
|
||||
|
||||
if (_model) {
|
||||
if (hasRenderAnimation()) {
|
||||
if (!jointsMapped()) {
|
||||
QStringList modelJointNames = _model->getJointNames();
|
||||
mapJoints(modelJointNames);
|
||||
}
|
||||
}
|
||||
|
||||
_jointDataLock.withWriteLock([&] {
|
||||
getAnimationFrame();
|
||||
|
||||
// relay any inbound joint changes from scripts/animation/network to the model/rig
|
||||
for (int index = 0; index < _localJointRotations.size(); index++) {
|
||||
if (_localJointRotationsDirty[index]) {
|
||||
glm::quat rotation = _localJointRotations[index];
|
||||
_model->setJointRotation(index, true, rotation, 1.0f);
|
||||
_localJointRotationsDirty[index] = false;
|
||||
}
|
||||
}
|
||||
for (int index = 0; index < _localJointTranslations.size(); index++) {
|
||||
if (_localJointTranslationsDirty[index]) {
|
||||
glm::vec3 translation = _localJointTranslations[index];
|
||||
_model->setJointTranslation(index, true, translation, 1.0f);
|
||||
_localJointTranslationsDirty[index] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
updateModelBounds();
|
||||
}
|
||||
}
|
||||
|
||||
// Enqueue updates for the next frame
|
||||
if (_model) {
|
||||
|
||||
#ifdef WANT_EXTRA_RENDER_DEBUGGING
|
||||
// debugging...
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
_model->renderDebugMeshBoxes(batch);
|
||||
#endif
|
||||
|
||||
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
|
||||
// FIXME: this seems like it could be optimized if we tracked our last known visible state in
|
||||
// the renderable item. As it stands now the model checks it's visible/invisible state
|
||||
// so most of the time we don't do anything in this function.
|
||||
_model->setVisibleInScene(getVisible(), scene);
|
||||
|
||||
// Remap textures for the next frame to avoid flicker
|
||||
remapTextures();
|
||||
|
||||
// update whether the model should be showing collision mesh (this may flag for fixupInScene)
|
||||
bool showingCollisionGeometry = (bool)(args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS);
|
||||
if (showingCollisionGeometry != _showCollisionGeometry) {
|
||||
ShapeType type = getShapeType();
|
||||
_showCollisionGeometry = showingCollisionGeometry;
|
||||
if (_showCollisionGeometry && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) {
|
||||
// NOTE: it is OK if _collisionMeshKey is nullptr
|
||||
model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey);
|
||||
// NOTE: the model will render the collisionGeometry if it has one
|
||||
_model->setCollisionMesh(mesh);
|
||||
} else {
|
||||
// release mesh
|
||||
if (_collisionMeshKey) {
|
||||
collisionMeshCache.releaseMesh(_collisionMeshKey);
|
||||
}
|
||||
// clear model's collision geometry
|
||||
model::MeshPointer mesh = nullptr;
|
||||
_model->setCollisionMesh(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
if (_model->needsFixupInScene()) {
|
||||
render::PendingChanges pendingChanges;
|
||||
|
||||
_model->removeFromScene(scene, pendingChanges);
|
||||
|
||||
render::Item::Status::Getters statusGetters;
|
||||
makeEntityItemStatusGetters(getThisPointer(), statusGetters);
|
||||
_model->addToScene(scene, pendingChanges, statusGetters);
|
||||
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
auto& currentURL = getParsedModelURL();
|
||||
if (currentURL != _model->getURL()) {
|
||||
// Defer setting the url to the render thread
|
||||
getModel(_myRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -587,6 +588,10 @@ EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlag
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::supportsDetailedRayIntersection() const {
|
||||
return _model && _model->isLoaded();
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face,
|
||||
glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const {
|
||||
|
@ -807,6 +812,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
auto& meshes = _model->getGeometry()->getMeshes();
|
||||
int32_t numMeshes = (int32_t)(meshes.size());
|
||||
|
||||
const int MAX_ALLOWED_MESH_COUNT = 500;
|
||||
if (numMeshes > MAX_ALLOWED_MESH_COUNT) {
|
||||
// too many will cause the deadlock timer to throw...
|
||||
shapeInfo.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions);
|
||||
return;
|
||||
}
|
||||
|
||||
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
||||
pointCollection.clear();
|
||||
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
|
||||
void updateModelBounds();
|
||||
virtual void render(RenderArgs* args) override;
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
virtual bool supportsDetailedRayIntersection() const override;
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal,
|
||||
|
|
|
@ -208,6 +208,7 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re
|
|||
assert(!entity->getPhysicsInfo());
|
||||
if (entity->isDead()) {
|
||||
prepareEntityForDelete(entity);
|
||||
entityItr = _entitiesToAddToPhysics.erase(entityItr);
|
||||
} else if (!entity->shouldBePhysical()) {
|
||||
// this entity should no longer be on the internal _entitiesToAddToPhysics
|
||||
entityItr = _entitiesToAddToPhysics.erase(entityItr);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include <OVR_CAPI.h>
|
||||
|
||||
#include "OculusHelpers.h"
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(oculus)
|
||||
|
@ -42,26 +44,33 @@ bool OculusControllerManager::activate() {
|
|||
}
|
||||
Q_ASSERT(_session);
|
||||
|
||||
// register with UserInputMapper
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
checkForConnectedDevices();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OculusControllerManager::checkForConnectedDevices() {
|
||||
if (_touch && _remote) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int controllerConnected = ovr_GetConnectedControllerTypes(_session);
|
||||
|
||||
if ((controllerConnected & ovrControllerType_Remote) == ovrControllerType_Remote) {
|
||||
if (!_remote && (controllerConnected & ovrControllerType_Remote) == ovrControllerType_Remote) {
|
||||
if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Remote, &_inputState))) {
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
_remote = std::make_shared<RemoteDevice>(*this);
|
||||
userInputMapper->registerDevice(_remote);
|
||||
}
|
||||
}
|
||||
|
||||
if ((controllerConnected & ovrControllerType_Touch) != 0) {
|
||||
if (!_touch && (controllerConnected & ovrControllerType_Touch) != 0) {
|
||||
if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Touch, &_inputState))) {
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
_touch = std::make_shared<TouchDevice>(*this);
|
||||
userInputMapper->registerDevice(_touch);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OculusControllerManager::deactivate() {
|
||||
|
@ -85,6 +94,8 @@ void OculusControllerManager::deactivate() {
|
|||
void OculusControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
PerformanceTimer perfTimer("OculusControllerManager::TouchDevice::update");
|
||||
|
||||
checkForConnectedDevices();
|
||||
|
||||
if (_touch) {
|
||||
if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Touch, &_inputState))) {
|
||||
_touch->update(deltaTime, inputCalibrationData);
|
||||
|
|
|
@ -91,6 +91,8 @@ private:
|
|||
friend class OculusControllerManager;
|
||||
};
|
||||
|
||||
void checkForConnectedDevices();
|
||||
|
||||
ovrSession _session { nullptr };
|
||||
ovrInputState _inputState {};
|
||||
RemoteDevice::Pointer _remote;
|
||||
|
|
|
@ -311,3 +311,6 @@ clamp = function(val, min, max){
|
|||
return Math.max(min, Math.min(max, val))
|
||||
}
|
||||
|
||||
easeIn = function(t) {
|
||||
return Math.pow(t / 1, 5);
|
||||
}
|
||||
|
|
104
scripts/system/audioMuteOverlay.js
Normal file
104
scripts/system/audioMuteOverlay.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
"use strict";
|
||||
/* jslint vars: true, plusplus: true, forin: true*/
|
||||
/* globals Tablet, Script, AvatarList, Users, Entities, MyAvatar, Camera, Overlays, Vec3, Quat, Controller, print, getControllerWorldLocation */
|
||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||
//
|
||||
// audioMuteOverlay.js
|
||||
//
|
||||
// client script that creates an overlay to provide mute feedback
|
||||
//
|
||||
// Created by Triplelexx on 17/03/09
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
var utilsPath = Script.resolvePath('../developer/libraries/utils.js');
|
||||
Script.include(utilsPath);
|
||||
|
||||
var TWEEN_SPEED = 0.025;
|
||||
var MIX_AMOUNT = 0.25;
|
||||
|
||||
var overlayPosition = Vec3.ZERO;
|
||||
var tweenPosition = 0;
|
||||
var startColor = {
|
||||
red: 170,
|
||||
green: 170,
|
||||
blue: 170
|
||||
};
|
||||
var endColor = {
|
||||
red: 255,
|
||||
green: 0,
|
||||
blue: 0
|
||||
};
|
||||
var overlayID;
|
||||
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
||||
function update(dt) {
|
||||
if (!AudioDevice.getMuted()) {
|
||||
if (hasOverlay()) {
|
||||
deleteOverlay();
|
||||
}
|
||||
} else if (!hasOverlay()) {
|
||||
createOverlay();
|
||||
} else {
|
||||
updateOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
function getOffsetPosition() {
|
||||
return Vec3.sum(Camera.position, Quat.getFront(Camera.orientation));
|
||||
}
|
||||
|
||||
function createOverlay() {
|
||||
overlayPosition = getOffsetPosition();
|
||||
overlayID = Overlays.addOverlay("sphere", {
|
||||
position: overlayPosition,
|
||||
rotation: Camera.orientation,
|
||||
alpha: 0.9,
|
||||
dimensions: 0.1,
|
||||
solid: true,
|
||||
ignoreRayIntersection: true
|
||||
});
|
||||
}
|
||||
|
||||
function hasOverlay() {
|
||||
return Overlays.getProperty(overlayID, "position") !== undefined;
|
||||
}
|
||||
|
||||
function updateOverlay() {
|
||||
// increase by TWEEN_SPEED until completion
|
||||
if (tweenPosition < 1) {
|
||||
tweenPosition += TWEEN_SPEED;
|
||||
} else {
|
||||
// after tween completion reset to zero and flip values to ping pong
|
||||
tweenPosition = 0;
|
||||
for (var component in startColor) {
|
||||
var storedColor = startColor[component];
|
||||
startColor[component] = endColor[component];
|
||||
endColor[component] = storedColor;
|
||||
}
|
||||
}
|
||||
// mix previous position with new and mix colors
|
||||
overlayPosition = Vec3.mix(overlayPosition, getOffsetPosition(), MIX_AMOUNT);
|
||||
Overlays.editOverlay(overlayID, {
|
||||
color: colorMix(startColor, endColor, easeIn(tweenPosition)),
|
||||
position: overlayPosition,
|
||||
rotation: Camera.orientation
|
||||
});
|
||||
}
|
||||
|
||||
function deleteOverlay() {
|
||||
Overlays.deleteOverlay(overlayID);
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
deleteOverlay();
|
||||
AudioDevice.muteToggled.disconnect(onMuteToggled);
|
||||
Script.update.disconnect(update);
|
||||
}
|
||||
}()); // END LOCAL_SCOPE
|
Loading…
Reference in a new issue