mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 11:07:52 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into yellow
This commit is contained in:
commit
2c05349b06
29 changed files with 614 additions and 266 deletions
|
@ -17,8 +17,7 @@ EntityActionPointer assignmentActionFactory(EntityActionType type, const QUuid&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityActionPointer AssignmentActionFactory::factory(EntitySimulation* simulation,
|
EntityActionPointer AssignmentActionFactory::factory(EntityActionType type,
|
||||||
EntityActionType type,
|
|
||||||
const QUuid& id,
|
const QUuid& id,
|
||||||
EntityItemPointer ownerEntity,
|
EntityItemPointer ownerEntity,
|
||||||
QVariantMap arguments) {
|
QVariantMap arguments) {
|
||||||
|
@ -33,9 +32,7 @@ EntityActionPointer AssignmentActionFactory::factory(EntitySimulation* simulatio
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityActionPointer AssignmentActionFactory::factoryBA(EntitySimulation* simulation,
|
EntityActionPointer AssignmentActionFactory::factoryBA(EntityItemPointer ownerEntity, QByteArray data) {
|
||||||
EntityItemPointer ownerEntity,
|
|
||||||
QByteArray data) {
|
|
||||||
QDataStream serializedActionDataStream(data);
|
QDataStream serializedActionDataStream(data);
|
||||||
EntityActionType type;
|
EntityActionType type;
|
||||||
QUuid id;
|
QUuid id;
|
||||||
|
|
|
@ -19,14 +19,11 @@ class AssignmentActionFactory : public EntityActionFactoryInterface {
|
||||||
public:
|
public:
|
||||||
AssignmentActionFactory() : EntityActionFactoryInterface() { }
|
AssignmentActionFactory() : EntityActionFactoryInterface() { }
|
||||||
virtual ~AssignmentActionFactory() { }
|
virtual ~AssignmentActionFactory() { }
|
||||||
virtual EntityActionPointer factory(EntitySimulation* simulation,
|
virtual EntityActionPointer factory(EntityActionType type,
|
||||||
EntityActionType type,
|
|
||||||
const QUuid& id,
|
const QUuid& id,
|
||||||
EntityItemPointer ownerEntity,
|
EntityItemPointer ownerEntity,
|
||||||
QVariantMap arguments);
|
QVariantMap arguments);
|
||||||
virtual EntityActionPointer factoryBA(EntitySimulation* simulation,
|
virtual EntityActionPointer factoryBA(EntityItemPointer ownerEntity, QByteArray data);
|
||||||
EntityItemPointer ownerEntity,
|
|
||||||
QByteArray data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AssignmentActionFactory_h
|
#endif // hifi_AssignmentActionFactory_h
|
||||||
|
|
|
@ -9,9 +9,7 @@
|
||||||
var NUM_MOONS = 20;
|
var NUM_MOONS = 20;
|
||||||
// 1 = 60Hz, 2 = 30Hz, 3 = 20Hz, etc
|
// 1 = 60Hz, 2 = 30Hz, 3 = 20Hz, etc
|
||||||
var UPDATE_FREQUENCY_DIVISOR = 2;
|
var UPDATE_FREQUENCY_DIVISOR = 2;
|
||||||
|
|
||||||
var MAX_RANGE = 75.0;
|
var MAX_RANGE = 75.0;
|
||||||
var LIFETIME = 600;
|
|
||||||
var SCALE = 0.1;
|
var SCALE = 0.1;
|
||||||
|
|
||||||
var center = Vec3.sum(MyAvatar.position,
|
var center = Vec3.sum(MyAvatar.position,
|
||||||
|
@ -22,44 +20,47 @@ var PARTICLE_MIN_SIZE = 2.50;
|
||||||
var PARTICLE_MAX_SIZE = 2.50;
|
var PARTICLE_MAX_SIZE = 2.50;
|
||||||
|
|
||||||
|
|
||||||
var planet = Entities.addEntity({
|
function deleteAnimationTestEntitites() {
|
||||||
type: "Sphere",
|
var ids = Entities.findEntities(MyAvatar.position, 50);
|
||||||
position: center,
|
for (var i = 0; i < ids.length; i++) {
|
||||||
dimensions: { x: 10 * SCALE, y: 10 * SCALE, z: 10 * SCALE },
|
var id = ids[i];
|
||||||
color: { red: 0, green: 0, blue: 255 },
|
var properties = Entities.getEntityProperties(id);
|
||||||
ignoreCollisions: true,
|
if (properties.name == "AnimationTest") {
|
||||||
collisionsWillMove: false,
|
Entities.deleteEntity(id);
|
||||||
lifetime: LIFETIME
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteAnimationTestEntitites();
|
||||||
|
|
||||||
var moons = [];
|
var moons = [];
|
||||||
|
|
||||||
// Create initial test particles that will move according to gravity from the planets
|
// Create initial test particles that will move according to gravity from the planets
|
||||||
for (var i = 0; i < NUM_MOONS; i++) {
|
for (var i = 0; i < NUM_MOONS; i++) {
|
||||||
var radius = PARTICLE_MIN_SIZE + Math.random() * PARTICLE_MAX_SIZE;
|
var radius = PARTICLE_MIN_SIZE + Math.random() * PARTICLE_MAX_SIZE;
|
||||||
radius *= SCALE;
|
radius *= SCALE;
|
||||||
var gray = Math.random() * 155;
|
var gray = Math.random() * 155;
|
||||||
var position = { x: 10 , y: i * 3, z: 0 };
|
var position = { x: 10 , y: i * 3, z: 0 };
|
||||||
var color = { red: 100 + gray, green: 100 + gray, blue: 100 + gray };
|
var color = { red: 100 + gray, green: 100 + gray, blue: 100 + gray };
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
color = { red: 255, green: 0, blue: 0 };
|
color = { red: 255, green: 0, blue: 0 };
|
||||||
radius = 6 * SCALE
|
radius = 6 * SCALE
|
||||||
}
|
}
|
||||||
moons.push(Entities.addEntity({
|
moons.push(Entities.addEntity({
|
||||||
type: "Sphere",
|
type: "Sphere",
|
||||||
position: Vec3.sum(center, position),
|
name: "AnimationTest",
|
||||||
dimensions: { x: radius, y: radius, z: radius },
|
position: Vec3.sum(center, position),
|
||||||
color: color,
|
dimensions: { x: radius, y: radius, z: radius },
|
||||||
ignoreCollisions: true,
|
color: color,
|
||||||
lifetime: LIFETIME,
|
ignoreCollisions: true,
|
||||||
collisionsWillMove: false
|
collisionsWillMove: false
|
||||||
}));
|
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Script.update.connect(update);
|
Script.update.connect(update);
|
||||||
|
|
||||||
function scriptEnding() {
|
function scriptEnding() {
|
||||||
Entities.deleteEntity(planet);
|
|
||||||
for (var i = 0; i < moons.length; i++) {
|
for (var i = 0; i < moons.length; i++) {
|
||||||
Entities.deleteEntity(moons[i]);
|
Entities.deleteEntity(moons[i]);
|
||||||
}
|
}
|
||||||
|
@ -70,22 +71,20 @@ var updateCount = 0;
|
||||||
function update(deltaTime) {
|
function update(deltaTime) {
|
||||||
// Apply gravitational force from planets
|
// Apply gravitational force from planets
|
||||||
totalTime += deltaTime;
|
totalTime += deltaTime;
|
||||||
updateCount++;
|
updateCount++;
|
||||||
if (0 != updateCount % UPDATE_FREQUENCY_DIVISOR) {
|
if (0 != updateCount % UPDATE_FREQUENCY_DIVISOR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var planetProperties = Entities.getEntityProperties(planet);
|
|
||||||
var center = planetProperties.position;
|
|
||||||
var particlePos = Entities.getEntityProperties(moons[0]).position;
|
var particlePos = Entities.getEntityProperties(moons[0]).position;
|
||||||
var relativePos = Vec3.subtract(particlePos.position, center);
|
var relativePos = Vec3.subtract(particlePos.position, center);
|
||||||
for (var t = 0; t < moons.length; t++) {
|
for (var t = 0; t < moons.length; t++) {
|
||||||
var thetaDelta = (Math.PI * 2.0 / NUM_MOONS) * t;
|
var thetaDelta = (Math.PI * 2.0 / NUM_MOONS) * t;
|
||||||
var y = Math.sin(totalTime + thetaDelta) * 10.0 * SCALE;
|
var y = Math.sin(totalTime + thetaDelta) * 10.0 * SCALE;
|
||||||
var x = Math.cos(totalTime + thetaDelta) * 10.0 * SCALE;
|
var x = Math.cos(totalTime + thetaDelta) * 10.0 * SCALE;
|
||||||
var newBasePos = Vec3.sum({ x: 0, y: y, z: x }, center);
|
var newBasePos = Vec3.sum({ x: 0, y: y, z: x }, center);
|
||||||
Entities.editEntity(moons[t], { position: newBasePos});
|
Entities.editEntity(moons[t], { position: newBasePos});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Script.scriptEnding.connect(scriptEnding);
|
Script.scriptEnding.connect(deleteAnimationTestEntitites);
|
||||||
|
|
58
examples/cubePerfTest.js
Normal file
58
examples/cubePerfTest.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/07/01
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
var SIDE_SIZE = 10;
|
||||||
|
|
||||||
|
var center = { x: 0, y: 0, z: 0 };
|
||||||
|
|
||||||
|
var DEGREES_TO_RADIANS = Math.PI / 180.0;
|
||||||
|
var PARTICLE_MIN_SIZE = 2.50;
|
||||||
|
var PARTICLE_MAX_SIZE = 2.50;
|
||||||
|
var LIFETIME = 600;
|
||||||
|
var boxes = [];
|
||||||
|
|
||||||
|
var ids = Entities.findEntities({ x: 512, y: 512, z: 512 }, 50);
|
||||||
|
for (var i = 0; i < ids.length; i++) {
|
||||||
|
var id = ids[i];
|
||||||
|
var properties = Entities.getEntityProperties(id);
|
||||||
|
if (properties.name == "PerfTest") {
|
||||||
|
Entities.deleteEntity(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create initial test particles that will move according to gravity from the planets
|
||||||
|
for (var x = 0; x < SIDE_SIZE; x++) {
|
||||||
|
for (var y = 0; y < SIDE_SIZE; y++) {
|
||||||
|
for (var z = 0; z < SIDE_SIZE; z++) {
|
||||||
|
var gray = Math.random() * 155;
|
||||||
|
var cube = Math.random() > 0.5;
|
||||||
|
var color = { red: 100 + gray, green: 100 + gray, blue: 100 + gray };
|
||||||
|
var position = { x: 512 + x * 0.2, y: 512 + y * 0.2, z: 512 + z * 0.2};
|
||||||
|
var radius = Math.random() * 0.1;
|
||||||
|
boxes.push(Entities.addEntity({
|
||||||
|
type: cube ? "Box" : "Sphere",
|
||||||
|
name: "PerfTest",
|
||||||
|
position: position,
|
||||||
|
dimensions: { x: radius, y: radius, z: radius },
|
||||||
|
color: color,
|
||||||
|
ignoreCollisions: true,
|
||||||
|
collisionsWillMove: false,
|
||||||
|
lifetime: LIFETIME
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function scriptEnding() {
|
||||||
|
for (var i = 0; i < boxes.length; i++) {
|
||||||
|
//Entities.deleteEntity(boxes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Script.scriptEnding.connect(scriptEnding);
|
73
examples/stick-hydra.js
Normal file
73
examples/stick-hydra.js
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
// stick-hydra.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by Seth Alves on 2015-7-9
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Allow avatar to hold a stick and control it with a hand-tracker
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
var hand = "left";
|
||||||
|
var nullActionID = "00000000-0000-0000-0000-000000000000";
|
||||||
|
var controllerID;
|
||||||
|
var controllerActive;
|
||||||
|
var stickID = null;
|
||||||
|
var actionID = nullActionID;
|
||||||
|
var makingNewStick = false;
|
||||||
|
|
||||||
|
function makeNewStick() {
|
||||||
|
if (makingNewStick) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
makingNewStick = true;
|
||||||
|
cleanUp();
|
||||||
|
// sometimes if this is run immediately the stick doesn't get created? use a timer.
|
||||||
|
Script.setTimeout(function() {
|
||||||
|
stickID = Entities.addEntity({
|
||||||
|
type: "Model",
|
||||||
|
name: "stick",
|
||||||
|
modelURL: "https://hifi-public.s3.amazonaws.com/eric/models/stick.fbx",
|
||||||
|
compoundShapeURL: "https://hifi-public.s3.amazonaws.com/eric/models/stick.obj",
|
||||||
|
dimensions: {x: .11, y: .11, z: 1.0},
|
||||||
|
position: MyAvatar.getRightPalmPosition(), // initial position doesn't matter, as long as it's close
|
||||||
|
rotation: MyAvatar.orientation,
|
||||||
|
damping: .1,
|
||||||
|
collisionSoundURL: "http://public.highfidelity.io/sounds/Collisions-hitsandslaps/67LCollision07.wav",
|
||||||
|
restitution: 0.01,
|
||||||
|
collisionsWillMove: true
|
||||||
|
});
|
||||||
|
actionID = Entities.addAction("hold", stickID,
|
||||||
|
{relativePosition: {x: 0.0, y: 0.0, z: -0.5},
|
||||||
|
relativeRotation: Quat.fromVec3Degrees({x: 0.0, y: 90.0, z: 0.0}),
|
||||||
|
hand: hand,
|
||||||
|
timeScale: 0.15});
|
||||||
|
if (actionID == nullActionID) {
|
||||||
|
cleanUp();
|
||||||
|
}
|
||||||
|
makingNewStick = false;
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cleanUp() {
|
||||||
|
if (stickID) {
|
||||||
|
Entities.deleteEntity(stickID);
|
||||||
|
stickID = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function initControls(){
|
||||||
|
if (hand == "right") {
|
||||||
|
controllerID = 3; // right handed
|
||||||
|
} else {
|
||||||
|
controllerID = 4; // left handed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanUp);
|
||||||
|
makeNewStick();
|
|
@ -394,6 +394,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
static_cast<NodeList*>(dependency)->deleteLater();
|
static_cast<NodeList*>(dependency)->deleteLater();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// setup a timer for domain-server check ins
|
||||||
|
QTimer* domainCheckInTimer = new QTimer(nodeList.data());
|
||||||
|
connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn);
|
||||||
|
domainCheckInTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS);
|
||||||
|
|
||||||
// put the NodeList and datagram processing on the node thread
|
// put the NodeList and datagram processing on the node thread
|
||||||
nodeList->moveToThread(nodeThread);
|
nodeList->moveToThread(nodeThread);
|
||||||
|
|
||||||
|
@ -887,12 +892,6 @@ void Application::paintGL() {
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("renderOverlay");
|
PerformanceTimer perfTimer("renderOverlay");
|
||||||
/*
|
|
||||||
gpu::Context context(new gpu::GLBackend());
|
|
||||||
RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
|
|
||||||
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
|
||||||
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
|
||||||
*/
|
|
||||||
_applicationOverlay.renderOverlay(&renderArgs);
|
_applicationOverlay.renderOverlay(&renderArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,6 +967,8 @@ void Application::paintGL() {
|
||||||
} else if (TV3DManager::isConnected()) {
|
} else if (TV3DManager::isConnected()) {
|
||||||
TV3DManager::display(&renderArgs, _myCamera);
|
TV3DManager::display(&renderArgs, _myCamera);
|
||||||
} else {
|
} else {
|
||||||
|
PROFILE_RANGE(__FUNCTION__ "/mainRender");
|
||||||
|
|
||||||
DependencyManager::get<GlowEffect>()->prepare(&renderArgs);
|
DependencyManager::get<GlowEffect>()->prepare(&renderArgs);
|
||||||
|
|
||||||
// Viewport is assigned to the size of the framebuffer
|
// Viewport is assigned to the size of the framebuffer
|
||||||
|
@ -982,7 +983,7 @@ void Application::paintGL() {
|
||||||
|
|
||||||
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||||
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
||||||
|
@ -1002,6 +1003,7 @@ void Application::paintGL() {
|
||||||
|
|
||||||
|
|
||||||
if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
|
if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__ "/bufferSwap");
|
||||||
_glWidget->swapBuffers();
|
_glWidget->swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,6 +1053,7 @@ void Application::resetCameras(Camera& camera, const glm::uvec2& size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::resizeGL() {
|
void Application::resizeGL() {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
// 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
|
||||||
QSize renderSize;
|
QSize renderSize;
|
||||||
|
@ -1526,6 +1529,7 @@ void Application::focusOutEvent(QFocusEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
|
void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
// Used by application overlay to determine how to draw cursor(s)
|
// Used by application overlay to determine how to draw cursor(s)
|
||||||
_lastMouseMoveWasSimulated = deviceID > 0;
|
_lastMouseMoveWasSimulated = deviceID > 0;
|
||||||
if (!_lastMouseMoveWasSimulated) {
|
if (!_lastMouseMoveWasSimulated) {
|
||||||
|
@ -1781,9 +1785,6 @@ void Application::checkFPS() {
|
||||||
_frameCount = 0;
|
_frameCount = 0;
|
||||||
_datagramProcessor->resetCounters();
|
_datagramProcessor->resetCounters();
|
||||||
_timerStart.start();
|
_timerStart.start();
|
||||||
|
|
||||||
// ask the node list to check in with the domain server
|
|
||||||
DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::idle() {
|
void Application::idle() {
|
||||||
|
@ -1829,6 +1830,7 @@ void Application::idle() {
|
||||||
PerformanceTimer perfTimer("update");
|
PerformanceTimer perfTimer("update");
|
||||||
PerformanceWarning warn(showWarnings, "Application::idle()... update()");
|
PerformanceWarning warn(showWarnings, "Application::idle()... update()");
|
||||||
const float BIGGEST_DELTA_TIME_SECS = 0.25f;
|
const float BIGGEST_DELTA_TIME_SECS = 0.25f;
|
||||||
|
PROFILE_RANGE(__FUNCTION__ "/idleUpdate");
|
||||||
update(glm::clamp((float)timeSinceLastUpdate / 1000.0f, 0.0f, BIGGEST_DELTA_TIME_SECS));
|
update(glm::clamp((float)timeSinceLastUpdate / 1000.0f, 0.0f, BIGGEST_DELTA_TIME_SECS));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -1852,7 +1854,7 @@ void Application::idle() {
|
||||||
// After finishing all of the above work, ensure the idle timer is set to the proper interval,
|
// After finishing all of the above work, ensure the idle timer is set to the proper interval,
|
||||||
// depending on whether we're throttling or not
|
// depending on whether we're throttling or not
|
||||||
idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 0);
|
idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for any requested background downloads.
|
// check for any requested background downloads.
|
||||||
emit checkBackgroundDownloads();
|
emit checkBackgroundDownloads();
|
||||||
|
@ -2954,6 +2956,7 @@ QRect Application::getDesirableApplicationGeometry() {
|
||||||
// or the "myCamera".
|
// or the "myCamera".
|
||||||
//
|
//
|
||||||
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
// We will use these below, from either the camera or head vectors calculated above
|
// We will use these below, from either the camera or head vectors calculated above
|
||||||
viewFrustum.setProjection(camera.getProjection());
|
viewFrustum.setProjection(camera.getProjection());
|
||||||
|
|
||||||
|
@ -3310,7 +3313,7 @@ namespace render {
|
||||||
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
|
||||||
const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
|
const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
|
||||||
|
|
||||||
glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
|
glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
|
||||||
/ closestData.getAtmosphereOuterRadius();
|
/ closestData.getAtmosphereOuterRadius();
|
||||||
float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter());
|
float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter());
|
||||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||||
|
@ -3318,8 +3321,8 @@ namespace render {
|
||||||
alpha = 0.0f;
|
alpha = 0.0f;
|
||||||
|
|
||||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||||
float directionY = glm::clamp(sunDirection.y,
|
float directionY = glm::clamp(sunDirection.y,
|
||||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||||
}
|
}
|
||||||
|
@ -3330,8 +3333,8 @@ namespace render {
|
||||||
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
(closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
|
||||||
|
|
||||||
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
|
||||||
float directionY = glm::clamp(sunDirection.y,
|
float directionY = glm::clamp(sunDirection.y,
|
||||||
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
-APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
|
||||||
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
+ APPROXIMATE_DISTANCE_FROM_HORIZON;
|
||||||
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
|
||||||
}
|
}
|
||||||
|
@ -3458,9 +3461,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
// Assuming nothing get's rendered through that
|
// Assuming nothing get's rendered through that
|
||||||
|
|
||||||
if (!selfAvatarOnly) {
|
if (!selfAvatarOnly) {
|
||||||
|
|
||||||
// render models...
|
|
||||||
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||||
|
// render models...
|
||||||
PerformanceTimer perfTimer("entities");
|
PerformanceTimer perfTimer("entities");
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
"Application::displaySide() ... entities...");
|
"Application::displaySide() ... entities...");
|
||||||
|
@ -3468,11 +3470,11 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE;
|
RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE;
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) {
|
||||||
renderDebugFlags = (RenderArgs::DebugFlags) (renderDebugFlags | (int) RenderArgs::RENDER_DEBUG_HULLS);
|
renderDebugFlags = (RenderArgs::DebugFlags) (renderDebugFlags | (int)RenderArgs::RENDER_DEBUG_HULLS);
|
||||||
}
|
}
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned)) {
|
||||||
renderDebugFlags =
|
renderDebugFlags =
|
||||||
(RenderArgs::DebugFlags) (renderDebugFlags | (int) RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP);
|
(RenderArgs::DebugFlags) (renderDebugFlags | (int)RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP);
|
||||||
}
|
}
|
||||||
renderArgs->_debugFlags = renderDebugFlags;
|
renderArgs->_debugFlags = renderDebugFlags;
|
||||||
_entities.render(renderArgs);
|
_entities.render(renderArgs);
|
||||||
|
@ -3497,8 +3499,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
pendingChanges.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload);
|
pendingChanges.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
pendingChanges.updateItem<WorldBoxRenderData>(WorldBoxRenderData::_item,
|
pendingChanges.updateItem<WorldBoxRenderData>(WorldBoxRenderData::_item,
|
||||||
[](WorldBoxRenderData& payload) {
|
[](WorldBoxRenderData& payload) {
|
||||||
payload._val++;
|
payload._val++;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3517,7 +3519,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("SceneProcessPendingChanges");
|
PerformanceTimer perfTimer("SceneProcessPendingChanges");
|
||||||
_main3DScene->enqueuePendingChanges(pendingChanges);
|
_main3DScene->enqueuePendingChanges(pendingChanges);
|
||||||
|
|
||||||
_main3DScene->processPendingChangesQueue();
|
_main3DScene->processPendingChangesQueue();
|
||||||
|
@ -4826,7 +4828,7 @@ qreal Application::getDevicePixelRatio() {
|
||||||
mat4 Application::getEyeProjection(int eye) const {
|
mat4 Application::getEyeProjection(int eye) const {
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
return OculusManager::getEyeProjection(eye);
|
return OculusManager::getEyeProjection(eye);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _viewFrustum.getProjection();
|
return _viewFrustum.getProjection();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,13 @@ DatagramProcessor::DatagramProcessor(QObject* parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatagramProcessor::processDatagrams() {
|
void DatagramProcessor::processDatagrams() {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
|
||||||
"DatagramProcessor::processDatagrams()");
|
|
||||||
|
|
||||||
if (_isShuttingDown) {
|
if (_isShuttingDown) {
|
||||||
return; // bail early... we're shutting down.
|
return; // bail early... we're shutting down.
|
||||||
}
|
}
|
||||||
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
|
"DatagramProcessor::processDatagrams()");
|
||||||
|
|
||||||
|
|
||||||
HifiSockAddr senderSockAddr;
|
HifiSockAddr senderSockAddr;
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,7 @@ EntityActionPointer interfaceActionFactory(EntityActionType type, const QUuid& i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityActionPointer InterfaceActionFactory::factory(EntitySimulation* simulation,
|
EntityActionPointer InterfaceActionFactory::factory(EntityActionType type,
|
||||||
EntityActionType type,
|
|
||||||
const QUuid& id,
|
const QUuid& id,
|
||||||
EntityItemPointer ownerEntity,
|
EntityItemPointer ownerEntity,
|
||||||
QVariantMap arguments) {
|
QVariantMap arguments) {
|
||||||
|
@ -51,9 +50,7 @@ EntityActionPointer InterfaceActionFactory::factory(EntitySimulation* simulation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityActionPointer InterfaceActionFactory::factoryBA(EntitySimulation* simulation,
|
EntityActionPointer InterfaceActionFactory::factoryBA(EntityItemPointer ownerEntity, QByteArray data) {
|
||||||
EntityItemPointer ownerEntity,
|
|
||||||
QByteArray data) {
|
|
||||||
QDataStream serializedArgumentStream(data);
|
QDataStream serializedArgumentStream(data);
|
||||||
EntityActionType type;
|
EntityActionType type;
|
||||||
QUuid id;
|
QUuid id;
|
||||||
|
|
|
@ -18,13 +18,11 @@ class InterfaceActionFactory : public EntityActionFactoryInterface {
|
||||||
public:
|
public:
|
||||||
InterfaceActionFactory() : EntityActionFactoryInterface() { }
|
InterfaceActionFactory() : EntityActionFactoryInterface() { }
|
||||||
virtual ~InterfaceActionFactory() { }
|
virtual ~InterfaceActionFactory() { }
|
||||||
virtual EntityActionPointer factory(EntitySimulation* simulation,
|
virtual EntityActionPointer factory(EntityActionType type,
|
||||||
EntityActionType type,
|
|
||||||
const QUuid& id,
|
const QUuid& id,
|
||||||
EntityItemPointer ownerEntity,
|
EntityItemPointer ownerEntity,
|
||||||
QVariantMap arguments);
|
QVariantMap arguments);
|
||||||
virtual EntityActionPointer factoryBA(EntitySimulation* simulation,
|
virtual EntityActionPointer factoryBA(EntityItemPointer ownerEntity,
|
||||||
EntityItemPointer ownerEntity,
|
|
||||||
QByteArray data);
|
QByteArray data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
#include <AudioClient.h>
|
#include <AudioClient.h>
|
||||||
#include <AudioConstants.h>
|
#include <AudioConstants.h>
|
||||||
#include <GeometryCache.h>
|
#include <GeometryCache.h>
|
||||||
|
#include <TextureCache.h>
|
||||||
|
#include <gpu/Context.h>
|
||||||
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
#include "AudioScope.h"
|
#include "AudioScope.h"
|
||||||
|
|
||||||
|
@ -104,7 +107,7 @@ void AudioScope::freeScope() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioScope::render(int width, int height) {
|
void AudioScope::render(RenderArgs* renderArgs, int width, int height) {
|
||||||
|
|
||||||
if (!_isEnabled) {
|
if (!_isEnabled) {
|
||||||
return;
|
return;
|
||||||
|
@ -122,24 +125,26 @@ void AudioScope::render(int width, int height) {
|
||||||
int y = (height - (int)SCOPE_HEIGHT) / 2;
|
int y = (height - (int)SCOPE_HEIGHT) / 2;
|
||||||
int w = (int)SCOPE_WIDTH;
|
int w = (int)SCOPE_WIDTH;
|
||||||
int h = (int)SCOPE_HEIGHT;
|
int h = (int)SCOPE_HEIGHT;
|
||||||
|
|
||||||
renderBackground(backgroundColor, x, y, w, h);
|
gpu::Batch batch;
|
||||||
renderGrid(gridColor, x, y, w, h, gridRows, gridCols);
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
geometryCache->useSimpleDrawPipeline(batch);
|
||||||
renderLineStrip(_inputID, inputColor, x, y, _samplesPerScope, _scopeInputOffset, _scopeInput);
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
renderLineStrip(_outputLeftID, outputLeftColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputLeft);
|
batch.setUniformTexture(0, textureCache->getWhiteTexture());
|
||||||
renderLineStrip(_outputRightD, outputRightColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputRight);
|
mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, -1000, 1000);
|
||||||
|
batch.setProjectionTransform(legacyProjection);
|
||||||
|
batch.setModelTransform(Transform());
|
||||||
|
batch.setViewTransform(Transform());
|
||||||
|
geometryCache->renderQuad(batch, x, y, w, h, backgroundColor);
|
||||||
|
geometryCache->renderGrid(batch, x, y, w, h, gridRows, gridCols, gridColor, _audioScopeGrid);
|
||||||
|
renderLineStrip(batch, _inputID, inputColor, x, y, _samplesPerScope, _scopeInputOffset, _scopeInput);
|
||||||
|
renderLineStrip(batch, _outputLeftID, outputLeftColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputLeft);
|
||||||
|
renderLineStrip(batch, _outputRightD, outputRightColor, x, y, _samplesPerScope, _scopeOutputOffset, _scopeOutputRight);
|
||||||
|
renderArgs->_context->syncCache();
|
||||||
|
renderArgs->_context->render(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioScope::renderBackground(const glm::vec4& color, int x, int y, int width, int height) {
|
void AudioScope::renderLineStrip(gpu::Batch& batch, int id, const glm::vec4& color, int x, int y, int n, int offset, const QByteArray* byteArray) {
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(x, y, width, height, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioScope::renderGrid(const glm::vec4& color, int x, int y, int width, int height, int rows, int cols) {
|
|
||||||
DependencyManager::get<GeometryCache>()->renderGrid(x, y, width, height, rows, cols, color, _audioScopeGrid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioScope::renderLineStrip(int id, const glm::vec4& color, int x, int y, int n, int offset, const QByteArray* byteArray) {
|
|
||||||
|
|
||||||
int16_t sample;
|
int16_t sample;
|
||||||
int16_t* samples = ((int16_t*) byteArray->data()) + offset;
|
int16_t* samples = ((int16_t*) byteArray->data()) + offset;
|
||||||
|
@ -194,7 +199,7 @@ void AudioScope::renderLineStrip(int id, const glm::vec4& color, int x, int y, i
|
||||||
|
|
||||||
|
|
||||||
geometryCache->updateVertices(id, points, color);
|
geometryCache->updateVertices(id, points, color);
|
||||||
geometryCache->renderVertices(gpu::LINE_STRIP, id);
|
geometryCache->renderVertices(batch, gpu::LINE_STRIP, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioScope::addBufferToScope(QByteArray* byteArray, int frameOffset, const int16_t* source, int sourceSamplesPerChannel,
|
int AudioScope::addBufferToScope(QByteArray* byteArray, int frameOffset, const int16_t* source, int sourceSamplesPerChannel,
|
||||||
|
|
|
@ -14,11 +14,14 @@
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <gpu/Batch.h>
|
||||||
|
#include <RenderArgs.h>
|
||||||
|
|
||||||
|
|
||||||
class AudioScope : public QObject, public Dependency {
|
class AudioScope : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
|
@ -28,7 +31,7 @@ public:
|
||||||
void freeScope();
|
void freeScope();
|
||||||
void reallocateScope(int frames);
|
void reallocateScope(int frames);
|
||||||
|
|
||||||
void render(int width, int height);
|
void render(RenderArgs* renderArgs, int width, int height);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggle();
|
void toggle();
|
||||||
|
@ -48,9 +51,7 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Audio scope methods for rendering
|
// Audio scope methods for rendering
|
||||||
static void renderBackground(const glm::vec4& color, int x, int y, int width, int height);
|
void renderLineStrip(gpu::Batch& batch, int id, const glm::vec4& color, int x, int y, int n, int offset, const QByteArray* byteArray);
|
||||||
void renderGrid(const glm::vec4& color, int x, int y, int width, int height, int rows, int cols);
|
|
||||||
void renderLineStrip(int id, const glm::vec4& color, int x, int y, int n, int offset, const QByteArray* byteArray);
|
|
||||||
|
|
||||||
// Audio scope methods for data acquisition
|
// Audio scope methods for data acquisition
|
||||||
int addBufferToScope(QByteArray* byteArray, int frameOffset, const int16_t* source, int sourceSamples,
|
int addBufferToScope(QByteArray* byteArray, int frameOffset, const int16_t* source, int sourceSamples,
|
||||||
|
|
|
@ -52,16 +52,18 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 palmPosition;
|
glm::vec3 palmPosition;
|
||||||
|
glm::quat palmRotation;
|
||||||
if (_hand == "right") {
|
if (_hand == "right") {
|
||||||
palmPosition = myAvatar->getRightPalmPosition();
|
palmPosition = myAvatar->getRightPalmPosition();
|
||||||
|
palmRotation = myAvatar->getRightPalmRotation();
|
||||||
} else {
|
} else {
|
||||||
palmPosition = myAvatar->getLeftPalmPosition();
|
palmPosition = myAvatar->getLeftPalmPosition();
|
||||||
|
palmRotation = myAvatar->getLeftPalmRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rotation = myAvatar->getWorldAlignedOrientation();
|
auto rotation = palmRotation * _relativeRotation;
|
||||||
auto offset = rotation * _relativePosition;
|
auto offset = rotation * _relativePosition;
|
||||||
auto position = palmPosition + offset;
|
auto position = palmPosition + offset;
|
||||||
rotation *= _relativeRotation;
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (!tryLockForWrite()) {
|
if (!tryLockForWrite()) {
|
||||||
|
@ -83,6 +85,13 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_positionalTarget != position || _rotationalTarget != rotation) {
|
||||||
|
auto ownerEntity = _ownerEntity.lock();
|
||||||
|
if (ownerEntity) {
|
||||||
|
ownerEntity->setActionDataDirty(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_positionalTarget = position;
|
_positionalTarget = position;
|
||||||
_rotationalTarget = rotation;
|
_rotationalTarget = rotation;
|
||||||
unlock();
|
unlock();
|
||||||
|
|
|
@ -371,6 +371,12 @@ glm::vec3 MyAvatar::getLeftPalmPosition() {
|
||||||
return leftHandPosition;
|
return leftHandPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::quat MyAvatar::getLeftPalmRotation() {
|
||||||
|
glm::quat leftRotation;
|
||||||
|
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation);
|
||||||
|
return leftRotation;
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 MyAvatar::getRightPalmPosition() {
|
glm::vec3 MyAvatar::getRightPalmPosition() {
|
||||||
glm::vec3 rightHandPosition;
|
glm::vec3 rightHandPosition;
|
||||||
getSkeletonModel().getRightHandPosition(rightHandPosition);
|
getSkeletonModel().getRightHandPosition(rightHandPosition);
|
||||||
|
@ -380,6 +386,12 @@ glm::vec3 MyAvatar::getRightPalmPosition() {
|
||||||
return rightHandPosition;
|
return rightHandPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::quat MyAvatar::getRightPalmRotation() {
|
||||||
|
glm::quat rightRotation;
|
||||||
|
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation);
|
||||||
|
return rightRotation;
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::clearReferential() {
|
void MyAvatar::clearReferential() {
|
||||||
changeReferential(NULL);
|
changeReferential(NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,10 +195,12 @@ public slots:
|
||||||
void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }
|
void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }
|
||||||
|
|
||||||
void updateMotionBehavior();
|
void updateMotionBehavior();
|
||||||
|
|
||||||
glm::vec3 getLeftPalmPosition();
|
glm::vec3 getLeftPalmPosition();
|
||||||
|
glm::quat getLeftPalmRotation();
|
||||||
glm::vec3 getRightPalmPosition();
|
glm::vec3 getRightPalmPosition();
|
||||||
|
glm::quat getRightPalmRotation();
|
||||||
|
|
||||||
void clearReferential();
|
void clearReferential();
|
||||||
bool setModelReferential(const QUuid& id);
|
bool setModelReferential(const QUuid& id);
|
||||||
bool setJointReferential(const QUuid& id, int jointIndex);
|
bool setJointReferential(const QUuid& id, int jointIndex);
|
||||||
|
|
|
@ -184,6 +184,7 @@ void ApplicationCompositor::bindCursorTexture(gpu::Batch& batch, uint8_t cursorI
|
||||||
|
|
||||||
// Draws the FBO texture for the screen
|
// Draws the FBO texture for the screen
|
||||||
void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
|
void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
if (_alpha == 0.0f) {
|
if (_alpha == 0.0f) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -252,6 +253,7 @@ vec2 getPolarCoordinates(const PalmData& palm) {
|
||||||
|
|
||||||
// Draws the FBO texture for Oculus rift.
|
// Draws the FBO texture for Oculus rift.
|
||||||
void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int eye) {
|
void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int eye) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
if (_alpha == 0.0f) {
|
if (_alpha == 0.0f) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ ApplicationOverlay::~ApplicationOverlay() {
|
||||||
|
|
||||||
// Renders the overlays either to a texture or to the screen
|
// Renders the overlays either to a texture or to the screen
|
||||||
void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
||||||
|
|
||||||
|
@ -98,6 +99,7 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
|
void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
if (_uiTexture) {
|
if (_uiTexture) {
|
||||||
gpu::Batch batch;
|
gpu::Batch batch;
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
@ -112,6 +114,7 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) {
|
void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
glm::vec2 size = qApp->getCanvasSize();
|
glm::vec2 size = qApp->getCanvasSize();
|
||||||
|
|
||||||
mat4 legacyProjection = glm::ortho<float>(0, size.x, size.y, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP);
|
mat4 legacyProjection = glm::ortho<float>(0, size.x, size.y, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP);
|
||||||
|
@ -129,11 +132,12 @@ void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) {
|
||||||
emit qApp->renderingOverlay();
|
emit qApp->renderingOverlay();
|
||||||
qApp->getOverlays().renderHUD(renderArgs);
|
qApp->getOverlays().renderHUD(renderArgs);
|
||||||
|
|
||||||
|
DependencyManager::get<AudioScope>()->render(renderArgs, _overlayFramebuffer->size().width(), _overlayFramebuffer->size().height());
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
renderArgs->_context->syncCache();
|
|
||||||
fboViewport(_overlayFramebuffer);
|
fboViewport(_overlayFramebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +223,7 @@ GLuint ApplicationOverlay::getOverlayTexture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::buildFramebufferObject() {
|
void ApplicationOverlay::buildFramebufferObject() {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
QSize fboSize = qApp->getDeviceSize();
|
QSize fboSize = qApp->getDeviceSize();
|
||||||
if (_overlayFramebuffer && fboSize == _overlayFramebuffer->size()) {
|
if (_overlayFramebuffer && fboSize == _overlayFramebuffer->size()) {
|
||||||
// Already built
|
// Already built
|
||||||
|
|
|
@ -75,44 +75,44 @@ void ImageOverlay::render(RenderArgs* args) {
|
||||||
glm::vec2 topLeft(left, top);
|
glm::vec2 topLeft(left, top);
|
||||||
glm::vec2 bottomRight(right, bottom);
|
glm::vec2 bottomRight(right, bottom);
|
||||||
|
|
||||||
float imageWidth = _texture->getWidth();
|
|
||||||
float imageHeight = _texture->getHeight();
|
|
||||||
|
|
||||||
// if for some reason our image is not over 0 width or height, don't attempt to render the image
|
// if for some reason our image is not over 0 width or height, don't attempt to render the image
|
||||||
if (_renderImage && imageWidth > 0 && imageHeight > 0) {
|
if (_renderImage) {
|
||||||
|
float imageWidth = _texture->getWidth();
|
||||||
|
float imageHeight = _texture->getHeight();
|
||||||
|
if (imageWidth > 0 && imageHeight > 0) {
|
||||||
|
QRect fromImage;
|
||||||
|
if (_wantClipFromImage) {
|
||||||
|
float scaleX = imageWidth / _texture->getOriginalWidth();
|
||||||
|
float scaleY = imageHeight / _texture->getOriginalHeight();
|
||||||
|
|
||||||
QRect fromImage;
|
fromImage.setX(scaleX * _fromImage.x());
|
||||||
if (_wantClipFromImage) {
|
fromImage.setY(scaleY * _fromImage.y());
|
||||||
float scaleX = imageWidth / _texture->getOriginalWidth();
|
fromImage.setWidth(scaleX * _fromImage.width());
|
||||||
float scaleY = imageHeight / _texture->getOriginalHeight();
|
fromImage.setHeight(scaleY * _fromImage.height());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fromImage.setX(0);
|
||||||
|
fromImage.setY(0);
|
||||||
|
fromImage.setWidth(imageWidth);
|
||||||
|
fromImage.setHeight(imageHeight);
|
||||||
|
}
|
||||||
|
|
||||||
fromImage.setX(scaleX * _fromImage.x());
|
float x = fromImage.x() / imageWidth;
|
||||||
fromImage.setY(scaleY * _fromImage.y());
|
float y = fromImage.y() / imageHeight;
|
||||||
fromImage.setWidth(scaleX * _fromImage.width());
|
float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure
|
||||||
fromImage.setHeight(scaleY * _fromImage.height());
|
float h = fromImage.height() / imageHeight;
|
||||||
|
|
||||||
|
glm::vec2 texCoordTopLeft(x, y);
|
||||||
|
glm::vec2 texCoordBottomRight(x + w, y + h);
|
||||||
|
|
||||||
|
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor);
|
||||||
} else {
|
} else {
|
||||||
fromImage.setX(0);
|
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, quadColor);
|
||||||
fromImage.setY(0);
|
|
||||||
fromImage.setWidth(imageWidth);
|
|
||||||
fromImage.setHeight(imageHeight);
|
|
||||||
}
|
}
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
float x = fromImage.x() / imageWidth;
|
|
||||||
float y = fromImage.y() / imageHeight;
|
|
||||||
float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure
|
|
||||||
float h = fromImage.height() / imageHeight;
|
|
||||||
|
|
||||||
glm::vec2 texCoordTopLeft(x, y);
|
|
||||||
glm::vec2 texCoordBottomRight(x + w, y + h);
|
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor);
|
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, quadColor);
|
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, quadColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_renderImage) {
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageOverlay::setProperties(const QScriptValue& properties) {
|
void ImageOverlay::setProperties(const QScriptValue& properties) {
|
||||||
|
|
|
@ -96,6 +96,7 @@ void Overlays::cleanupOverlaysToDelete() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::renderHUD(RenderArgs* renderArgs) {
|
void Overlays::renderHUD(RenderArgs* renderArgs) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
QReadLocker lock(&_lock);
|
QReadLocker lock(&_lock);
|
||||||
gpu::Batch batch;
|
gpu::Batch batch;
|
||||||
renderArgs->_batch = &batch;
|
renderArgs->_batch = &batch;
|
||||||
|
|
|
@ -802,6 +802,8 @@ void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityS
|
||||||
connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity);
|
connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity);
|
||||||
connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity);
|
connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity);
|
||||||
connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity);
|
connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity);
|
||||||
|
|
||||||
|
connect(&(*DependencyManager::get<SceneScriptingInterface>()), &SceneScriptingInterface::shouldRenderEntitiesChanged, this, &EntityTreeRenderer::updateEntityRenderStatus, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValueList EntityTreeRenderer::createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID) {
|
QScriptValueList EntityTreeRenderer::createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID) {
|
||||||
|
@ -1152,3 +1154,17 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
|
||||||
entityScriptB.property("collisionWithEntity").call(entityScriptA, args);
|
entityScriptB.property("collisionWithEntity").call(entityScriptA, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTreeRenderer::updateEntityRenderStatus(bool shouldRenderEntities) {
|
||||||
|
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||||
|
for (auto entityID : _entityIDsLastInScene) {
|
||||||
|
addingEntity(entityID);
|
||||||
|
}
|
||||||
|
_entityIDsLastInScene.clear();
|
||||||
|
} else {
|
||||||
|
_entityIDsLastInScene = _entitiesInScene.keys();
|
||||||
|
for (auto entityID : _entityIDsLastInScene) {
|
||||||
|
deletingEntity(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -90,6 +90,9 @@ public:
|
||||||
virtual void scriptContentsAvailable(const QUrl& url, const QString& scriptContents);
|
virtual void scriptContentsAvailable(const QUrl& url, const QString& scriptContents);
|
||||||
virtual void errorInLoadingScript(const QUrl& url);
|
virtual void errorInLoadingScript(const QUrl& url);
|
||||||
|
|
||||||
|
// For Scene.shouldRenderEntities
|
||||||
|
QList<EntityItemID>& getEntitiesLastInScene() { return _entityIDsLastInScene; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void mousePressOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
void mousePressOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
||||||
void mouseMoveOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
void mouseMoveOnEntity(const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId);
|
||||||
|
@ -112,6 +115,7 @@ public slots:
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
void deletingEntity(const EntityItemID& entityID);
|
||||||
void entitySciptChanging(const EntityItemID& entityID, const bool reload);
|
void entitySciptChanging(const EntityItemID& entityID, const bool reload);
|
||||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||||
|
void updateEntityRenderStatus(bool shouldRenderEntities);
|
||||||
|
|
||||||
// optional slots that can be wired to menu items
|
// optional slots that can be wired to menu items
|
||||||
void setDisplayElementChildProxies(bool value) { _displayElementChildProxies = value; }
|
void setDisplayElementChildProxies(bool value) { _displayElementChildProxies = value; }
|
||||||
|
@ -188,6 +192,8 @@ private:
|
||||||
int _previousStageDay;
|
int _previousStageDay;
|
||||||
|
|
||||||
QHash<EntityItemID, EntityItemPointer> _entitiesInScene;
|
QHash<EntityItemID, EntityItemPointer> _entitiesInScene;
|
||||||
|
// For Scene.shouldRenderEntities
|
||||||
|
QList<EntityItemID> _entityIDsLastInScene;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,11 @@ class EntityActionFactoryInterface : public QObject, public Dependency {
|
||||||
public:
|
public:
|
||||||
EntityActionFactoryInterface() { }
|
EntityActionFactoryInterface() { }
|
||||||
virtual ~EntityActionFactoryInterface() { }
|
virtual ~EntityActionFactoryInterface() { }
|
||||||
virtual EntityActionPointer factory(EntitySimulation* simulation,
|
virtual EntityActionPointer factory(EntityActionType type,
|
||||||
EntityActionType type,
|
|
||||||
const QUuid& id,
|
const QUuid& id,
|
||||||
EntityItemPointer ownerEntity,
|
EntityItemPointer ownerEntity,
|
||||||
QVariantMap arguments) { assert(false); return nullptr; }
|
QVariantMap arguments) { assert(false); return nullptr; }
|
||||||
virtual EntityActionPointer factoryBA(EntitySimulation* simulation,
|
virtual EntityActionPointer factoryBA(EntityItemPointer ownerEntity,
|
||||||
EntityItemPointer ownerEntity,
|
|
||||||
QByteArray data) { assert(false); return nullptr; }
|
QByteArray data) { assert(false); return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1489,20 +1489,22 @@ void EntityItem::clearSimulationOwnership() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer action) {
|
bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer action) {
|
||||||
|
lockForWrite();
|
||||||
checkWaitingToRemove(simulation);
|
checkWaitingToRemove(simulation);
|
||||||
if (!checkWaitingActionData(simulation)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool result = addActionInternal(simulation, action);
|
bool result = addActionInternal(simulation, action);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
removeAction(simulation, action->getID());
|
removeAction(simulation, action->getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItem::addActionInternal(EntitySimulation* simulation, EntityActionPointer action) {
|
bool EntityItem::addActionInternal(EntitySimulation* simulation, EntityActionPointer action) {
|
||||||
|
assertLocked();
|
||||||
assert(action);
|
assert(action);
|
||||||
assert(simulation);
|
assert(simulation);
|
||||||
auto actionOwnerEntity = action->getOwnerEntity().lock();
|
auto actionOwnerEntity = action->getOwnerEntity().lock();
|
||||||
|
@ -1523,36 +1525,37 @@ bool EntityItem::addActionInternal(EntitySimulation* simulation, EntityActionPoi
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItem::updateAction(EntitySimulation* simulation, const QUuid& actionID, const QVariantMap& arguments) {
|
bool EntityItem::updateAction(EntitySimulation* simulation, const QUuid& actionID, const QVariantMap& arguments) {
|
||||||
|
lockForWrite();
|
||||||
checkWaitingToRemove(simulation);
|
checkWaitingToRemove(simulation);
|
||||||
if (!checkWaitingActionData(simulation)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_objectActions.contains(actionID)) {
|
if (!_objectActions.contains(actionID)) {
|
||||||
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
EntityActionPointer action = _objectActions[actionID];
|
EntityActionPointer action = _objectActions[actionID];
|
||||||
bool success = action->updateArguments(arguments);
|
|
||||||
|
|
||||||
|
bool success = action->updateArguments(arguments);
|
||||||
if (success) {
|
if (success) {
|
||||||
_allActionsDataCache = serializeActions(success);
|
_allActionsDataCache = serializeActions(success);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "EntityItem::updateAction failed";
|
qDebug() << "EntityItem::updateAction failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItem::removeAction(EntitySimulation* simulation, const QUuid& actionID) {
|
bool EntityItem::removeAction(EntitySimulation* simulation, const QUuid& actionID) {
|
||||||
|
lockForWrite();
|
||||||
checkWaitingToRemove(simulation);
|
checkWaitingToRemove(simulation);
|
||||||
if (!checkWaitingActionData(simulation)) {
|
|
||||||
return false;;
|
|
||||||
}
|
|
||||||
|
|
||||||
return removeActionInternal(actionID);
|
bool success = removeActionInternal(actionID);
|
||||||
|
unlock();
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* simulation) {
|
bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* simulation) {
|
||||||
|
assertWriteLocked();
|
||||||
if (_objectActions.contains(actionID)) {
|
if (_objectActions.contains(actionID)) {
|
||||||
if (!simulation) {
|
if (!simulation) {
|
||||||
EntityTree* entityTree = _element ? _element->getTree() : nullptr;
|
EntityTree* entityTree = _element ? _element->getTree() : nullptr;
|
||||||
|
@ -1575,7 +1578,7 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* s
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItem::clearActions(EntitySimulation* simulation) {
|
bool EntityItem::clearActions(EntitySimulation* simulation) {
|
||||||
_waitingActionData.clear();
|
lockForWrite();
|
||||||
QHash<QUuid, EntityActionPointer>::iterator i = _objectActions.begin();
|
QHash<QUuid, EntityActionPointer>::iterator i = _objectActions.begin();
|
||||||
while (i != _objectActions.end()) {
|
while (i != _objectActions.end()) {
|
||||||
const QUuid id = i.key();
|
const QUuid id = i.key();
|
||||||
|
@ -1584,85 +1587,84 @@ bool EntityItem::clearActions(EntitySimulation* simulation) {
|
||||||
action->setOwnerEntity(nullptr);
|
action->setOwnerEntity(nullptr);
|
||||||
action->removeFromSimulation(simulation);
|
action->removeFromSimulation(simulation);
|
||||||
}
|
}
|
||||||
|
// empty _serializedActions means no actions for the EntityItem
|
||||||
_actionsToRemove.clear();
|
_actionsToRemove.clear();
|
||||||
_allActionsDataCache.clear();
|
_allActionsDataCache.clear();
|
||||||
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityItem::deserializeActions(QByteArray allActionsData, EntitySimulation* simulation) const {
|
|
||||||
bool success = true;
|
void EntityItem::deserializeActions() {
|
||||||
QVector<QByteArray> serializedActions;
|
assertUnlocked();
|
||||||
if (allActionsData.size() > 0) {
|
lockForWrite();
|
||||||
QDataStream serializedActionsStream(allActionsData);
|
deserializeActionsInternal();
|
||||||
serializedActionsStream >> serializedActions;
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EntityItem::deserializeActionsInternal() {
|
||||||
|
assertWriteLocked();
|
||||||
|
|
||||||
|
if (!_element) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep track of which actions got added or updated by the new actionData
|
// Keep track of which actions got added or updated by the new actionData
|
||||||
QSet<QUuid> updated;
|
|
||||||
|
|
||||||
EntityTree* entityTree = _element ? _element->getTree() : nullptr;
|
EntityTree* entityTree = _element ? _element->getTree() : nullptr;
|
||||||
if (!simulation) {
|
assert(entityTree);
|
||||||
simulation = entityTree ? entityTree->getSimulation() : nullptr;
|
EntitySimulation* simulation = entityTree ? entityTree->getSimulation() : nullptr;
|
||||||
|
assert(simulation);
|
||||||
|
|
||||||
|
QVector<QByteArray> serializedActions;
|
||||||
|
if (_allActionsDataCache.size() > 0) {
|
||||||
|
QDataStream serializedActionsStream(_allActionsDataCache);
|
||||||
|
serializedActionsStream >> serializedActions;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simulation && entityTree) {
|
QSet<QUuid> updated;
|
||||||
foreach(QByteArray serializedAction, serializedActions) {
|
|
||||||
QDataStream serializedActionStream(serializedAction);
|
|
||||||
EntityActionType actionType;
|
|
||||||
QUuid actionID;
|
|
||||||
serializedActionStream >> actionType;
|
|
||||||
serializedActionStream >> actionID;
|
|
||||||
updated << actionID;
|
|
||||||
|
|
||||||
if (_objectActions.contains(actionID)) {
|
foreach(QByteArray serializedAction, serializedActions) {
|
||||||
EntityActionPointer action = _objectActions[actionID];
|
QDataStream serializedActionStream(serializedAction);
|
||||||
// TODO: make sure types match? there isn't currently a way to
|
EntityActionType actionType;
|
||||||
// change the type of an existing action.
|
QUuid actionID;
|
||||||
action->deserialize(serializedAction);
|
serializedActionStream >> actionType;
|
||||||
} else {
|
serializedActionStream >> actionID;
|
||||||
auto actionFactory = DependencyManager::get<EntityActionFactoryInterface>();
|
updated << actionID;
|
||||||
if (simulation) {
|
|
||||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(_id);
|
if (_objectActions.contains(actionID)) {
|
||||||
EntityActionPointer action = actionFactory->factoryBA(simulation, entity, serializedAction);
|
EntityActionPointer action = _objectActions[actionID];
|
||||||
if (action) {
|
// TODO: make sure types match? there isn't currently a way to
|
||||||
entity->addActionInternal(simulation, action);
|
// change the type of an existing action.
|
||||||
}
|
action->deserialize(serializedAction);
|
||||||
} else {
|
} else {
|
||||||
// we can't yet add the action. This method will be called later.
|
auto actionFactory = DependencyManager::get<EntityActionFactoryInterface>();
|
||||||
success = false;
|
|
||||||
}
|
// EntityItemPointer entity = entityTree->findEntityByEntityItemID(_id, false);
|
||||||
|
EntityItemPointer entity = shared_from_this();
|
||||||
|
EntityActionPointer action = actionFactory->factoryBA(entity, serializedAction);
|
||||||
|
if (action) {
|
||||||
|
entity->addActionInternal(simulation, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove any actions that weren't included in the new data.
|
// remove any actions that weren't included in the new data.
|
||||||
QHash<QUuid, EntityActionPointer>::const_iterator i = _objectActions.begin();
|
QHash<QUuid, EntityActionPointer>::const_iterator i = _objectActions.begin();
|
||||||
while (i != _objectActions.end()) {
|
while (i != _objectActions.end()) {
|
||||||
const QUuid id = i.key();
|
QUuid id = i.key();
|
||||||
if (!updated.contains(id)) {
|
if (!updated.contains(id)) {
|
||||||
_actionsToRemove << id;
|
_actionsToRemove << id;
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
} else {
|
i++;
|
||||||
// no simulation
|
|
||||||
success = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
bool EntityItem::checkWaitingActionData(EntitySimulation* simulation) const {
|
|
||||||
if (_waitingActionData.size() == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool success = deserializeActions(_waitingActionData, simulation);
|
|
||||||
if (success) {
|
|
||||||
_waitingActionData.clear();
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) {
|
void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) {
|
||||||
|
assertLocked();
|
||||||
foreach(QUuid actionID, _actionsToRemove) {
|
foreach(QUuid actionID, _actionsToRemove) {
|
||||||
removeActionInternal(actionID, simulation);
|
removeActionInternal(actionID, simulation);
|
||||||
}
|
}
|
||||||
|
@ -1670,21 +1672,22 @@ void EntityItem::checkWaitingToRemove(EntitySimulation* simulation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::setActionData(QByteArray actionData) {
|
void EntityItem::setActionData(QByteArray actionData) {
|
||||||
|
assertUnlocked();
|
||||||
|
lockForWrite();
|
||||||
|
setActionDataInternal(actionData);
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::setActionDataInternal(QByteArray actionData) {
|
||||||
|
assertWriteLocked();
|
||||||
checkWaitingToRemove();
|
checkWaitingToRemove();
|
||||||
bool success = deserializeActions(actionData);
|
|
||||||
_allActionsDataCache = actionData;
|
_allActionsDataCache = actionData;
|
||||||
if (success) {
|
deserializeActionsInternal();
|
||||||
_waitingActionData.clear();
|
|
||||||
} else {
|
|
||||||
_waitingActionData = actionData;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray EntityItem::serializeActions(bool& success) const {
|
QByteArray EntityItem::serializeActions(bool& success) const {
|
||||||
|
assertLocked();
|
||||||
QByteArray result;
|
QByteArray result;
|
||||||
if (!checkWaitingActionData()) {
|
|
||||||
return _waitingActionData;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_objectActions.size() == 0) {
|
if (_objectActions.size() == 0) {
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -1713,21 +1716,132 @@ QByteArray EntityItem::serializeActions(bool& success) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray EntityItem::getActionData() const {
|
const QByteArray EntityItem::getActionDataInternal() const {
|
||||||
|
if (_actionDataDirty) {
|
||||||
|
bool success;
|
||||||
|
QByteArray newDataCache = serializeActions(success);
|
||||||
|
if (success) {
|
||||||
|
_allActionsDataCache = newDataCache;
|
||||||
|
}
|
||||||
|
_actionDataDirty = false;
|
||||||
|
}
|
||||||
return _allActionsDataCache;
|
return _allActionsDataCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QByteArray EntityItem::getActionData() const {
|
||||||
|
assertUnlocked();
|
||||||
|
lockForRead();
|
||||||
|
auto result = getActionDataInternal();
|
||||||
|
unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap EntityItem::getActionArguments(const QUuid& actionID) const {
|
QVariantMap EntityItem::getActionArguments(const QUuid& actionID) const {
|
||||||
QVariantMap result;
|
QVariantMap result;
|
||||||
|
lockForRead();
|
||||||
if (!checkWaitingActionData()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_objectActions.contains(actionID)) {
|
if (_objectActions.contains(actionID)) {
|
||||||
EntityActionPointer action = _objectActions[actionID];
|
EntityActionPointer action = _objectActions[actionID];
|
||||||
result = action->getArguments();
|
result = action->getArguments();
|
||||||
result["type"] = EntityActionInterface::actionTypeToString(action->getType());
|
result["type"] = EntityActionInterface::actionTypeToString(action->getType());
|
||||||
}
|
}
|
||||||
|
unlock();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define ENABLE_LOCKING 1
|
||||||
|
|
||||||
|
#ifdef ENABLE_LOCKING
|
||||||
|
void EntityItem::lockForRead() const {
|
||||||
|
_lock.lockForRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityItem::tryLockForRead() const {
|
||||||
|
return _lock.tryLockForRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::lockForWrite() const {
|
||||||
|
_lock.lockForWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityItem::tryLockForWrite() const {
|
||||||
|
return _lock.tryLockForWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItem::unlock() const {
|
||||||
|
_lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityItem::isLocked() const {
|
||||||
|
bool readSuccess = tryLockForRead();
|
||||||
|
if (readSuccess) {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
bool writeSuccess = tryLockForWrite();
|
||||||
|
if (writeSuccess) {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
if (readSuccess && writeSuccess) {
|
||||||
|
return false; // if we can take both kinds of lock, there was no previous lock
|
||||||
|
}
|
||||||
|
return true; // either read or write failed, so there is some lock in place.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool EntityItem::isWriteLocked() const {
|
||||||
|
bool readSuccess = tryLockForRead();
|
||||||
|
if (readSuccess) {
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool writeSuccess = tryLockForWrite();
|
||||||
|
if (writeSuccess) {
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true; // either read or write failed, so there is some lock in place.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool EntityItem::isUnlocked() const {
|
||||||
|
// this can't be sure -- this may get unlucky and hit locks from other threads. what we're actually trying
|
||||||
|
// to discover is if *this* thread hasn't locked the EntityItem. Try repeatedly to take both kinds of lock.
|
||||||
|
bool readSuccess = false;
|
||||||
|
for (int i=0; i<80; i++) {
|
||||||
|
readSuccess = tryLockForRead();
|
||||||
|
if (readSuccess) {
|
||||||
|
unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QThread::usleep(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool writeSuccess = false;
|
||||||
|
if (readSuccess) {
|
||||||
|
for (int i=0; i<80; i++) {
|
||||||
|
writeSuccess = tryLockForWrite();
|
||||||
|
if (writeSuccess) {
|
||||||
|
unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QThread::usleep(300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readSuccess && writeSuccess) {
|
||||||
|
return true; // if we can take both kinds of lock, there was no previous lock
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void EntityItem::lockForRead() const { }
|
||||||
|
bool EntityItem::tryLockForRead() const { return true; }
|
||||||
|
void EntityItem::lockForWrite() const { }
|
||||||
|
bool EntityItem::tryLockForWrite() const { return true; }
|
||||||
|
void EntityItem::unlock() const { }
|
||||||
|
bool EntityItem::isLocked() const { return true; }
|
||||||
|
bool EntityItem::isWriteLocked() const { return true; }
|
||||||
|
bool EntityItem::isUnlocked() const { return true; }
|
||||||
|
#endif
|
||||||
|
|
|
@ -68,10 +68,28 @@ const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f;
|
||||||
#define debugTimeOnly(T) qPrintable(QString("%1").arg(T, 16, 10))
|
#define debugTimeOnly(T) qPrintable(QString("%1").arg(T, 16, 10))
|
||||||
#define debugTreeVector(V) V << "[" << V << " in meters ]"
|
#define debugTreeVector(V) V << "[" << V << " in meters ]"
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define assertLocked() assert(isLocked())
|
||||||
|
#else
|
||||||
|
#define assertLocked()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define assertWriteLocked() assert(isWriteLocked())
|
||||||
|
#else
|
||||||
|
#define assertWriteLocked()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define assertUnlocked() assert(isUnlocked())
|
||||||
|
#else
|
||||||
|
#define assertUnlocked()
|
||||||
|
#endif
|
||||||
|
|
||||||
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
||||||
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
||||||
/// one directly, instead you must only construct one of it's derived classes with additional features.
|
/// one directly, instead you must only construct one of it's derived classes with additional features.
|
||||||
class EntityItem {
|
class EntityItem : public std::enable_shared_from_this<EntityItem> {
|
||||||
// These two classes manage lists of EntityItem pointers and must be able to cleanup pointers when an EntityItem is deleted.
|
// These two classes manage lists of EntityItem pointers and must be able to cleanup pointers when an EntityItem is deleted.
|
||||||
// To make the cleanup robust each EntityItem has backpointers to its manager classes (which are only ever set/cleared by
|
// To make the cleanup robust each EntityItem has backpointers to its manager classes (which are only ever set/cleared by
|
||||||
// the managers themselves, hence they are fiends) whose NULL status can be used to determine which managers still need to
|
// the managers themselves, hence they are fiends) whose NULL status can be used to determine which managers still need to
|
||||||
|
@ -395,9 +413,14 @@ public:
|
||||||
bool hasActions() { return !_objectActions.empty(); }
|
bool hasActions() { return !_objectActions.empty(); }
|
||||||
QList<QUuid> getActionIDs() { return _objectActions.keys(); }
|
QList<QUuid> getActionIDs() { return _objectActions.keys(); }
|
||||||
QVariantMap getActionArguments(const QUuid& actionID) const;
|
QVariantMap getActionArguments(const QUuid& actionID) const;
|
||||||
|
void deserializeActions();
|
||||||
|
void setActionDataDirty(bool value) const { _actionDataDirty = value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
const QByteArray getActionDataInternal() const;
|
||||||
|
void setActionDataInternal(QByteArray actionData);
|
||||||
|
|
||||||
static bool _sendPhysicsUpdates;
|
static bool _sendPhysicsUpdates;
|
||||||
EntityTypes::EntityType _type;
|
EntityTypes::EntityType _type;
|
||||||
QUuid _id;
|
QUuid _id;
|
||||||
|
@ -470,18 +493,28 @@ protected:
|
||||||
|
|
||||||
bool addActionInternal(EntitySimulation* simulation, EntityActionPointer action);
|
bool addActionInternal(EntitySimulation* simulation, EntityActionPointer action);
|
||||||
bool removeActionInternal(const QUuid& actionID, EntitySimulation* simulation = nullptr);
|
bool removeActionInternal(const QUuid& actionID, EntitySimulation* simulation = nullptr);
|
||||||
bool deserializeActions(QByteArray allActionsData, EntitySimulation* simulation = nullptr) const;
|
void deserializeActionsInternal();
|
||||||
QByteArray serializeActions(bool& success) const;
|
QByteArray serializeActions(bool& success) const;
|
||||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||||
|
|
||||||
static int _maxActionsDataSize;
|
static int _maxActionsDataSize;
|
||||||
mutable QByteArray _allActionsDataCache;
|
mutable QByteArray _allActionsDataCache;
|
||||||
// when an entity-server starts up, EntityItem::setActionData is called before the entity-tree is
|
// when an entity-server starts up, EntityItem::setActionData is called before the entity-tree is
|
||||||
// ready. This means we can't find our EntityItemPointer or add the action to the simulation. These
|
// ready. This means we can't find our EntityItemPointer or add the action to the simulation. These
|
||||||
// are used to keep track of and work around this situation.
|
// are used to keep track of and work around this situation.
|
||||||
bool checkWaitingActionData(EntitySimulation* simulation = nullptr) const;
|
|
||||||
void checkWaitingToRemove(EntitySimulation* simulation = nullptr);
|
void checkWaitingToRemove(EntitySimulation* simulation = nullptr);
|
||||||
mutable QByteArray _waitingActionData;
|
|
||||||
mutable QSet<QUuid> _actionsToRemove;
|
mutable QSet<QUuid> _actionsToRemove;
|
||||||
|
mutable bool _actionDataDirty = false;
|
||||||
|
|
||||||
|
mutable QReadWriteLock _lock;
|
||||||
|
void lockForRead() const;
|
||||||
|
bool tryLockForRead() const;
|
||||||
|
void lockForWrite() const;
|
||||||
|
bool tryLockForWrite() const;
|
||||||
|
void unlock() const;
|
||||||
|
bool isLocked() const;
|
||||||
|
bool isWriteLocked() const;
|
||||||
|
bool isUnlocked() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityItem_h
|
#endif // hifi_EntityItem_h
|
||||||
|
|
|
@ -574,7 +574,7 @@ QUuid EntityScriptingInterface::addAction(const QString& actionTypeString,
|
||||||
if (actionType == ACTION_TYPE_NONE) {
|
if (actionType == ACTION_TYPE_NONE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
EntityActionPointer action = actionFactory->factory(simulation, actionType, actionID, entity, arguments);
|
EntityActionPointer action = actionFactory->factory(actionType, actionID, entity, arguments);
|
||||||
if (action) {
|
if (action) {
|
||||||
entity->addAction(simulation, action);
|
entity->addAction(simulation, action);
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
|
@ -146,6 +146,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
|
||||||
|
|
||||||
void EntitySimulation::addEntity(EntityItemPointer entity) {
|
void EntitySimulation::addEntity(EntityItemPointer entity) {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
|
entity->deserializeActions();
|
||||||
if (entity->isMortal()) {
|
if (entity->isMortal()) {
|
||||||
_mortalEntities.insert(entity);
|
_mortalEntities.insert(entity);
|
||||||
quint64 expiry = entity->getExpiry();
|
quint64 expiry = entity->getExpiry();
|
||||||
|
|
|
@ -117,7 +117,7 @@ void GLBackend::updateTransform() {
|
||||||
if (_transform._invalidView || _transform._invalidProj || _transform._invalidViewport) {
|
if (_transform._invalidView || _transform._invalidProj || _transform._invalidViewport) {
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, 0);
|
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, 0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _transform._transformCameraBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, _transform._transformCameraBuffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera, GL_DYNAMIC_DRAW);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_transform._transformCamera), (const void*)&_transform._transformCamera);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ void GLBackend::updateTransform() {
|
||||||
if (_transform._invalidModel) {
|
if (_transform._invalidModel) {
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, 0);
|
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, 0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _transform._transformObjectBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, _transform._transformObjectBuffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformObject), (const void*) &_transform._transformObject, GL_DYNAMIC_DRAW);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_transform._transformObject), (const void*) &_transform._transformObject);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,6 +287,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_serverActionData != _entity->getActionData()) {
|
if (_serverActionData != _entity->getActionData()) {
|
||||||
|
setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
|
||||||
#include <gpu/GPUConfig.h>
|
#include <gpu/GPUConfig.h>
|
||||||
|
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
@ -24,7 +23,7 @@
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
|
|
||||||
#include "gpu/Batch.h"
|
#include "gpu/Batch.h"
|
||||||
#include "gpu/GLBackend.h"
|
#include "gpu/Context.h"
|
||||||
#include "gpu/StandardShaderLib.h"
|
#include "gpu/StandardShaderLib.h"
|
||||||
|
|
||||||
#include "simple_vert.h"
|
#include "simple_vert.h"
|
||||||
|
@ -269,7 +268,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
||||||
|
|
||||||
// Fetch the ViewMatrix;
|
// Fetch the ViewMatrix;
|
||||||
glm::mat4 invViewMat;
|
glm::mat4 invViewMat;
|
||||||
_viewState->getViewTransform().getMatrix(invViewMat);
|
invViewMat = args->_viewFrustum->getView();
|
||||||
|
|
||||||
auto& program = _directionalLight;
|
auto& program = _directionalLight;
|
||||||
const LightLocations* locations = &_directionalLightLocations;
|
const LightLocations* locations = &_directionalLightLocations;
|
||||||
|
@ -344,7 +343,8 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
||||||
|
|
||||||
float left, right, bottom, top, nearVal, farVal;
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
glm::vec4 nearClipPlane, farClipPlane;
|
glm::vec4 nearClipPlane, farClipPlane;
|
||||||
_viewState->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||||
|
|
||||||
batch._glUniform1f(locations->nearLocation, nearVal);
|
batch._glUniform1f(locations->nearLocation, nearVal);
|
||||||
|
|
||||||
float depthScale = (farVal - nearVal) / farVal;
|
float depthScale = (farVal - nearVal) / farVal;
|
||||||
|
@ -394,9 +394,9 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
||||||
|
|
||||||
// enlarge the scales slightly to account for tesselation
|
// enlarge the scales slightly to account for tesselation
|
||||||
const float SCALE_EXPANSION = 0.05f;
|
const float SCALE_EXPANSION = 0.05f;
|
||||||
|
|
||||||
const glm::vec3& eyePoint = _viewState->getCurrentViewFrustum()->getPosition();
|
auto eyePoint = args->_viewFrustum->getPosition();
|
||||||
float nearRadius = glm::distance(eyePoint, _viewState->getCurrentViewFrustum()->getNearTopLeft());
|
float nearRadius = glm::distance(eyePoint, args->_viewFrustum->getNearTopLeft());
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
|
|
|
@ -279,14 +279,21 @@ void GeometryCache::renderSphere(gpu::Batch& batch, float radius, int slices, in
|
||||||
const int VERTICES_SLOT = 0;
|
const int VERTICES_SLOT = 0;
|
||||||
const int NORMALS_SLOT = 1;
|
const int NORMALS_SLOT = 1;
|
||||||
const int COLOR_SLOT = 2;
|
const int COLOR_SLOT = 2;
|
||||||
gpu::Stream::FormatPointer streamFormat(new gpu::Stream::Format()); // 1 for everyone
|
static gpu::Stream::FormatPointer streamFormat;
|
||||||
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
static gpu::Element positionElement, normalElement, colorElement;
|
||||||
streamFormat->setAttribute(gpu::Stream::NORMAL, NORMALS_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
if (!streamFormat) {
|
||||||
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA));
|
streamFormat.reset(new gpu::Stream::Format()); // 1 for everyone
|
||||||
|
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||||
|
streamFormat->setAttribute(gpu::Stream::NORMAL, NORMALS_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
||||||
|
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA));
|
||||||
|
positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
|
||||||
|
normalElement = streamFormat->getAttributes().at(gpu::Stream::NORMAL)._element;
|
||||||
|
colorElement = streamFormat->getAttributes().at(gpu::Stream::COLOR)._element;
|
||||||
|
}
|
||||||
|
|
||||||
gpu::BufferView verticesView(verticesBuffer, streamFormat->getAttributes().at(gpu::Stream::POSITION)._element);
|
gpu::BufferView verticesView(verticesBuffer, positionElement);
|
||||||
gpu::BufferView normalsView(verticesBuffer, streamFormat->getAttributes().at(gpu::Stream::NORMAL)._element);
|
gpu::BufferView normalsView(verticesBuffer, normalElement);
|
||||||
gpu::BufferView colorView(colorBuffer, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
|
gpu::BufferView colorView(colorBuffer, colorElement);
|
||||||
|
|
||||||
batch.setInputFormat(streamFormat);
|
batch.setInputFormat(streamFormat);
|
||||||
batch.setInputBuffer(VERTICES_SLOT, verticesView);
|
batch.setInputBuffer(VERTICES_SLOT, verticesView);
|
||||||
|
@ -899,14 +906,21 @@ void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::ve
|
||||||
const int VERTICES_SLOT = 0;
|
const int VERTICES_SLOT = 0;
|
||||||
const int NORMALS_SLOT = 1;
|
const int NORMALS_SLOT = 1;
|
||||||
const int COLOR_SLOT = 2;
|
const int COLOR_SLOT = 2;
|
||||||
gpu::Stream::FormatPointer streamFormat(new gpu::Stream::Format()); // 1 for everyone
|
static gpu::Stream::FormatPointer streamFormat;
|
||||||
|
static gpu::Element positionElement, normalElement, colorElement;
|
||||||
|
if (!streamFormat) {
|
||||||
|
streamFormat.reset(new gpu::Stream::Format()); // 1 for everyone
|
||||||
|
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||||
|
streamFormat->setAttribute(gpu::Stream::NORMAL, NORMALS_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
||||||
|
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA));
|
||||||
|
positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
|
||||||
|
normalElement = streamFormat->getAttributes().at(gpu::Stream::NORMAL)._element;
|
||||||
|
colorElement = streamFormat->getAttributes().at(gpu::Stream::COLOR)._element;
|
||||||
|
}
|
||||||
|
|
||||||
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
|
||||||
streamFormat->setAttribute(gpu::Stream::NORMAL, NORMALS_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
gpu::BufferView verticesView(verticesBuffer, 0, verticesBuffer->getSize(), VERTEX_STRIDE, positionElement);
|
||||||
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA));
|
gpu::BufferView normalsView(verticesBuffer, NORMALS_OFFSET, verticesBuffer->getSize(), VERTEX_STRIDE, normalElement);
|
||||||
|
|
||||||
gpu::BufferView verticesView(verticesBuffer, 0, verticesBuffer->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::POSITION)._element);
|
|
||||||
gpu::BufferView normalsView(verticesBuffer, NORMALS_OFFSET, verticesBuffer->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::NORMAL)._element);
|
|
||||||
gpu::BufferView colorView(colorBuffer, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
|
gpu::BufferView colorView(colorBuffer, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
|
||||||
|
|
||||||
batch.setInputFormat(streamFormat);
|
batch.setInputFormat(streamFormat);
|
||||||
|
@ -986,12 +1000,18 @@ void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec
|
||||||
|
|
||||||
const int VERTICES_SLOT = 0;
|
const int VERTICES_SLOT = 0;
|
||||||
const int COLOR_SLOT = 1;
|
const int COLOR_SLOT = 1;
|
||||||
gpu::Stream::FormatPointer streamFormat(new gpu::Stream::Format()); // 1 for everyone
|
static gpu::Stream::FormatPointer streamFormat;
|
||||||
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
static gpu::Element positionElement, colorElement;
|
||||||
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA));
|
if (!streamFormat) {
|
||||||
|
streamFormat.reset(new gpu::Stream::Format()); // 1 for everyone
|
||||||
gpu::BufferView verticesView(verticesBuffer, streamFormat->getAttributes().at(gpu::Stream::POSITION)._element);
|
streamFormat->setAttribute(gpu::Stream::POSITION, VERTICES_SLOT, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||||
gpu::BufferView colorView(colorBuffer, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
|
streamFormat->setAttribute(gpu::Stream::COLOR, COLOR_SLOT, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA));
|
||||||
|
positionElement = streamFormat->getAttributes().at(gpu::Stream::POSITION)._element;
|
||||||
|
colorElement = streamFormat->getAttributes().at(gpu::Stream::COLOR)._element;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::BufferView verticesView(verticesBuffer, positionElement);
|
||||||
|
gpu::BufferView colorView(colorBuffer, colorElement);
|
||||||
|
|
||||||
batch.setInputFormat(streamFormat);
|
batch.setInputFormat(streamFormat);
|
||||||
batch.setInputBuffer(VERTICES_SLOT, verticesView);
|
batch.setInputBuffer(VERTICES_SLOT, verticesView);
|
||||||
|
|
Loading…
Reference in a new issue