mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 16:41:02 +02:00
Merge branch 'team-teaching' of https://github.com/highfidelity/hifi into team-teaching-scene-api
This commit is contained in:
commit
25823bedd1
147 changed files with 1651 additions and 1069 deletions
|
@ -325,8 +325,7 @@ void OctreeQueryNode::updateLastKnownViewFrustum() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// save that we know the view has been sent.
|
// save that we know the view has been sent.
|
||||||
quint64 now = usecTimestampNow();
|
setLastTimeBagEmpty();
|
||||||
setLastTimeBagEmpty(now); // is this what we want? poor names
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
bool moveShouldDump() const;
|
bool moveShouldDump() const;
|
||||||
|
|
||||||
quint64 getLastTimeBagEmpty() const { return _lastTimeBagEmpty; }
|
quint64 getLastTimeBagEmpty() const { return _lastTimeBagEmpty; }
|
||||||
void setLastTimeBagEmpty(quint64 lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; }
|
void setLastTimeBagEmpty() { _lastTimeBagEmpty = _sceneSendStartTime; }
|
||||||
|
|
||||||
bool getCurrentPacketIsColor() const { return _currentPacketIsColor; }
|
bool getCurrentPacketIsColor() const { return _currentPacketIsColor; }
|
||||||
bool getCurrentPacketIsCompressed() const { return _currentPacketIsCompressed; }
|
bool getCurrentPacketIsCompressed() const { return _currentPacketIsCompressed; }
|
||||||
|
@ -98,6 +98,8 @@ public:
|
||||||
void setLastRootTimestamp(quint64 timestamp) { _lastRootTimestamp = timestamp; }
|
void setLastRootTimestamp(quint64 timestamp) { _lastRootTimestamp = timestamp; }
|
||||||
unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; }
|
unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; }
|
||||||
int getDuplicatePacketCount() const { return _duplicatePacketCount; }
|
int getDuplicatePacketCount() const { return _duplicatePacketCount; }
|
||||||
|
|
||||||
|
void sceneStart(quint64 sceneSendStartTime) { _sceneSendStartTime = sceneSendStartTime; }
|
||||||
|
|
||||||
void nodeKilled();
|
void nodeKilled();
|
||||||
void forceNodeShutdown();
|
void forceNodeShutdown();
|
||||||
|
@ -158,6 +160,8 @@ private:
|
||||||
|
|
||||||
SentPacketHistory _sentPacketHistory;
|
SentPacketHistory _sentPacketHistory;
|
||||||
QQueue<OCTREE_PACKET_SEQUENCE> _nackedSequenceNumbers;
|
QQueue<OCTREE_PACKET_SEQUENCE> _nackedSequenceNumbers;
|
||||||
|
|
||||||
|
quint64 _sceneSendStartTime = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_OctreeQueryNode_h
|
#endif // hifi_OctreeQueryNode_h
|
||||||
|
|
|
@ -343,8 +343,7 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
|
||||||
|
|
||||||
if (!viewFrustumChanged && !nodeData->getWantDelta()) {
|
if (!viewFrustumChanged && !nodeData->getWantDelta()) {
|
||||||
// only set our last sent time if we weren't resetting due to frustum change
|
// only set our last sent time if we weren't resetting due to frustum change
|
||||||
quint64 now = usecTimestampNow();
|
nodeData->setLastTimeBagEmpty();
|
||||||
nodeData->setLastTimeBagEmpty(now);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// track completed scenes and send out the stats packet accordingly
|
// track completed scenes and send out the stats packet accordingly
|
||||||
|
@ -368,9 +367,11 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
|
||||||
|
|
||||||
// TODO: add these to stats page
|
// TODO: add these to stats page
|
||||||
//::startSceneSleepTime = _usleepTime;
|
//::startSceneSleepTime = _usleepTime;
|
||||||
|
|
||||||
|
nodeData->sceneStart(usecTimestampNow() - CHANGE_FUDGE);
|
||||||
// start tracking our stats
|
// start tracking our stats
|
||||||
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, _myServer->getOctree()->getRoot(), _myServer->getJurisdiction());
|
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged,
|
||||||
|
_myServer->getOctree()->getRoot(), _myServer->getJurisdiction());
|
||||||
|
|
||||||
// This is the start of "resending" the scene.
|
// This is the start of "resending" the scene.
|
||||||
bool dontRestartSceneOnMove = false; // this is experimental
|
bool dontRestartSceneOnMove = false; // this is experimental
|
||||||
|
@ -561,6 +562,13 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (somethingToSend) {
|
||||||
|
qDebug() << "Hit PPS Limit, packetsSentThisInterval =" << packetsSentThisInterval
|
||||||
|
<< " maxPacketsPerInterval = " << maxPacketsPerInterval
|
||||||
|
<< " clientMaxPacketsPerInterval = " << clientMaxPacketsPerInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Here's where we can/should allow the server to send other data...
|
// Here's where we can/should allow the server to send other data...
|
||||||
// send the environment packet
|
// send the environment packet
|
||||||
// TODO: should we turn this into a while loop to better handle sending multiple special packets
|
// TODO: should we turn this into a while loop to better handle sending multiple special packets
|
||||||
|
|
|
@ -15,7 +15,6 @@ Script.load("controllers/hydra/hydraMove.js");
|
||||||
Script.load("inspect.js");
|
Script.load("inspect.js");
|
||||||
Script.load("lobby.js");
|
Script.load("lobby.js");
|
||||||
Script.load("notifications.js");
|
Script.load("notifications.js");
|
||||||
Script.load("look.js");
|
|
||||||
Script.load("users.js");
|
Script.load("users.js");
|
||||||
Script.load("grab.js");
|
Script.load("grab.js");
|
||||||
Script.load("pointer.js");
|
Script.load("pointer.js");
|
||||||
|
|
|
@ -287,6 +287,18 @@
|
||||||
allSections.push(elWebSections);
|
allSections.push(elWebSections);
|
||||||
var elWebSourceURL = document.getElementById("property-web-source-url");
|
var elWebSourceURL = document.getElementById("property-web-source-url");
|
||||||
|
|
||||||
|
var elParticleSections = document.querySelectorAll(".particle-section");
|
||||||
|
allSections.push(elParticleSections);
|
||||||
|
var elParticleMaxParticles = document.getElementById("property-particle-maxparticles");
|
||||||
|
var elParticleLifeSpan = document.getElementById("property-particle-lifespan");
|
||||||
|
var elParticleEmitRate = document.getElementById("property-particle-emit-rate");
|
||||||
|
var elParticleEmitDirectionX = document.getElementById("property-particle-emit-direction-x");
|
||||||
|
var elParticleEmitDirectionY = document.getElementById("property-particle-emit-direction-y");
|
||||||
|
var elParticleEmitDirectionZ = document.getElementById("property-particle-emit-direction-z");
|
||||||
|
var elParticleEmitStrength = document.getElementById("property-particle-emit-strength");
|
||||||
|
var elParticleLocalGravity = document.getElementById("property-particle-localgravity");
|
||||||
|
var elParticleRadius = document.getElementById("property-particle-radius");
|
||||||
|
|
||||||
var elTextSections = document.querySelectorAll(".text-section");
|
var elTextSections = document.querySelectorAll(".text-section");
|
||||||
allSections.push(elTextSections);
|
allSections.push(elTextSections);
|
||||||
var elTextText = document.getElementById("property-text-text");
|
var elTextText = document.getElementById("property-text-text");
|
||||||
|
@ -455,7 +467,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.type == "Box" || properties.type == "Sphere") {
|
if (properties.type == "Box" || properties.type == "Sphere" || properties.type == "ParticleEffect") {
|
||||||
elColorSection.style.display = 'block';
|
elColorSection.style.display = 'block';
|
||||||
elColorRed.value = properties.color.red;
|
elColorRed.value = properties.color.red;
|
||||||
elColorGreen.value = properties.color.green;
|
elColorGreen.value = properties.color.green;
|
||||||
|
@ -465,7 +477,7 @@
|
||||||
elColorSection.style.display = 'none';
|
elColorSection.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.type == "Model") {
|
if (properties.type == "Model" || properties.type == "ParticleEffect") {
|
||||||
for (var i = 0; i < elModelSections.length; i++) {
|
for (var i = 0; i < elModelSections.length; i++) {
|
||||||
elModelSections[i].style.display = 'block';
|
elModelSections[i].style.display = 'block';
|
||||||
}
|
}
|
||||||
|
@ -479,7 +491,7 @@
|
||||||
elModelAnimationFrame.value = properties.animationFrameIndex;
|
elModelAnimationFrame.value = properties.animationFrameIndex;
|
||||||
elModelAnimationSettings.value = properties.animationSettings;
|
elModelAnimationSettings.value = properties.animationSettings;
|
||||||
elModelTextures.value = properties.textures;
|
elModelTextures.value = properties.textures;
|
||||||
elModelOriginalTextures.value = properties.originalTextures;
|
elModelOriginalTextures.value = properties.originalTextures;
|
||||||
} else if (properties.type == "Web") {
|
} else if (properties.type == "Web") {
|
||||||
for (var i = 0; i < elWebSections.length; i++) {
|
for (var i = 0; i < elWebSections.length; i++) {
|
||||||
elWebSections[i].style.display = 'block';
|
elWebSections[i].style.display = 'block';
|
||||||
|
@ -562,6 +574,20 @@
|
||||||
|
|
||||||
showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox');
|
showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox');
|
||||||
showElements(document.getElementsByClassName('atmosphere-section'), elZoneBackgroundMode.value == 'atmosphere');
|
showElements(document.getElementsByClassName('atmosphere-section'), elZoneBackgroundMode.value == 'atmosphere');
|
||||||
|
} else if (properties.type == "ParticleEffect") {
|
||||||
|
for (var i = 0; i < elParticleSections.length; i++) {
|
||||||
|
elParticleSections[i].style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
elParticleMaxParticles.value = properties.maxParticles;
|
||||||
|
elParticleLifeSpan.value = properties.lifespan.toFixed(2);
|
||||||
|
elParticleEmitRate.value = properties.emitRate.toFixed(1);
|
||||||
|
elParticleEmitDirectionX.value = properties.emitDirection.x.toFixed(2);
|
||||||
|
elParticleEmitDirectionY.value = properties.emitDirection.y.toFixed(2);
|
||||||
|
elParticleEmitDirectionZ.value = properties.emitDirection.z.toFixed(2);
|
||||||
|
elParticleEmitStrength.value = properties.emitStrength.toFixed(2);
|
||||||
|
elParticleLocalGravity.value = properties.localGravity.toFixed(2);
|
||||||
|
elParticleRadius.value = properties.particleRadius.toFixed(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
|
@ -678,6 +704,18 @@
|
||||||
elLightCutoff.addEventListener('change', createEmitNumberPropertyUpdateFunction('cutoff'));
|
elLightCutoff.addEventListener('change', createEmitNumberPropertyUpdateFunction('cutoff'));
|
||||||
|
|
||||||
elWebSourceURL.addEventListener('change', createEmitTextPropertyUpdateFunction('sourceUrl'));
|
elWebSourceURL.addEventListener('change', createEmitTextPropertyUpdateFunction('sourceUrl'));
|
||||||
|
|
||||||
|
elParticleMaxParticles.addEventListener('change', createEmitNumberPropertyUpdateFunction('maxParticles'));
|
||||||
|
elParticleLifeSpan.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifespan'));
|
||||||
|
elParticleEmitRate.addEventListener('change', createEmitNumberPropertyUpdateFunction('emitRate'));
|
||||||
|
var particleEmitDirectionChangeFunction = createEmitVec3PropertyUpdateFunctionWithMultiplier(
|
||||||
|
'emitDirection', elParticleEmitDirectionX, elParticleEmitDirectionY, elParticleEmitDirectionZ, DEGREES_TO_RADIANS);
|
||||||
|
elParticleEmitDirectionX.addEventListener('change', particleEmitDirectionChangeFunction);
|
||||||
|
elParticleEmitDirectionY.addEventListener('change', particleEmitDirectionChangeFunction);
|
||||||
|
elParticleEmitDirectionZ.addEventListener('change', particleEmitDirectionChangeFunction);
|
||||||
|
elParticleEmitStrength.addEventListener('change', createEmitNumberPropertyUpdateFunction('emitStrength'));
|
||||||
|
elParticleLocalGravity.addEventListener('change', createEmitNumberPropertyUpdateFunction('localGravity'));
|
||||||
|
elParticleRadius.addEventListener('change', createEmitNumberPropertyUpdateFunction('particleRadius'));
|
||||||
|
|
||||||
elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL'));
|
elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL'));
|
||||||
elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType'));
|
elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType'));
|
||||||
|
@ -1069,7 +1107,52 @@
|
||||||
<input type="text" id="property-web-source-url" class="url"></input>
|
<input type="text" id="property-web-source-url" class="url"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="particle-section property">
|
||||||
|
<div class="label">Max Particles</div>
|
||||||
|
<div class="value">
|
||||||
|
<input type='number' id="property-particle-maxparticles" min="0" max="2048" step="1"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="particle-section property">
|
||||||
|
<div class="label">Particle Life Span</div>
|
||||||
|
<div class="value">
|
||||||
|
<input type='number' id="property-particle-lifespan" min="0" step="0.1"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="particle-section property">
|
||||||
|
<div class="label">Particle Emission Rate</div>
|
||||||
|
<div class="value">
|
||||||
|
<input type='number' id="property-particle-emit-rate" min="0" step="0.5"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="particle-section property">
|
||||||
|
<div class="label">Particle Emission Direction</div>
|
||||||
|
<div class="value">
|
||||||
|
<div class="input-area">X <input class="coord" type='number' id="property-particle-emit-direction-x"></input></div>
|
||||||
|
<div class="input-area">Y <input class="coord" type='number' id="property-particle-emit-direction-y"></input></div>
|
||||||
|
<div class="input-area">Z <input class="coord" type='number' id="property-particle-emit-direction-z"></input></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="particle-section property">
|
||||||
|
<div class="label">Particle Emission Strength</div>
|
||||||
|
<div class="value">
|
||||||
|
<input type='number' id="property-particle-emit-strength" min="0" step="0.1"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="particle-section property">
|
||||||
|
<div class="label">Particle Local Gravity</div>
|
||||||
|
<div class="value">
|
||||||
|
<input class="coord" type='number' id="property-particle-localgravity" step="0.05"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="particle-section property">
|
||||||
|
<div class="label">Particle Radius</div>
|
||||||
|
<div class="value">
|
||||||
|
<input class="coord" type='number' id="property-particle-radius" min="0" step="0.005"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="model-section property">
|
<div class="model-section property">
|
||||||
<div class="label">Model URL</div>
|
<div class="label">Model URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
|
|
183
examples/look.js
183
examples/look.js
|
@ -1,183 +0,0 @@
|
||||||
//
|
|
||||||
// look.js
|
|
||||||
// examples
|
|
||||||
//
|
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// This is an example script that demonstrates use of the Controller class
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
var wantDebugging = false;
|
|
||||||
|
|
||||||
|
|
||||||
// Configuration
|
|
||||||
var TOUCH_YAW_SCALE = -0.25;
|
|
||||||
var TOUCH_PITCH_SCALE = -12.5;
|
|
||||||
var FIXED_TOUCH_TIMESTEP = 0.016;
|
|
||||||
|
|
||||||
var MOUSE_YAW_SCALE = -0.25;
|
|
||||||
var MOUSE_PITCH_SCALE = -12.5;
|
|
||||||
var FIXED_MOUSE_TIMESTEP = 0.016;
|
|
||||||
|
|
||||||
// Mouse Data
|
|
||||||
var alwaysLook = false; // if you want the mouse look to happen only when you click, change this to false
|
|
||||||
var isMouseDown = false;
|
|
||||||
var lastTouchX = 0;
|
|
||||||
var lastTouchY = 0;
|
|
||||||
var yawFromTouch = 0;
|
|
||||||
var pitchFromTouch = 0;
|
|
||||||
|
|
||||||
// Touch Data
|
|
||||||
var TIME_BEFORE_GENERATED_END_TOUCH_EVENT = 50; // ms
|
|
||||||
var startedTouching = false;
|
|
||||||
var lastTouchEvent = 0;
|
|
||||||
var lastMouseX = 0;
|
|
||||||
var lastMouseY = 0;
|
|
||||||
var yawFromMouse = 0;
|
|
||||||
var pitchFromMouse = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Mouse Events
|
|
||||||
function mousePressEvent(event) {
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("mousePressEvent event.x,y=" + event.x + ", " + event.y);
|
|
||||||
}
|
|
||||||
if (event.isRightButton) {
|
|
||||||
isMouseDown = true;
|
|
||||||
lastMouseX = event.x;
|
|
||||||
lastMouseY = event.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function mouseReleaseEvent(event) {
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("mouseReleaseEvent event.x,y=" + event.x + ", " + event.y);
|
|
||||||
}
|
|
||||||
isMouseDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mouseMoveEvent(event) {
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("mouseMoveEvent event.x,y=" + event.x + ", " + event.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alwaysLook || isMouseDown) {
|
|
||||||
yawFromMouse += ((event.x - lastMouseX) * MOUSE_YAW_SCALE * FIXED_MOUSE_TIMESTEP);
|
|
||||||
pitchFromMouse += ((event.y - lastMouseY) * MOUSE_PITCH_SCALE * FIXED_MOUSE_TIMESTEP);
|
|
||||||
lastMouseX = event.x;
|
|
||||||
lastMouseY = event.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Touch Events
|
|
||||||
function touchBeginEvent(event) {
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("touchBeginEvent event.x,y=" + event.x + ", " + event.y);
|
|
||||||
}
|
|
||||||
lastTouchX = event.x;
|
|
||||||
lastTouchY = event.y;
|
|
||||||
yawFromTouch = 0;
|
|
||||||
pitchFromTouch = 0;
|
|
||||||
startedTouching = true;
|
|
||||||
var d = new Date();
|
|
||||||
lastTouchEvent = d.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
function touchEndEvent(event) {
|
|
||||||
if (wantDebugging) {
|
|
||||||
if (event) {
|
|
||||||
print("touchEndEvent event.x,y=" + event.x + ", " + event.y);
|
|
||||||
} else {
|
|
||||||
print("touchEndEvent generated");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startedTouching = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function touchUpdateEvent(event) {
|
|
||||||
// print("TOUCH UPDATE");
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("touchUpdateEvent event.x,y=" + event.x + ", " + event.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!startedTouching) {
|
|
||||||
// handle Qt 5.4.x bug where we get touch update without a touch begin event
|
|
||||||
touchBeginEvent(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
yawFromTouch += ((event.x - lastTouchX) * TOUCH_YAW_SCALE * FIXED_TOUCH_TIMESTEP);
|
|
||||||
pitchFromTouch += ((event.y - lastTouchY) * TOUCH_PITCH_SCALE * FIXED_TOUCH_TIMESTEP);
|
|
||||||
lastTouchX = event.x;
|
|
||||||
lastTouchY = event.y;
|
|
||||||
var d = new Date();
|
|
||||||
lastTouchEvent = d.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function update(deltaTime) {
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("update()...");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startedTouching) {
|
|
||||||
var d = new Date();
|
|
||||||
var sinceLastTouch = d.getTime() - lastTouchEvent;
|
|
||||||
if (sinceLastTouch > TIME_BEFORE_GENERATED_END_TOUCH_EVENT) {
|
|
||||||
touchEndEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yawFromTouch != 0 || yawFromMouse != 0) {
|
|
||||||
var newOrientation = Quat.multiply(MyAvatar.orientation, Quat.fromPitchYawRollRadians(0, yawFromTouch + yawFromMouse, 0));
|
|
||||||
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("changing orientation"
|
|
||||||
+ " [old]MyAvatar.orientation="+MyAvatar.orientation.x + "," + MyAvatar.orientation.y + ","
|
|
||||||
+ MyAvatar.orientation.z + "," + MyAvatar.orientation.w
|
|
||||||
+ " newOrientation="+newOrientation.x + "," + newOrientation.y + "," + newOrientation.z + "," + newOrientation.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
MyAvatar.orientation = newOrientation;
|
|
||||||
yawFromTouch = 0;
|
|
||||||
yawFromMouse = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pitchFromTouch != 0 || pitchFromMouse != 0) {
|
|
||||||
var newPitch = MyAvatar.headPitch + pitchFromTouch + pitchFromMouse;
|
|
||||||
|
|
||||||
if (wantDebugging) {
|
|
||||||
print("changing pitch [old]MyAvatar.headPitch="+MyAvatar.headPitch+ " newPitch="+newPitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
MyAvatar.headPitch = newPitch;
|
|
||||||
pitchFromTouch = 0;
|
|
||||||
pitchFromMouse = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Map the mouse events to our functions
|
|
||||||
Controller.mousePressEvent.connect(mousePressEvent);
|
|
||||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
|
||||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
|
||||||
|
|
||||||
// Map the mouse events to our functions
|
|
||||||
Controller.touchBeginEvent.connect(touchBeginEvent);
|
|
||||||
Controller.touchUpdateEvent.connect(touchUpdateEvent);
|
|
||||||
Controller.touchEndEvent.connect(touchEndEvent);
|
|
||||||
|
|
||||||
// disable the standard application for mouse events
|
|
||||||
Controller.captureTouchEvents();
|
|
||||||
|
|
||||||
function scriptEnding() {
|
|
||||||
// re-enabled the standard application for mouse events
|
|
||||||
Controller.releaseTouchEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
// would be nice to change to update
|
|
||||||
Script.update.connect(update);
|
|
||||||
Script.scriptEnding.connect(scriptEnding);
|
|
|
@ -116,6 +116,7 @@
|
||||||
#include "devices/TV3DManager.h"
|
#include "devices/TV3DManager.h"
|
||||||
|
|
||||||
#include "gpu/Batch.h"
|
#include "gpu/Batch.h"
|
||||||
|
#include "gpu/Context.h"
|
||||||
#include "gpu/GLBackend.h"
|
#include "gpu/GLBackend.h"
|
||||||
|
|
||||||
#include "scripting/AccountScriptingInterface.h"
|
#include "scripting/AccountScriptingInterface.h"
|
||||||
|
@ -142,6 +143,7 @@
|
||||||
#include "ui/Stats.h"
|
#include "ui/Stats.h"
|
||||||
#include "ui/AddressBarDialog.h"
|
#include "ui/AddressBarDialog.h"
|
||||||
|
|
||||||
|
|
||||||
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -368,7 +370,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
_bookmarks = new Bookmarks(); // Before setting up the menu
|
_bookmarks = new Bookmarks(); // Before setting up the menu
|
||||||
|
|
||||||
_runningScriptsWidget = new RunningScriptsWidget(_window);
|
_runningScriptsWidget = new RunningScriptsWidget(_window);
|
||||||
|
|
||||||
|
|
||||||
|
_renderEngine->buildStandardTaskPipeline();
|
||||||
|
_renderEngine->registerScene(_main3DScene);
|
||||||
|
|
||||||
// start the nodeThread so its event loop is running
|
// start the nodeThread so its event loop is running
|
||||||
QThread* nodeThread = new QThread(this);
|
QThread* nodeThread = new QThread(this);
|
||||||
nodeThread->setObjectName("Datagram Processor Thread");
|
nodeThread->setObjectName("Datagram Processor Thread");
|
||||||
|
@ -687,6 +693,10 @@ Application::~Application() {
|
||||||
// stop the glWidget frame timer so it doesn't call paintGL
|
// stop the glWidget frame timer so it doesn't call paintGL
|
||||||
_glWidget->stopFrameTimer();
|
_glWidget->stopFrameTimer();
|
||||||
|
|
||||||
|
// remove avatars from physics engine
|
||||||
|
DependencyManager::get<AvatarManager>()->clearOtherAvatars();
|
||||||
|
_physicsEngine.deleteObjects(DependencyManager::get<AvatarManager>()->getObjectsToDelete());
|
||||||
|
|
||||||
DependencyManager::destroy<OffscreenUi>();
|
DependencyManager::destroy<OffscreenUi>();
|
||||||
DependencyManager::destroy<AvatarManager>();
|
DependencyManager::destroy<AvatarManager>();
|
||||||
DependencyManager::destroy<AnimationCache>();
|
DependencyManager::destroy<AnimationCache>();
|
||||||
|
@ -830,6 +840,13 @@ void Application::initializeUi() {
|
||||||
void Application::paintGL() {
|
void Application::paintGL() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
_glWidget->makeCurrent();
|
_glWidget->makeCurrent();
|
||||||
|
|
||||||
|
auto lodManager = DependencyManager::get<LODManager>();
|
||||||
|
gpu::Context context;
|
||||||
|
RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
|
||||||
|
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||||
|
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||||
|
|
||||||
PerformanceTimer perfTimer("paintGL");
|
PerformanceTimer perfTimer("paintGL");
|
||||||
//Need accurate frame timing for the oculus rift
|
//Need accurate frame timing for the oculus rift
|
||||||
if (OculusManager::isConnected()) {
|
if (OculusManager::isConnected()) {
|
||||||
|
@ -843,7 +860,7 @@ void Application::paintGL() {
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("renderOverlay");
|
PerformanceTimer perfTimer("renderOverlay");
|
||||||
_applicationOverlay.renderOverlay();
|
_applicationOverlay.renderOverlay(&renderArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_LINE_SMOOTH);
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
@ -892,22 +909,25 @@ void Application::paintGL() {
|
||||||
loadViewFrustum(_myCamera, _viewFrustum);
|
loadViewFrustum(_myCamera, _viewFrustum);
|
||||||
|
|
||||||
if (getShadowsEnabled()) {
|
if (getShadowsEnabled()) {
|
||||||
updateShadowMap();
|
renderArgs._renderMode = RenderArgs::SHADOW_RENDER_MODE;
|
||||||
|
updateShadowMap(&renderArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
||||||
|
|
||||||
if (OculusManager::isConnected()) {
|
if (OculusManager::isConnected()) {
|
||||||
//When in mirror mode, use camera rotation. Otherwise, use body rotation
|
//When in mirror mode, use camera rotation. Otherwise, use body rotation
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
OculusManager::display(_glWidget, _myCamera.getRotation(), _myCamera.getPosition(), _myCamera);
|
OculusManager::display(_glWidget, &renderArgs, _myCamera.getRotation(), _myCamera.getPosition(), _myCamera);
|
||||||
} else {
|
} else {
|
||||||
OculusManager::display(_glWidget, _myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), _myCamera);
|
OculusManager::display(_glWidget, &renderArgs, _myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), _myCamera);
|
||||||
}
|
}
|
||||||
} else if (TV3DManager::isConnected()) {
|
} else if (TV3DManager::isConnected()) {
|
||||||
|
|
||||||
TV3DManager::display(_myCamera);
|
TV3DManager::display(&renderArgs, _myCamera);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<GlowEffect>()->prepare();
|
DependencyManager::get<GlowEffect>()->prepare(&renderArgs);
|
||||||
|
|
||||||
// Viewport is assigned to the size of the framebuffer
|
// Viewport is assigned to the size of the framebuffer
|
||||||
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
|
QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
|
||||||
|
@ -916,16 +936,16 @@ void Application::paintGL() {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
displaySide(_myCamera);
|
displaySide(&renderArgs, _myCamera);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||||
_rearMirrorTools->render(true, _glWidget->mapFromGlobal(QCursor::pos()));
|
_rearMirrorTools->render(&renderArgs, true, _glWidget->mapFromGlobal(QCursor::pos()));
|
||||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
} else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||||
renderRearViewMirror(_mirrorViewRect);
|
renderRearViewMirror(&renderArgs, _mirrorViewRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto finalFbo = DependencyManager::get<GlowEffect>()->render();
|
auto finalFbo = DependencyManager::get<GlowEffect>()->render(&renderArgs);
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
|
||||||
|
@ -1970,7 +1990,7 @@ void Application::toggleFaceTrackerMute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs) {
|
bool Application::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs) {
|
||||||
QVector<EntityItem*> entities;
|
QVector<EntityItemPointer> entities;
|
||||||
|
|
||||||
auto entityTree = _entities.getTree();
|
auto entityTree = _entities.getTree();
|
||||||
EntityTree exportTree;
|
EntityTree exportTree;
|
||||||
|
@ -2011,7 +2031,7 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) {
|
bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) {
|
||||||
QVector<EntityItem*> entities;
|
QVector<EntityItemPointer> entities;
|
||||||
_entities.getTree()->findEntities(AACube(glm::vec3(x, y, z), scale), entities);
|
_entities.getTree()->findEntities(AACube(glm::vec3(x, y, z), scale), entities);
|
||||||
|
|
||||||
if (entities.size() > 0) {
|
if (entities.size() > 0) {
|
||||||
|
@ -2150,7 +2170,7 @@ void Application::init() {
|
||||||
_physicsEngine.init();
|
_physicsEngine.init();
|
||||||
|
|
||||||
EntityTree* tree = _entities.getTree();
|
EntityTree* tree = _entities.getTree();
|
||||||
_entitySimulation.init(tree, &_physicsEngine, &_shapeManager, &_entityEditSender);
|
_entitySimulation.init(tree, &_physicsEngine, &_entityEditSender);
|
||||||
tree->setSimulation(&_entitySimulation);
|
tree->setSimulation(&_entitySimulation);
|
||||||
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
@ -2470,12 +2490,21 @@ void Application::update(float deltaTime) {
|
||||||
_physicsEngine.changeObjects(_entitySimulation.getObjectsToChange());
|
_physicsEngine.changeObjects(_entitySimulation.getObjectsToChange());
|
||||||
_entitySimulation.unlock();
|
_entitySimulation.unlock();
|
||||||
|
|
||||||
|
AvatarManager* avatarManager = DependencyManager::get<AvatarManager>().data();
|
||||||
|
_physicsEngine.deleteObjects(avatarManager->getObjectsToDelete());
|
||||||
|
_physicsEngine.addObjects(avatarManager->getObjectsToAdd());
|
||||||
|
_physicsEngine.changeObjects(avatarManager->getObjectsToChange());
|
||||||
|
|
||||||
_physicsEngine.stepSimulation();
|
_physicsEngine.stepSimulation();
|
||||||
|
|
||||||
if (_physicsEngine.hasOutgoingChanges()) {
|
if (_physicsEngine.hasOutgoingChanges()) {
|
||||||
_entitySimulation.lock();
|
_entitySimulation.lock();
|
||||||
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID());
|
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID());
|
||||||
_entitySimulation.unlock();
|
_entitySimulation.unlock();
|
||||||
|
|
||||||
|
avatarManager->handleOutgoingChanges(_physicsEngine.getOutgoingChanges());
|
||||||
|
avatarManager->handleCollisionEvents(_physicsEngine.getCollisionEvents());
|
||||||
|
|
||||||
_physicsEngine.dumpStatsIfNecessary();
|
_physicsEngine.dumpStatsIfNecessary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2879,7 +2908,7 @@ glm::vec3 Application::getSunDirection() {
|
||||||
// FIXME, preprocessor guard this check to occur only in DEBUG builds
|
// FIXME, preprocessor guard this check to occur only in DEBUG builds
|
||||||
static QThread * activeRenderingThread = nullptr;
|
static QThread * activeRenderingThread = nullptr;
|
||||||
|
|
||||||
void Application::updateShadowMap() {
|
void Application::updateShadowMap(RenderArgs* renderArgs) {
|
||||||
activeRenderingThread = QThread::currentThread();
|
activeRenderingThread = QThread::currentThread();
|
||||||
|
|
||||||
PerformanceTimer perfTimer("shadowMap");
|
PerformanceTimer perfTimer("shadowMap");
|
||||||
|
@ -3000,23 +3029,23 @@ void Application::updateShadowMap() {
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("avatarManager");
|
PerformanceTimer perfTimer("avatarManager");
|
||||||
DependencyManager::get<AvatarManager>()->renderAvatars(RenderArgs::SHADOW_RENDER_MODE);
|
DependencyManager::get<AvatarManager>()->renderAvatars(renderArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("entities");
|
PerformanceTimer perfTimer("entities");
|
||||||
_entities.render(RenderArgs::SHADOW_RENDER_MODE);
|
_entities.render(renderArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render JS/scriptable overlays
|
// render JS/scriptable overlays
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("3dOverlays");
|
PerformanceTimer perfTimer("3dOverlays");
|
||||||
_overlays.renderWorld(false, RenderArgs::SHADOW_RENDER_MODE);
|
_overlays.renderWorld(renderArgs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("3dOverlaysFront");
|
PerformanceTimer perfTimer("3dOverlaysFront");
|
||||||
_overlays.renderWorld(true, RenderArgs::SHADOW_RENDER_MODE);
|
_overlays.renderWorld(renderArgs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
@ -3084,15 +3113,16 @@ PickRay Application::computePickRay(float x, float y) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage Application::renderAvatarBillboard() {
|
QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
|
||||||
auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
|
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
|
||||||
|
|
||||||
// the "glow" here causes an alpha of one
|
// the "glow" here causes an alpha of one
|
||||||
Glower glower;
|
Glower glower(renderArgs);
|
||||||
|
|
||||||
const int BILLBOARD_SIZE = 64;
|
const int BILLBOARD_SIZE = 64;
|
||||||
renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE,
|
// TODO: Pass a RenderArgs to renderAvatarBillboard
|
||||||
|
renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE,
|
||||||
BILLBOARD_SIZE, BILLBOARD_SIZE),
|
BILLBOARD_SIZE, BILLBOARD_SIZE),
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
@ -3144,7 +3174,26 @@ const ViewFrustum* Application::getDisplayViewFrustum() const {
|
||||||
return &_displayViewFrustum;
|
return &_displayViewFrustum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) {
|
class MyFirstStuff {
|
||||||
|
public:
|
||||||
|
typedef render::Payload<MyFirstStuff> Payload;
|
||||||
|
typedef std::shared_ptr<render::Item::PayloadInterface> PayloadPointer;
|
||||||
|
typedef Payload::DataPointer Pointer;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// For Ubuntu, the compiler want's the Payload's functions to be specialized in the "render" namespace explicitely...
|
||||||
|
namespace render {
|
||||||
|
template <> const ItemKey payloadGetKey(const MyFirstStuff::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); }
|
||||||
|
template <> const Item::Bound payloadGetBound(const MyFirstStuff::Pointer& stuff) { return Item::Bound(); }
|
||||||
|
template <> void payloadRender(const MyFirstStuff::Pointer& stuff, RenderArgs* args) {
|
||||||
|
if (args) {
|
||||||
|
args->_elementsTouched ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) {
|
||||||
activeRenderingThread = QThread::currentThread();
|
activeRenderingThread = QThread::currentThread();
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
PerformanceTimer perfTimer("display");
|
PerformanceTimer perfTimer("display");
|
||||||
|
@ -3183,7 +3232,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
if (renderSide != RenderArgs::MONO) {
|
if (renderArgs->_renderSide != RenderArgs::MONO) {
|
||||||
glm::mat4 invView = glm::inverse(_untranslatedViewMatrix);
|
glm::mat4 invView = glm::inverse(_untranslatedViewMatrix);
|
||||||
|
|
||||||
viewTransform.evalFromRawMatrix(invView);
|
viewTransform.evalFromRawMatrix(invView);
|
||||||
|
@ -3314,7 +3363,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
// render JS/scriptable overlays
|
// render JS/scriptable overlays
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("3dOverlays");
|
PerformanceTimer perfTimer("3dOverlays");
|
||||||
_overlays.renderWorld(false);
|
_overlays.renderWorld(renderArgs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render models...
|
// render models...
|
||||||
|
@ -3336,7 +3385,9 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||||
}
|
}
|
||||||
_entities.render(renderMode, renderSide, renderDebugFlags);
|
renderArgs->_renderMode = renderMode;
|
||||||
|
renderArgs->_debugFlags = renderDebugFlags;
|
||||||
|
_entities.render(renderArgs);
|
||||||
|
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||||
// Restaure polygon mode
|
// Restaure polygon mode
|
||||||
|
@ -3357,10 +3408,30 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("avatars");
|
PerformanceTimer perfTimer("avatars");
|
||||||
DependencyManager::get<AvatarManager>()->renderAvatars(mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE,
|
renderArgs->_renderMode = mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE;
|
||||||
false, selfAvatarOnly);
|
DependencyManager::get<AvatarManager>()->renderAvatars(renderArgs, false, selfAvatarOnly);
|
||||||
|
renderArgs->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static render::ItemID myFirstRenderItem = 0;
|
||||||
|
|
||||||
|
if (myFirstRenderItem == 0) {
|
||||||
|
auto myVeryFirstStuff = MyFirstStuff::Pointer(new MyFirstStuff());
|
||||||
|
auto myVeryFirstPayload = new MyFirstStuff::Payload(myVeryFirstStuff);
|
||||||
|
auto myFirstPayload = MyFirstStuff::PayloadPointer(myVeryFirstPayload);
|
||||||
|
myFirstRenderItem = _main3DScene->allocateID();
|
||||||
|
|
||||||
|
render::Scene::PendingChanges pendingChanges;
|
||||||
|
pendingChanges.resetItem(myFirstRenderItem, myFirstPayload);
|
||||||
|
|
||||||
|
_main3DScene->enqueuePendingChanges(pendingChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
_main3DScene->processPendingChangesQueue();
|
||||||
|
|
||||||
|
// Before the deferred pass, let's try to use the render engine
|
||||||
|
_renderEngine->run();
|
||||||
|
|
||||||
{
|
{
|
||||||
DependencyManager::get<DeferredLightingEffect>()->setAmbientLightMode(getRenderAmbientLight());
|
DependencyManager::get<DeferredLightingEffect>()->setAmbientLightMode(getRenderAmbientLight());
|
||||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||||
|
@ -3375,8 +3446,9 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("avatarsPostLighting");
|
PerformanceTimer perfTimer("avatarsPostLighting");
|
||||||
DependencyManager::get<AvatarManager>()->renderAvatars(mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE,
|
renderArgs->_renderMode = mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE;
|
||||||
true, selfAvatarOnly);
|
DependencyManager::get<AvatarManager>()->renderAvatars(renderArgs, true, selfAvatarOnly);
|
||||||
|
renderArgs->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Render the sixense lasers
|
//Render the sixense lasers
|
||||||
|
@ -3400,7 +3472,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
"Application::displaySide() ... octree fades...");
|
"Application::displaySide() ... octree fades...");
|
||||||
_octreeFadesLock.lockForWrite();
|
_octreeFadesLock.lockForWrite();
|
||||||
for(std::vector<OctreeFade>::iterator fade = _octreeFades.begin(); fade != _octreeFades.end();) {
|
for(std::vector<OctreeFade>::iterator fade = _octreeFades.begin(); fade != _octreeFades.end();) {
|
||||||
fade->render();
|
fade->render(renderArgs);
|
||||||
if(fade->isDone()) {
|
if(fade->isDone()) {
|
||||||
fade = _octreeFades.erase(fade);
|
fade = _octreeFades.erase(fade);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3425,8 +3497,8 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("3dOverlaysFront");
|
PerformanceTimer perfTimer("3dOverlaysFront");
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
Glower glower; // Sets alpha to 1.0
|
Glower glower(renderArgs); // Sets alpha to 1.0
|
||||||
_overlays.renderWorld(true);
|
_overlays.renderWorld(renderArgs, true);
|
||||||
}
|
}
|
||||||
activeRenderingThread = nullptr;
|
activeRenderingThread = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -3504,7 +3576,7 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
|
||||||
return screenPoint;
|
return screenPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) {
|
||||||
// Grab current viewport to reset it at the end
|
// Grab current viewport to reset it at the end
|
||||||
int viewport[4];
|
int viewport[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||||
|
@ -3564,11 +3636,11 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
||||||
|
|
||||||
// render rear mirror view
|
// render rear mirror view
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
displaySide(_mirrorCamera, true);
|
displaySide(renderArgs, _mirrorCamera, true);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
if (!billboard) {
|
if (!billboard) {
|
||||||
_rearMirrorTools->render(false, _glWidget->mapFromGlobal(QCursor::pos()));
|
_rearMirrorTools->render(renderArgs, false, _glWidget->mapFromGlobal(QCursor::pos()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset Viewport and projection matrix
|
// reset Viewport and projection matrix
|
||||||
|
|
|
@ -77,6 +77,7 @@
|
||||||
#include "octree/OctreePacketProcessor.h"
|
#include "octree/OctreePacketProcessor.h"
|
||||||
#include "UndoStackScriptingInterface.h"
|
#include "UndoStackScriptingInterface.h"
|
||||||
|
|
||||||
|
#include "render/Engine.h"
|
||||||
|
|
||||||
class QGLWidget;
|
class QGLWidget;
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
|
@ -268,9 +269,9 @@ public:
|
||||||
virtual void setupWorldLight();
|
virtual void setupWorldLight();
|
||||||
virtual bool shouldRenderMesh(float largestDimension, float distanceToCamera);
|
virtual bool shouldRenderMesh(float largestDimension, float distanceToCamera);
|
||||||
|
|
||||||
QImage renderAvatarBillboard();
|
QImage renderAvatarBillboard(RenderArgs* renderArgs);
|
||||||
|
|
||||||
void displaySide(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO);
|
void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false);
|
||||||
|
|
||||||
/// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as
|
/// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as
|
||||||
/// the view matrix translation.
|
/// the view matrix translation.
|
||||||
|
@ -499,8 +500,8 @@ private:
|
||||||
|
|
||||||
glm::vec3 getSunDirection();
|
glm::vec3 getSunDirection();
|
||||||
|
|
||||||
void updateShadowMap();
|
void updateShadowMap(RenderArgs* renderArgs);
|
||||||
void renderRearViewMirror(const QRect& region, bool billboard = false);
|
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false);
|
||||||
void setMenuShortcutsEnabled(bool enabled);
|
void setMenuShortcutsEnabled(bool enabled);
|
||||||
|
|
||||||
static void attachNewHeadToNode(Node *newNode);
|
static void attachNewHeadToNode(Node *newNode);
|
||||||
|
@ -670,6 +671,9 @@ private:
|
||||||
int _maxOctreePPS = DEFAULT_MAX_OCTREE_PPS;
|
int _maxOctreePPS = DEFAULT_MAX_OCTREE_PPS;
|
||||||
|
|
||||||
quint64 _lastFaceTrackerUpdate;
|
quint64 _lastFaceTrackerUpdate;
|
||||||
|
|
||||||
|
render::ScenePointer _main3DScene{ new render::Scene() };
|
||||||
|
render::EnginePointer _renderEngine{ new render::Engine() };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Application_h
|
#endif // hifi_Application_h
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
#include "AvatarManager.h"
|
#include "AvatarManager.h"
|
||||||
|
#include "AvatarMotionState.h"
|
||||||
#include "Hand.h"
|
#include "Hand.h"
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
|
@ -268,7 +269,7 @@ static TextRenderer* textRenderer(TextRendererType type) {
|
||||||
return displayNameRenderer;
|
return displayNameRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode, bool postLighting) {
|
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
|
||||||
if (_referential) {
|
if (_referential) {
|
||||||
_referential->update();
|
_referential->update();
|
||||||
}
|
}
|
||||||
|
@ -339,7 +340,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
// simple frustum check
|
// simple frustum check
|
||||||
float boundingRadius = getBillboardSize();
|
float boundingRadius = getBillboardSize();
|
||||||
ViewFrustum* frustum = nullptr;
|
ViewFrustum* frustum = nullptr;
|
||||||
if (renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
frustum = Application::getInstance()->getShadowViewFrustum();
|
frustum = Application::getInstance()->getShadowViewFrustum();
|
||||||
} else {
|
} else {
|
||||||
frustum = Application::getInstance()->getDisplayViewFrustum();
|
frustum = Application::getInstance()->getDisplayViewFrustum();
|
||||||
|
@ -365,14 +366,14 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
GLOW_FROM_AVERAGE_LOUDNESS = 0.0f;
|
GLOW_FROM_AVERAGE_LOUDNESS = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == RenderArgs::NORMAL_RENDER_MODE
|
float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderArgs->_renderMode == RenderArgs::NORMAL_RENDER_MODE
|
||||||
? 1.0f
|
? 1.0f
|
||||||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||||
|
|
||||||
// render body
|
// render body
|
||||||
renderBody(frustum, renderMode, postLighting, glowLevel);
|
renderBody(renderArgs, frustum, postLighting, glowLevel);
|
||||||
|
|
||||||
if (!postLighting && renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
if (!postLighting && renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
// add local lights
|
// add local lights
|
||||||
const float BASE_LIGHT_DISTANCE = 2.0f;
|
const float BASE_LIGHT_DISTANCE = 2.0f;
|
||||||
const float LIGHT_EXPONENT = 1.0f;
|
const float LIGHT_EXPONENT = 1.0f;
|
||||||
|
@ -396,10 +397,10 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
_skeletonModel.renderJointCollisionShapes(0.7f);
|
_skeletonModel.renderJointCollisionShapes(0.7f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderHead && shouldRenderHead(cameraPosition, renderMode)) {
|
if (renderHead && shouldRenderHead(renderArgs, cameraPosition)) {
|
||||||
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
|
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
|
||||||
}
|
}
|
||||||
if (renderBounding && shouldRenderHead(cameraPosition, renderMode)) {
|
if (renderBounding && shouldRenderHead(renderArgs, cameraPosition)) {
|
||||||
_skeletonModel.renderBoundingCollisionShapes(0.7f);
|
_skeletonModel.renderBoundingCollisionShapes(0.7f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +437,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
||||||
float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING;
|
float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING;
|
||||||
|
|
||||||
if (renderMode == RenderArgs::NORMAL_RENDER_MODE && (sphereRadius > MIN_SPHERE_SIZE) &&
|
if (renderArgs->_renderMode == RenderArgs::NORMAL_RENDER_MODE && (sphereRadius > MIN_SPHERE_SIZE) &&
|
||||||
(angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) {
|
(angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(_position.x, _position.y, _position.z);
|
glTranslatef(_position.x, _position.y, _position.z);
|
||||||
|
@ -455,8 +456,8 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
}
|
}
|
||||||
|
|
||||||
const float DISPLAYNAME_DISTANCE = 20.0f;
|
const float DISPLAYNAME_DISTANCE = 20.0f;
|
||||||
setShowDisplayName(renderMode == RenderArgs::NORMAL_RENDER_MODE && distanceToTarget < DISPLAYNAME_DISTANCE);
|
setShowDisplayName(renderArgs->_renderMode == RenderArgs::NORMAL_RENDER_MODE && distanceToTarget < DISPLAYNAME_DISTANCE);
|
||||||
if (!postLighting || renderMode != RenderArgs::NORMAL_RENDER_MODE || (isMyAvatar() &&
|
if (!postLighting || renderArgs->_renderMode != RenderArgs::NORMAL_RENDER_MODE || (isMyAvatar() &&
|
||||||
Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON)) {
|
Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -479,13 +480,12 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
|
||||||
return glm::angleAxis(angle * proportion, axis);
|
return glm::angleAxis(angle * proportion, axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode renderMode, bool postLighting, float glowLevel) {
|
void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel) {
|
||||||
Model::RenderMode modelRenderMode = renderMode;
|
|
||||||
{
|
{
|
||||||
Glower glower(glowLevel);
|
Glower glower(renderArgs, glowLevel);
|
||||||
|
|
||||||
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||||
if (postLighting || renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
if (postLighting || renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
// render the billboard until both models are loaded
|
// render the billboard until both models are loaded
|
||||||
renderBillboard();
|
renderBillboard();
|
||||||
}
|
}
|
||||||
|
@ -493,18 +493,16 @@ void Avatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode rende
|
||||||
}
|
}
|
||||||
|
|
||||||
if (postLighting) {
|
if (postLighting) {
|
||||||
getHand()->render(false, modelRenderMode);
|
getHand()->render(renderArgs, false);
|
||||||
} else {
|
} else {
|
||||||
RenderArgs args;
|
_skeletonModel.render(renderArgs, 1.0f);
|
||||||
args._viewFrustum = renderFrustum;
|
renderAttachments(renderArgs);
|
||||||
_skeletonModel.render(1.0f, modelRenderMode, &args);
|
|
||||||
renderAttachments(renderMode, &args);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getHead()->render(1.0f, renderFrustum, modelRenderMode, postLighting);
|
getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Avatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode) const {
|
bool Avatar::shouldRenderHead(const RenderArgs* renderArgs, const glm::vec3& cameraPosition) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,11 +526,11 @@ void Avatar::simulateAttachments(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::renderAttachments(RenderArgs::RenderMode renderMode, RenderArgs* args) {
|
void Avatar::renderAttachments(RenderArgs* args) {
|
||||||
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
// RenderArgs::RenderMode modelRenderMode = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||||
// RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE;
|
// RenderArgs::SHADOW_RENDER_MODE : RenderArgs::DEFAULT_RENDER_MODE;
|
||||||
foreach (Model* model, _attachmentModels) {
|
foreach (Model* model, _attachmentModels) {
|
||||||
model->render(1.0f, renderMode, args);
|
model->render(args, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -972,6 +970,9 @@ int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) {
|
||||||
|
|
||||||
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
|
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
|
||||||
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;
|
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;
|
||||||
|
if (_moving && _motionState) {
|
||||||
|
_motionState->addDirtyFlags(EntityItem::DIRTY_POSITION);
|
||||||
|
}
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
@ -1087,20 +1088,15 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void Avatar::rebuildSkeletonBody() {
|
void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
/* TODO: implement this and remove override from MyAvatar (when we have AvatarMotionStates working)
|
const CapsuleShape& capsule = _skeletonModel.getBoundingShape();
|
||||||
if (_motionState) {
|
shapeInfo.setCapsuleY(capsule.getRadius(), capsule.getHalfHeight());
|
||||||
// compute localAABox
|
shapeInfo.setOffset(_skeletonModel.getBoundingShapeOffset());
|
||||||
const CapsuleShape& capsule = _skeletonModel.getBoundingShape();
|
}
|
||||||
float radius = capsule.getRadius();
|
|
||||||
float height = 2.0f * (capsule.getHalfHeight() + radius);
|
// virtual
|
||||||
glm::vec3 corner(-radius, -0.5f * height, -radius);
|
void Avatar::rebuildSkeletonBody() {
|
||||||
corner += _skeletonModel.getBoundingShapeOffset();
|
DependencyManager::get<AvatarManager>()->updateAvatarPhysicsShape(getSessionUUID());
|
||||||
glm::vec3 scale(2.0f * radius, height, 2.0f * radius);
|
|
||||||
//_characterController.setLocalBoundingBox(corner, scale);
|
|
||||||
_motionState->setBoundingBox(corner, scale);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
#include <QtCore/QUuid>
|
#include <QtCore/QUuid>
|
||||||
|
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
|
#include <ShapeInfo.h>
|
||||||
|
|
||||||
#include "Hand.h"
|
#include "Hand.h"
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "Recorder.h"
|
|
||||||
#include "SkeletonModel.h"
|
#include "SkeletonModel.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ enum ScreenTintLayer {
|
||||||
NUM_SCREEN_TINT_LAYERS
|
NUM_SCREEN_TINT_LAYERS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AvatarMotionState;
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
class Avatar : public AvatarData {
|
class Avatar : public AvatarData {
|
||||||
|
@ -68,7 +69,7 @@ public:
|
||||||
void init();
|
void init();
|
||||||
void simulate(float deltaTime);
|
void simulate(float deltaTime);
|
||||||
|
|
||||||
virtual void render(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode = RenderArgs::NORMAL_RENDER_MODE,
|
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition,
|
||||||
bool postLighting = false);
|
bool postLighting = false);
|
||||||
|
|
||||||
//setters
|
//setters
|
||||||
|
@ -146,9 +147,9 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE glm::vec3 getNeckPosition() const;
|
Q_INVOKABLE glm::vec3 getNeckPosition() const;
|
||||||
|
|
||||||
Q_INVOKABLE glm::vec3 getAcceleration() const { return _acceleration; }
|
Q_INVOKABLE const glm::vec3& getAcceleration() const { return _acceleration; }
|
||||||
Q_INVOKABLE glm::vec3 getAngularVelocity() const { return _angularVelocity; }
|
Q_INVOKABLE const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
||||||
Q_INVOKABLE glm::vec3 getAngularAcceleration() const { return _angularAcceleration; }
|
Q_INVOKABLE const glm::vec3& getAngularAcceleration() const { return _angularAcceleration; }
|
||||||
|
|
||||||
|
|
||||||
/// Scales a world space position vector relative to the avatar position and scale
|
/// Scales a world space position vector relative to the avatar position and scale
|
||||||
|
@ -164,6 +165,10 @@ public:
|
||||||
|
|
||||||
virtual void rebuildSkeletonBody();
|
virtual void rebuildSkeletonBody();
|
||||||
|
|
||||||
|
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
||||||
|
|
||||||
|
friend class AvatarManager;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
||||||
|
|
||||||
|
@ -208,11 +213,11 @@ protected:
|
||||||
|
|
||||||
float calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD);
|
float calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD);
|
||||||
void renderDisplayName();
|
void renderDisplayName();
|
||||||
virtual void renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f);
|
||||||
virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode) const;
|
virtual bool shouldRenderHead(const RenderArgs* renderArgs, const glm::vec3& cameraPosition) const;
|
||||||
|
|
||||||
void simulateAttachments(float deltaTime);
|
void simulateAttachments(float deltaTime);
|
||||||
virtual void renderAttachments(RenderArgs::RenderMode renderMode, RenderArgs* args);
|
virtual void renderAttachments(RenderArgs* args);
|
||||||
|
|
||||||
virtual void updateJointMappings();
|
virtual void updateJointMappings();
|
||||||
|
|
||||||
|
@ -231,7 +236,7 @@ private:
|
||||||
|
|
||||||
int _voiceSphereID;
|
int _voiceSphereID;
|
||||||
|
|
||||||
//AvatarMotionState* _motionState = nullptr;
|
AvatarMotionState* _motionState = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Avatar_h
|
#endif // hifi_Avatar_h
|
||||||
|
|
|
@ -92,22 +92,18 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
// simulate avatars
|
// simulate avatars
|
||||||
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||||
while (avatarIterator != _avatarHash.end()) {
|
while (avatarIterator != _avatarHash.end()) {
|
||||||
AvatarSharedPointer sharedAvatar = avatarIterator.value();
|
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().data());
|
||||||
Avatar* avatar = reinterpret_cast<Avatar*>(sharedAvatar.data());
|
|
||||||
|
|
||||||
if (sharedAvatar == _myAvatar || !avatar->isInitialized()) {
|
if (avatar == _myAvatar || !avatar->isInitialized()) {
|
||||||
// DO NOT update _myAvatar! Its update has already been done earlier in the main loop.
|
// DO NOT update _myAvatar! Its update has already been done earlier in the main loop.
|
||||||
// DO NOT update uninitialized Avatars
|
// DO NOT update or fade out uninitialized Avatars
|
||||||
++avatarIterator;
|
++avatarIterator;
|
||||||
continue;
|
} else if (avatar->shouldDie()) {
|
||||||
}
|
_avatarFades.push_back(avatarIterator.value());
|
||||||
if (!shouldKillAvatar(sharedAvatar)) {
|
avatarIterator = _avatarHash.erase(avatarIterator);
|
||||||
// this avatar's mixer is still around, go ahead and simulate it
|
} else {
|
||||||
avatar->simulate(deltaTime);
|
avatar->simulate(deltaTime);
|
||||||
++avatarIterator;
|
++avatarIterator;
|
||||||
} else {
|
|
||||||
// the mixer that owned this avatar is gone, give it to the vector of fades and kill it
|
|
||||||
avatarIterator = erase(avatarIterator);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +111,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
simulateAvatarFades(deltaTime);
|
simulateAvatarFades(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::renderAvatars(RenderArgs::RenderMode renderMode, bool postLighting, bool selfAvatarOnly) {
|
void AvatarManager::renderAvatars(RenderArgs* renderArgs, bool postLighting, bool selfAvatarOnly) {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
"Application::renderAvatars()");
|
"Application::renderAvatars()");
|
||||||
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderLookAtVectors);
|
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderLookAtVectors);
|
||||||
|
@ -129,14 +125,14 @@ void AvatarManager::renderAvatars(RenderArgs::RenderMode renderMode, bool postLi
|
||||||
if (!avatar->isInitialized()) {
|
if (!avatar->isInitialized()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
avatar->render(cameraPosition, renderMode, postLighting);
|
avatar->render(renderArgs, cameraPosition, postLighting);
|
||||||
avatar->setDisplayingLookatVectors(renderLookAtVectors);
|
avatar->setDisplayingLookatVectors(renderLookAtVectors);
|
||||||
}
|
}
|
||||||
renderAvatarFades(cameraPosition, renderMode);
|
renderAvatarFades(renderArgs, cameraPosition);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// just render myAvatar
|
// just render myAvatar
|
||||||
_myAvatar->render(cameraPosition, renderMode, postLighting);
|
_myAvatar->render(renderArgs, cameraPosition, postLighting);
|
||||||
_myAvatar->setDisplayingLookatVectors(renderLookAtVectors);
|
_myAvatar->setDisplayingLookatVectors(renderLookAtVectors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,14 +155,14 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::renderAvatarFades(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode) {
|
void AvatarManager::renderAvatarFades(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
// render avatar fades
|
// render avatar fades
|
||||||
Glower glower(renderMode == RenderArgs::NORMAL_RENDER_MODE ? 1.0f : 0.0f);
|
Glower glower(renderArgs, renderArgs->_renderMode == RenderArgs::NORMAL_RENDER_MODE ? 1.0f : 0.0f);
|
||||||
|
|
||||||
foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) {
|
foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) {
|
||||||
Avatar* avatar = static_cast<Avatar*>(fadingAvatar.data());
|
Avatar* avatar = static_cast<Avatar*>(fadingAvatar.data());
|
||||||
if (avatar != static_cast<Avatar*>(_myAvatar.data()) && avatar->isInitialized()) {
|
if (avatar != static_cast<Avatar*>(_myAvatar.data()) && avatar->isInitialized()) {
|
||||||
avatar->render(cameraPosition, renderMode);
|
avatar->render(renderArgs, cameraPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,24 +171,52 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
||||||
return AvatarSharedPointer(new Avatar());
|
return AvatarSharedPointer(new Avatar());
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarHash::iterator AvatarManager::erase(const AvatarHash::iterator& iterator) {
|
// virtual
|
||||||
if (iterator.key() != MY_AVATAR_KEY) {
|
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||||
if (reinterpret_cast<Avatar*>(iterator.value().data())->isInitialized()) {
|
AvatarSharedPointer avatar = AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer);
|
||||||
_avatarFades.push_back(iterator.value());
|
return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected
|
||||||
|
void AvatarManager::removeAvatarMotionState(Avatar* avatar) {
|
||||||
|
AvatarMotionState* motionState= avatar->_motionState;
|
||||||
|
if (motionState) {
|
||||||
|
// clean up physics stuff
|
||||||
|
motionState->clearObjectBackPointer();
|
||||||
|
avatar->_motionState = nullptr;
|
||||||
|
_avatarMotionStates.remove(motionState);
|
||||||
|
_motionStatesToAdd.remove(motionState);
|
||||||
|
_motionStatesToDelete.push_back(motionState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
void AvatarManager::removeAvatar(const QUuid& sessionUUID) {
|
||||||
|
AvatarHash::iterator avatarIterator = _avatarHash.find(sessionUUID);
|
||||||
|
if (avatarIterator != _avatarHash.end()) {
|
||||||
|
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().data());
|
||||||
|
if (avatar != _myAvatar && avatar->isInitialized()) {
|
||||||
|
removeAvatarMotionState(avatar);
|
||||||
|
|
||||||
|
_avatarFades.push_back(avatarIterator.value());
|
||||||
|
_avatarHash.erase(avatarIterator);
|
||||||
}
|
}
|
||||||
return AvatarHashMap::erase(iterator);
|
|
||||||
} else {
|
|
||||||
// never remove _myAvatar from the list
|
|
||||||
AvatarHash::iterator returnIterator = iterator;
|
|
||||||
return ++returnIterator;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::clearOtherAvatars() {
|
void AvatarManager::clearOtherAvatars() {
|
||||||
// clear any avatars that came from an avatar-mixer
|
// clear any avatars that came from an avatar-mixer
|
||||||
AvatarHash::iterator removeAvatar = _avatarHash.begin();
|
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||||
while (removeAvatar != _avatarHash.end()) {
|
while (avatarIterator != _avatarHash.end()) {
|
||||||
removeAvatar = erase(removeAvatar);
|
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().data());
|
||||||
|
if (avatar == _myAvatar || !avatar->isInitialized()) {
|
||||||
|
// don't remove myAvatar or uninitialized avatars from the list
|
||||||
|
++avatarIterator;
|
||||||
|
} else {
|
||||||
|
removeAvatarMotionState(avatar);
|
||||||
|
_avatarFades.push_back(avatarIterator.value());
|
||||||
|
avatarIterator = _avatarHash.erase(avatarIterator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_myAvatar->clearLookAtTargetAvatar();
|
_myAvatar->clearLookAtTargetAvatar();
|
||||||
}
|
}
|
||||||
|
@ -215,3 +239,57 @@ QVector<AvatarManager::LocalLight> AvatarManager::getLocalLights() const {
|
||||||
return _localLights;
|
return _localLights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VectorOfMotionStates& AvatarManager::getObjectsToDelete() {
|
||||||
|
_tempMotionStates.clear();
|
||||||
|
_tempMotionStates.swap(_motionStatesToDelete);
|
||||||
|
return _tempMotionStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorOfMotionStates& AvatarManager::getObjectsToAdd() {
|
||||||
|
_tempMotionStates.clear();
|
||||||
|
|
||||||
|
for (auto motionState : _motionStatesToAdd) {
|
||||||
|
_tempMotionStates.push_back(motionState);
|
||||||
|
}
|
||||||
|
_motionStatesToAdd.clear();
|
||||||
|
return _tempMotionStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorOfMotionStates& AvatarManager::getObjectsToChange() {
|
||||||
|
_tempMotionStates.clear();
|
||||||
|
for (auto state : _avatarMotionStates) {
|
||||||
|
if (state->_dirtyFlags > 0) {
|
||||||
|
_tempMotionStates.push_back(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _tempMotionStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarManager::handleOutgoingChanges(VectorOfMotionStates& motionStates) {
|
||||||
|
// TODO: extract the MyAvatar results once we use a MotionState for it.
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarManager::handleCollisionEvents(CollisionEvents& collisionEvents) {
|
||||||
|
// TODO: expose avatar collision events to JS
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) {
|
||||||
|
AvatarHash::iterator avatarItr = _avatarHash.find(id);
|
||||||
|
if (avatarItr != _avatarHash.end()) {
|
||||||
|
Avatar* avatar = static_cast<Avatar*>(avatarItr.value().data());
|
||||||
|
AvatarMotionState* motionState = avatar->_motionState;
|
||||||
|
if (motionState) {
|
||||||
|
motionState->addDirtyFlags(EntityItem::DIRTY_SHAPE);
|
||||||
|
} else {
|
||||||
|
ShapeInfo shapeInfo;
|
||||||
|
avatar->computeShapeInfo(shapeInfo);
|
||||||
|
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||||
|
if (shape) {
|
||||||
|
AvatarMotionState* motionState = new AvatarMotionState(avatar, shape);
|
||||||
|
avatar->_motionState = motionState;
|
||||||
|
_motionStatesToAdd.insert(motionState);
|
||||||
|
_avatarMotionStates.insert(motionState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,8 +17,10 @@
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
#include <AvatarHashMap.h>
|
#include <AvatarHashMap.h>
|
||||||
|
#include <PhysicsEngine.h>
|
||||||
|
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
|
#include "AvatarMotionState.h"
|
||||||
|
|
||||||
class MyAvatar;
|
class MyAvatar;
|
||||||
|
|
||||||
|
@ -37,7 +39,7 @@ public:
|
||||||
|
|
||||||
void updateMyAvatar(float deltaTime);
|
void updateMyAvatar(float deltaTime);
|
||||||
void updateOtherAvatars(float deltaTime);
|
void updateOtherAvatars(float deltaTime);
|
||||||
void renderAvatars(RenderArgs::RenderMode renderMode, bool postLighting = false, bool selfAvatarOnly = false);
|
void renderAvatars(RenderArgs* renderArgs, bool postLighting = false, bool selfAvatarOnly = false);
|
||||||
|
|
||||||
void clearOtherAvatars();
|
void clearOtherAvatars();
|
||||||
|
|
||||||
|
@ -51,6 +53,14 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void setLocalLights(const QVector<AvatarManager::LocalLight>& localLights);
|
Q_INVOKABLE void setLocalLights(const QVector<AvatarManager::LocalLight>& localLights);
|
||||||
Q_INVOKABLE QVector<AvatarManager::LocalLight> getLocalLights() const;
|
Q_INVOKABLE QVector<AvatarManager::LocalLight> getLocalLights() const;
|
||||||
|
|
||||||
|
VectorOfMotionStates& getObjectsToDelete();
|
||||||
|
VectorOfMotionStates& getObjectsToAdd();
|
||||||
|
VectorOfMotionStates& getObjectsToChange();
|
||||||
|
void handleOutgoingChanges(VectorOfMotionStates& motionStates);
|
||||||
|
void handleCollisionEvents(CollisionEvents& collisionEvents);
|
||||||
|
|
||||||
|
void updateAvatarPhysicsShape(const QUuid& id);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
|
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
|
||||||
|
@ -60,12 +70,13 @@ private:
|
||||||
AvatarManager(const AvatarManager& other);
|
AvatarManager(const AvatarManager& other);
|
||||||
|
|
||||||
void simulateAvatarFades(float deltaTime);
|
void simulateAvatarFades(float deltaTime);
|
||||||
void renderAvatarFades(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode);
|
void renderAvatarFades(RenderArgs* renderArgs, const glm::vec3& cameraPosition);
|
||||||
|
|
||||||
AvatarSharedPointer newSharedAvatar();
|
|
||||||
|
|
||||||
// virtual overrides
|
// virtual overrides
|
||||||
AvatarHash::iterator erase(const AvatarHash::iterator& iterator);
|
virtual AvatarSharedPointer newSharedAvatar();
|
||||||
|
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
||||||
|
void removeAvatarMotionState(Avatar* avatar);
|
||||||
|
virtual void removeAvatar(const QUuid& sessionUUID);
|
||||||
|
|
||||||
QVector<AvatarSharedPointer> _avatarFades;
|
QVector<AvatarSharedPointer> _avatarFades;
|
||||||
QSharedPointer<MyAvatar> _myAvatar;
|
QSharedPointer<MyAvatar> _myAvatar;
|
||||||
|
@ -74,6 +85,11 @@ private:
|
||||||
QVector<AvatarManager::LocalLight> _localLights;
|
QVector<AvatarManager::LocalLight> _localLights;
|
||||||
|
|
||||||
bool _shouldShowReceiveStats = false;
|
bool _shouldShowReceiveStats = false;
|
||||||
|
|
||||||
|
SetOfAvatarMotionStates _avatarMotionStates;
|
||||||
|
SetOfMotionStates _motionStatesToAdd;
|
||||||
|
VectorOfMotionStates _motionStatesToDelete;
|
||||||
|
VectorOfMotionStates _tempMotionStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(AvatarManager::LocalLight)
|
Q_DECLARE_METATYPE(AvatarManager::LocalLight)
|
||||||
|
|
160
interface/src/avatar/AvatarMotionState.cpp
Normal file
160
interface/src/avatar/AvatarMotionState.cpp
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
//
|
||||||
|
// AvatarMotionState.cpp
|
||||||
|
// interface/src/avatar/
|
||||||
|
//
|
||||||
|
// Created by Andrew Meadows 2015.05.14
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <PhysicsHelpers.h>
|
||||||
|
|
||||||
|
#include "Avatar.h"
|
||||||
|
#include "AvatarMotionState.h"
|
||||||
|
#include "BulletUtil.h"
|
||||||
|
|
||||||
|
AvatarMotionState::AvatarMotionState(Avatar* avatar, btCollisionShape* shape) : ObjectMotionState(shape), _avatar(avatar) {
|
||||||
|
assert(_avatar);
|
||||||
|
if (_shape) {
|
||||||
|
_mass = 100.0f; // HACK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarMotionState::~AvatarMotionState() {
|
||||||
|
_avatar = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
uint32_t AvatarMotionState::getAndClearIncomingDirtyFlags() {
|
||||||
|
uint32_t dirtyFlags = 0;
|
||||||
|
if (_body && _avatar) {
|
||||||
|
dirtyFlags = _dirtyFlags;
|
||||||
|
_dirtyFlags = 0;
|
||||||
|
}
|
||||||
|
return dirtyFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
MotionType AvatarMotionState::computeObjectMotionType() const {
|
||||||
|
// TODO?: support non-DYNAMIC motion for avatars? (e.g. when sitting)
|
||||||
|
return MOTION_TYPE_DYNAMIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual and protected
|
||||||
|
btCollisionShape* AvatarMotionState::computeNewShape() {
|
||||||
|
if (_avatar) {
|
||||||
|
ShapeInfo shapeInfo;
|
||||||
|
_avatar->computeShapeInfo(shapeInfo);
|
||||||
|
return getShapeManager()->getShape(shapeInfo);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
bool AvatarMotionState::isMoving() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
void AvatarMotionState::getWorldTransform(btTransform& worldTrans) const {
|
||||||
|
if (!_avatar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
worldTrans.setOrigin(glmToBullet(getObjectPosition()));
|
||||||
|
worldTrans.setRotation(glmToBullet(getObjectRotation()));
|
||||||
|
if (_body) {
|
||||||
|
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||||
|
_body->setAngularVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||||
|
if (!_avatar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// HACK: The PhysicsEngine does not actually move OTHER avatars -- instead it slaves their local RigidBody to the transform
|
||||||
|
// as specified by a remote simulation. However, to give the remote simulation time to respond to our own objects we tie
|
||||||
|
// the other avatar's body to its true position with a simple spring. This is a HACK that will have to be improved later.
|
||||||
|
const float SPRING_TIMESCALE = 0.5f;
|
||||||
|
float tau = PHYSICS_ENGINE_FIXED_SUBSTEP / SPRING_TIMESCALE;
|
||||||
|
btVector3 currentPosition = worldTrans.getOrigin();
|
||||||
|
btVector3 targetPosition = glmToBullet(getObjectPosition());
|
||||||
|
btTransform newTransform;
|
||||||
|
newTransform.setOrigin((1.0f - tau) * currentPosition + tau * targetPosition);
|
||||||
|
newTransform.setRotation(glmToBullet(getObjectRotation()));
|
||||||
|
_body->setWorldTransform(newTransform);
|
||||||
|
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||||
|
_body->setAngularVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// These pure virtual methods must be implemented for each MotionState type
|
||||||
|
// and make it possible to implement more complicated methods in this base class.
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
float AvatarMotionState::getObjectRestitution() const {
|
||||||
|
return 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
float AvatarMotionState::getObjectFriction() const {
|
||||||
|
return 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
float AvatarMotionState::getObjectLinearDamping() const {
|
||||||
|
return 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
float AvatarMotionState::getObjectAngularDamping() const {
|
||||||
|
return 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
glm::vec3 AvatarMotionState::getObjectPosition() const {
|
||||||
|
return _avatar->getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
glm::quat AvatarMotionState::getObjectRotation() const {
|
||||||
|
return _avatar->getOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
const glm::vec3& AvatarMotionState::getObjectLinearVelocity() const {
|
||||||
|
return _avatar->getVelocity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
const glm::vec3& AvatarMotionState::getObjectAngularVelocity() const {
|
||||||
|
return _avatar->getAngularVelocity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
const glm::vec3& AvatarMotionState::getObjectGravity() const {
|
||||||
|
return _avatar->getAcceleration();
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
const QUuid& AvatarMotionState::getObjectID() const {
|
||||||
|
return _avatar->getSessionUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
QUuid AvatarMotionState::getSimulatorID() const {
|
||||||
|
return _avatar->getSessionUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
void AvatarMotionState::bump() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
void AvatarMotionState::clearObjectBackPointer() {
|
||||||
|
ObjectMotionState::clearObjectBackPointer();
|
||||||
|
_avatar = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
75
interface/src/avatar/AvatarMotionState.h
Normal file
75
interface/src/avatar/AvatarMotionState.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
//
|
||||||
|
// AvatarMotionState.h
|
||||||
|
// interface/src/avatar/
|
||||||
|
//
|
||||||
|
// Created by Andrew Meadows 2015.05.14
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_AvatarMotionState_h
|
||||||
|
#define hifi_AvatarMotionState_h
|
||||||
|
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
|
#include <ObjectMotionState.h>
|
||||||
|
|
||||||
|
class Avatar;
|
||||||
|
|
||||||
|
class AvatarMotionState : public ObjectMotionState {
|
||||||
|
public:
|
||||||
|
AvatarMotionState(Avatar* avatar, btCollisionShape* shape);
|
||||||
|
~AvatarMotionState();
|
||||||
|
|
||||||
|
virtual MotionType getMotionType() const { return _motionType; }
|
||||||
|
|
||||||
|
virtual uint32_t getAndClearIncomingDirtyFlags();
|
||||||
|
|
||||||
|
virtual MotionType computeObjectMotionType() const;
|
||||||
|
|
||||||
|
virtual bool isMoving() const;
|
||||||
|
|
||||||
|
// this relays incoming position/rotation to the RigidBody
|
||||||
|
virtual void getWorldTransform(btTransform& worldTrans) const;
|
||||||
|
|
||||||
|
// this relays outgoing position/rotation to the EntityItem
|
||||||
|
virtual void setWorldTransform(const btTransform& worldTrans);
|
||||||
|
|
||||||
|
|
||||||
|
// These pure virtual methods must be implemented for each MotionState type
|
||||||
|
// and make it possible to implement more complicated methods in this base class.
|
||||||
|
|
||||||
|
virtual float getObjectRestitution() const;
|
||||||
|
virtual float getObjectFriction() const;
|
||||||
|
virtual float getObjectLinearDamping() const;
|
||||||
|
virtual float getObjectAngularDamping() const;
|
||||||
|
|
||||||
|
virtual glm::vec3 getObjectPosition() const;
|
||||||
|
virtual glm::quat getObjectRotation() const;
|
||||||
|
virtual const glm::vec3& getObjectLinearVelocity() const;
|
||||||
|
virtual const glm::vec3& getObjectAngularVelocity() const;
|
||||||
|
virtual const glm::vec3& getObjectGravity() const;
|
||||||
|
|
||||||
|
virtual const QUuid& getObjectID() const;
|
||||||
|
|
||||||
|
virtual QUuid getSimulatorID() const;
|
||||||
|
virtual void bump();
|
||||||
|
|
||||||
|
void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal);
|
||||||
|
|
||||||
|
void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; }
|
||||||
|
|
||||||
|
friend class AvatarManager;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual btCollisionShape* computeNewShape();
|
||||||
|
virtual void clearObjectBackPointer();
|
||||||
|
Avatar* _avatar;
|
||||||
|
uint32_t _dirtyFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QSet<AvatarMotionState*> SetOfAvatarMotionStates;
|
||||||
|
|
||||||
|
#endif // hifi_AvatarMotionState_h
|
|
@ -102,8 +102,8 @@ void Hand::resolvePenetrations() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hand::render(bool isMine, Model::RenderMode renderMode) {
|
void Hand::render(RenderArgs* renderArgs, bool isMine) {
|
||||||
if (renderMode != RenderArgs::SHADOW_RENDER_MODE &&
|
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE &&
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes)) {
|
Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes)) {
|
||||||
// draw a green sphere at hand joint location, which is actually near the wrist)
|
// draw a green sphere at hand joint location, which is actually near the wrist)
|
||||||
for (size_t i = 0; i < getNumPalms(); i++) {
|
for (size_t i = 0; i < getNumPalms(); i++) {
|
||||||
|
@ -119,7 +119,7 @@ void Hand::render(bool isMine, Model::RenderMode renderMode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderMode != RenderArgs::SHADOW_RENDER_MODE && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHands)) {
|
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHands)) {
|
||||||
renderHandTargets(isMine);
|
renderHandTargets(isMine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void simulate(float deltaTime, bool isMine);
|
void simulate(float deltaTime, bool isMine);
|
||||||
void render(bool isMine, Model::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE);
|
void render(RenderArgs* renderArgs, bool isMine);
|
||||||
|
|
||||||
void collideAgainstAvatar(Avatar* avatar, bool isMyHand);
|
void collideAgainstAvatar(Avatar* avatar, bool isMyHand);
|
||||||
|
|
||||||
|
|
|
@ -262,15 +262,13 @@ void Head::relaxLean(float deltaTime) {
|
||||||
_deltaLeanForward *= relaxationFactor;
|
_deltaLeanForward *= relaxationFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::render(float alpha, ViewFrustum* renderFrustum, Model::RenderMode mode, bool postLighting) {
|
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting) {
|
||||||
if (postLighting) {
|
if (postLighting) {
|
||||||
if (_renderLookatVectors) {
|
if (_renderLookatVectors) {
|
||||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition());
|
renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RenderArgs args;
|
_faceModel.render(renderArgs, alpha);
|
||||||
args._viewFrustum = renderFrustum;
|
|
||||||
_faceModel.render(alpha, mode, &args);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,9 +351,9 @@ void Head::addLeanDeltas(float sideways, float forward) {
|
||||||
_deltaLeanForward += forward;
|
_deltaLeanForward += forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
|
void Head::renderLookatVectors(RenderArgs* renderArgs, glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
DependencyManager::get<GlowEffect>()->begin();
|
DependencyManager::get<GlowEffect>()->begin(renderArgs);
|
||||||
|
|
||||||
glLineWidth(2.0);
|
glLineWidth(2.0);
|
||||||
|
|
||||||
|
@ -364,7 +362,7 @@ void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosi
|
||||||
geometryCache->renderLine(leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID);
|
geometryCache->renderLine(leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID);
|
||||||
geometryCache->renderLine(rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID);
|
geometryCache->renderLine(rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID);
|
||||||
|
|
||||||
DependencyManager::get<GlowEffect>()->end();
|
DependencyManager::get<GlowEffect>()->end(renderArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
void init();
|
void init();
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
||||||
void render(float alpha, ViewFrustum* renderFrustum, Model::RenderMode mode, bool postLighting);
|
void render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting);
|
||||||
void setScale(float scale);
|
void setScale(float scale);
|
||||||
void setPosition(glm::vec3 position) { _position = position; }
|
void setPosition(glm::vec3 position) { _position = position; }
|
||||||
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
||||||
|
@ -153,7 +153,7 @@ private:
|
||||||
int _rightEyeLookAtID;
|
int _rightEyeLookAtID;
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
void renderLookatVectors(RenderArgs* renderArgs, glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
||||||
void calculateMouthShapes();
|
void calculateMouthShapes();
|
||||||
|
|
||||||
friend class FaceModel;
|
friend class FaceModel;
|
||||||
|
|
|
@ -30,7 +30,7 @@ ModelReferential::ModelReferential(Referential* referential, EntityTree* tree, A
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
_lastRefDimension = item->getDimensions();
|
_lastRefDimension = item->getDimensions();
|
||||||
_refRotation = item->getRotation();
|
_refRotation = item->getRotation();
|
||||||
|
@ -44,7 +44,7 @@ ModelReferential::ModelReferential(const QUuid& entityID, EntityTree* tree, Avat
|
||||||
_entityID(entityID),
|
_entityID(entityID),
|
||||||
_tree(tree)
|
_tree(tree)
|
||||||
{
|
{
|
||||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||||
if (!isValid() || item == NULL) {
|
if (!isValid() || item == NULL) {
|
||||||
qCDebug(interfaceapp) << "ModelReferential::constructor(): Not Valid";
|
qCDebug(interfaceapp) << "ModelReferential::constructor(): Not Valid";
|
||||||
_isValid = false;
|
_isValid = false;
|
||||||
|
@ -61,7 +61,7 @@ ModelReferential::ModelReferential(const QUuid& entityID, EntityTree* tree, Avat
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelReferential::update() {
|
void ModelReferential::update() {
|
||||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||||
if (!isValid() || item == NULL || _avatar == NULL) {
|
if (!isValid() || item == NULL || _avatar == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ JointReferential::JointReferential(Referential* referential, EntityTree* tree, A
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||||
const Model* model = getModel(item);
|
const Model* model = getModel(item);
|
||||||
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
||||||
_lastRefDimension = item->getDimensions();
|
_lastRefDimension = item->getDimensions();
|
||||||
|
@ -120,7 +120,7 @@ JointReferential::JointReferential(uint32_t jointIndex, const QUuid& entityID, E
|
||||||
_jointIndex(jointIndex)
|
_jointIndex(jointIndex)
|
||||||
{
|
{
|
||||||
_type = JOINT;
|
_type = JOINT;
|
||||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||||
const Model* model = getModel(item);
|
const Model* model = getModel(item);
|
||||||
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
||||||
qCDebug(interfaceapp) << "JointReferential::constructor(): Not Valid";
|
qCDebug(interfaceapp) << "JointReferential::constructor(): Not Valid";
|
||||||
|
@ -139,7 +139,7 @@ JointReferential::JointReferential(uint32_t jointIndex, const QUuid& entityID, E
|
||||||
}
|
}
|
||||||
|
|
||||||
void JointReferential::update() {
|
void JointReferential::update() {
|
||||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||||
const Model* model = getModel(item);
|
const Model* model = getModel(item);
|
||||||
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
||||||
return;
|
return;
|
||||||
|
@ -163,7 +163,7 @@ void JointReferential::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Model* JointReferential::getModel(const EntityItem* item) {
|
const Model* JointReferential::getModel(EntityItemPointer item) {
|
||||||
EntityItemFBXService* fbxService = _tree->getFBXService();
|
EntityItemFBXService* fbxService = _tree->getFBXService();
|
||||||
if (item != NULL && fbxService != NULL) {
|
if (item != NULL && fbxService != NULL) {
|
||||||
return fbxService->getModelForEntityItem(item);
|
return fbxService->getModelForEntityItem(item);
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Model* getModel(const EntityItem* item);
|
const Model* getModel(EntityItemPointer item);
|
||||||
virtual int packExtraData(unsigned char* destinationBuffer) const;
|
virtual int packExtraData(unsigned char* destinationBuffer) const;
|
||||||
virtual int unpackExtraData(const unsigned char* sourceBuffer, int size);
|
virtual int unpackExtraData(const unsigned char* sourceBuffer, int size);
|
||||||
|
|
||||||
|
|
|
@ -328,13 +328,13 @@ void MyAvatar::renderDebugBodyPoints() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void MyAvatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode, bool postLighting) {
|
void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
|
||||||
// don't render if we've been asked to disable local rendering
|
// don't render if we've been asked to disable local rendering
|
||||||
if (!_shouldRender) {
|
if (!_shouldRender) {
|
||||||
return; // exit early
|
return; // exit early
|
||||||
}
|
}
|
||||||
|
|
||||||
Avatar::render(cameraPosition, renderMode, postLighting);
|
Avatar::render(renderArgs, cameraPosition, postLighting);
|
||||||
|
|
||||||
// don't display IK constraints in shadow mode
|
// don't display IK constraints in shadow mode
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) && postLighting) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) && postLighting) {
|
||||||
|
@ -1166,7 +1166,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g
|
||||||
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
|
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode renderMode, bool postLighting, float glowLevel) {
|
void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel) {
|
||||||
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||||
return; // wait until both models are loaded
|
return; // wait until both models are loaded
|
||||||
}
|
}
|
||||||
|
@ -1190,28 +1190,25 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode ren
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Render the body's voxels and head
|
// Render the body's voxels and head
|
||||||
RenderArgs::RenderMode modelRenderMode = renderMode;
|
|
||||||
if (!postLighting) {
|
if (!postLighting) {
|
||||||
RenderArgs args;
|
_skeletonModel.render(renderArgs, 1.0f);
|
||||||
args._viewFrustum = renderFrustum;
|
renderAttachments(renderArgs);
|
||||||
_skeletonModel.render(1.0f, modelRenderMode, &args);
|
|
||||||
renderAttachments(renderMode, &args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render head so long as the camera isn't inside it
|
// Render head so long as the camera isn't inside it
|
||||||
if (shouldRenderHead(cameraPos, renderMode)) {
|
if (shouldRenderHead(renderArgs, cameraPos)) {
|
||||||
getHead()->render(1.0f, renderFrustum, modelRenderMode, postLighting);
|
getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting);
|
||||||
}
|
}
|
||||||
if (postLighting) {
|
if (postLighting) {
|
||||||
getHand()->render(true, modelRenderMode);
|
getHand()->render(renderArgs, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f;
|
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f;
|
||||||
|
|
||||||
bool MyAvatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode) const {
|
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs, const glm::vec3& cameraPosition) const {
|
||||||
const Head* head = getHead();
|
const Head* head = getHead();
|
||||||
return (renderMode != RenderArgs::NORMAL_RENDER_MODE) || (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON) ||
|
return (renderArgs->_renderMode != RenderArgs::NORMAL_RENDER_MODE) || (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON) ||
|
||||||
(glm::length(cameraPosition - head->getEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE * _scale);
|
(glm::length(cameraPosition - head->getEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE * _scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1474,7 +1471,8 @@ void MyAvatar::maybeUpdateBillboard() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QImage image = Application::getInstance()->renderAvatarBillboard();
|
RenderArgs renderArgs;
|
||||||
|
QImage image = Application::getInstance()->renderAvatarBillboard(&renderArgs);
|
||||||
_billboard.clear();
|
_billboard.clear();
|
||||||
QBuffer buffer(&_billboard);
|
QBuffer buffer(&_billboard);
|
||||||
buffer.open(QIODevice::WriteOnly);
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
@ -1551,9 +1549,9 @@ void MyAvatar::updateMotionBehavior() {
|
||||||
_feetTouchFloor = menu->isOptionChecked(MenuOption::ShiftHipsForIdleAnimations);
|
_feetTouchFloor = menu->isOptionChecked(MenuOption::ShiftHipsForIdleAnimations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::renderAttachments(RenderArgs::RenderMode renderMode, RenderArgs* args) {
|
void MyAvatar::renderAttachments(RenderArgs* args) {
|
||||||
if (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON || renderMode == RenderArgs::MIRROR_RENDER_MODE) {
|
if (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON || args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
|
||||||
Avatar::renderAttachments(renderMode, args);
|
Avatar::renderAttachments(args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const FBXGeometry& geometry = _skeletonModel.getGeometry()->getFBXGeometry();
|
const FBXGeometry& geometry = _skeletonModel.getGeometry()->getFBXGeometry();
|
||||||
|
@ -1563,7 +1561,7 @@ void MyAvatar::renderAttachments(RenderArgs::RenderMode renderMode, RenderArgs*
|
||||||
for (int i = 0; i < _attachmentData.size(); i++) {
|
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||||
const QString& jointName = _attachmentData.at(i).jointName;
|
const QString& jointName = _attachmentData.at(i).jointName;
|
||||||
if (jointName != headJointName && jointName != "Head") {
|
if (jointName != headJointName && jointName != "Head") {
|
||||||
_attachmentModels.at(i)->render(1.0f, renderMode, args);
|
_attachmentModels.at(i)->render(args, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,9 @@ public:
|
||||||
void simulate(float deltaTime);
|
void simulate(float deltaTime);
|
||||||
void updateFromTrackers(float deltaTime);
|
void updateFromTrackers(float deltaTime);
|
||||||
|
|
||||||
void render(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode = RenderArgs::NORMAL_RENDER_MODE, bool postLighting = false);
|
void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting = false);
|
||||||
void renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f);
|
||||||
bool shouldRenderHead(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode) const;
|
bool shouldRenderHead(const RenderArgs* renderArgs, const glm::vec3& cameraPosition) const override;
|
||||||
void renderDebugBodyPoints();
|
void renderDebugBodyPoints();
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
|
@ -198,7 +198,7 @@ signals:
|
||||||
void transformChanged();
|
void transformChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void renderAttachments(RenderArgs::RenderMode renderMode, RenderArgs* args);
|
virtual void renderAttachments(RenderArgs* args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent) :
|
||||||
_headClipDistance(DEFAULT_NEAR_CLIP)
|
_headClipDistance(DEFAULT_NEAR_CLIP)
|
||||||
{
|
{
|
||||||
assert(_owningAvatar);
|
assert(_owningAvatar);
|
||||||
|
_enableShapes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonModel::~SkeletonModel() {
|
SkeletonModel::~SkeletonModel() {
|
||||||
|
|
|
@ -465,7 +465,7 @@ void OculusManager::configureCamera(Camera& camera) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Displays everything for the oculus, frame timing must be active
|
//Displays everything for the oculus, frame timing must be active
|
||||||
void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera) {
|
void OculusManager::display(QGLWidget * glCanvas, RenderArgs* renderArgs, const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera) {
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Ensure the frame counter always increments by exactly 1
|
// Ensure the frame counter always increments by exactly 1
|
||||||
|
@ -532,7 +532,7 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati
|
||||||
|
|
||||||
//Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it
|
//Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
|
||||||
DependencyManager::get<GlowEffect>()->prepare();
|
DependencyManager::get<GlowEffect>()->prepare(renderArgs);
|
||||||
} else {
|
} else {
|
||||||
auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFBO));
|
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFBO));
|
||||||
|
@ -613,7 +613,8 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati
|
||||||
|
|
||||||
glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h);
|
glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h);
|
||||||
|
|
||||||
qApp->displaySide(*_camera, false, RenderArgs::MONO);
|
renderArgs->_renderSide = RenderArgs::MONO;
|
||||||
|
qApp->displaySide(renderArgs, *_camera, false);
|
||||||
qApp->getApplicationOverlay().displayOverlayTextureHmd(*_camera);
|
qApp->getApplicationOverlay().displayOverlayTextureHmd(*_camera);
|
||||||
});
|
});
|
||||||
_activeEye = ovrEye_Count;
|
_activeEye = ovrEye_Count;
|
||||||
|
@ -625,7 +626,7 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
|
||||||
//Full texture viewport for glow effect
|
//Full texture viewport for glow effect
|
||||||
glViewport(0, 0, _renderTargetSize.w, _renderTargetSize.h);
|
glViewport(0, 0, _renderTargetSize.w, _renderTargetSize.h);
|
||||||
finalFbo = DependencyManager::get<GlowEffect>()->render();
|
finalFbo = DependencyManager::get<GlowEffect>()->render(renderArgs);
|
||||||
} else {
|
} else {
|
||||||
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "RenderArgs.h"
|
||||||
|
|
||||||
class Camera;
|
class Camera;
|
||||||
class PalmData;
|
class PalmData;
|
||||||
class Text3DOverlay;
|
class Text3DOverlay;
|
||||||
|
@ -61,7 +63,7 @@ public:
|
||||||
static void endFrameTiming();
|
static void endFrameTiming();
|
||||||
static bool allowSwap();
|
static bool allowSwap();
|
||||||
static void configureCamera(Camera& camera);
|
static void configureCamera(Camera& camera);
|
||||||
static void display(QGLWidget * glCanvas, const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera);
|
static void display(QGLWidget * glCanvas, RenderArgs* renderArgs, const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera);
|
||||||
static void reset();
|
static void reset();
|
||||||
|
|
||||||
/// param \yaw[out] yaw in radians
|
/// param \yaw[out] yaw in radians
|
||||||
|
|
|
@ -80,7 +80,7 @@ void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int scre
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TV3DManager::display(Camera& whichCamera) {
|
void TV3DManager::display(RenderArgs* renderArgs, Camera& whichCamera) {
|
||||||
double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
|
double nearZ = DEFAULT_NEAR_CLIP; // near clipping plane
|
||||||
double farZ = DEFAULT_FAR_CLIP; // far clipping plane
|
double farZ = DEFAULT_FAR_CLIP; // far clipping plane
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ void TV3DManager::display(Camera& whichCamera) {
|
||||||
int portalH = deviceSize.height();
|
int portalH = deviceSize.height();
|
||||||
|
|
||||||
|
|
||||||
DependencyManager::get<GlowEffect>()->prepare();
|
DependencyManager::get<GlowEffect>()->prepare(renderArgs);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
Camera eyeCamera;
|
Camera eyeCamera;
|
||||||
|
@ -118,7 +118,8 @@ void TV3DManager::display(Camera& whichCamera) {
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
qApp->displaySide(eyeCamera, false, RenderArgs::MONO);
|
renderArgs->_renderSide = RenderArgs::MONO;
|
||||||
|
qApp->displaySide(renderArgs, eyeCamera, false);
|
||||||
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov);
|
||||||
_activeEye = NULL;
|
_activeEye = NULL;
|
||||||
}, [&]{
|
}, [&]{
|
||||||
|
@ -128,7 +129,7 @@ void TV3DManager::display(Camera& whichCamera) {
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
auto finalFbo = DependencyManager::get<GlowEffect>()->render();
|
auto finalFbo = DependencyManager::get<GlowEffect>()->render(renderArgs);
|
||||||
auto fboSize = finalFbo->getSize();
|
auto fboSize = finalFbo->getSize();
|
||||||
// Get the ACTUAL device size for the BLIT
|
// Get the ACTUAL device size for the BLIT
|
||||||
deviceSize = qApp->getDeviceSize();
|
deviceSize = qApp->getDeviceSize();
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
static void connect();
|
static void connect();
|
||||||
static bool isConnected();
|
static bool isConnected();
|
||||||
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
||||||
static void display(Camera& whichCamera);
|
static void display(RenderArgs* renderArgs, Camera& whichCamera);
|
||||||
static void overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
static void overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane);
|
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane);
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -37,8 +37,8 @@ OctreeFade::OctreeFade(FadeDirection direction, float red, float green, float bl
|
||||||
opacity = (direction == FADE_OUT) ? FADE_OUT_START : FADE_IN_START;
|
opacity = (direction == FADE_OUT) ? FADE_OUT_START : FADE_IN_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeFade::render() {
|
void OctreeFade::render(RenderArgs* renderArgs) {
|
||||||
DependencyManager::get<GlowEffect>()->begin();
|
DependencyManager::get<GlowEffect>()->begin(renderArgs);
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -53,7 +53,7 @@ void OctreeFade::render() {
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
|
||||||
DependencyManager::get<GlowEffect>()->end();
|
DependencyManager::get<GlowEffect>()->end(renderArgs);
|
||||||
|
|
||||||
opacity *= (direction == FADE_OUT) ? FADE_OUT_STEP : FADE_IN_STEP;
|
opacity *= (direction == FADE_OUT) ? FADE_OUT_STEP : FADE_IN_STEP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
OctreeFade(FadeDirection direction = FADE_OUT, float red = DEFAULT_RED,
|
OctreeFade(FadeDirection direction = FADE_OUT, float red = DEFAULT_RED,
|
||||||
float green = DEFAULT_GREEN, float blue = DEFAULT_BLUE);
|
float green = DEFAULT_GREEN, float blue = DEFAULT_BLUE);
|
||||||
|
|
||||||
void render();
|
void render(RenderArgs* renderArgs);
|
||||||
bool isDone() const;
|
bool isDone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,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() {
|
void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
||||||
Overlays& overlays = qApp->getOverlays();
|
Overlays& overlays = qApp->getOverlays();
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ void ApplicationOverlay::renderOverlay() {
|
||||||
// give external parties a change to hook in
|
// give external parties a change to hook in
|
||||||
emit qApp->renderingOverlay();
|
emit qApp->renderingOverlay();
|
||||||
|
|
||||||
overlays.renderHUD();
|
overlays.renderHUD(renderArgs);
|
||||||
|
|
||||||
renderPointers();
|
renderPointers();
|
||||||
|
|
||||||
|
@ -979,6 +979,14 @@ void ApplicationOverlay::renderStatsAndLogs() {
|
||||||
glLineWidth(1.0f);
|
glLineWidth(1.0f);
|
||||||
glPointSize(1.0f);
|
glPointSize(1.0f);
|
||||||
|
|
||||||
|
// Determine whether to compute timing details
|
||||||
|
bool shouldDisplayTimingDetail = Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails) &&
|
||||||
|
Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||||
|
Stats::getInstance()->isExpanded();
|
||||||
|
if (shouldDisplayTimingDetail != PerformanceTimer::isActive()) {
|
||||||
|
PerformanceTimer::setActive(shouldDisplayTimingDetail);
|
||||||
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||||
// let's set horizontal offset to give stats some margin to mirror
|
// let's set horizontal offset to give stats some margin to mirror
|
||||||
int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
|
int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
ApplicationOverlay();
|
ApplicationOverlay();
|
||||||
~ApplicationOverlay();
|
~ApplicationOverlay();
|
||||||
|
|
||||||
void renderOverlay();
|
void renderOverlay(RenderArgs* renderArgs);
|
||||||
void displayOverlayTexture();
|
void displayOverlayTexture();
|
||||||
void displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov);
|
void displayOverlayTextureStereo(Camera& whichCamera, float aspectRatio, float fov);
|
||||||
void displayOverlayTextureHmd(Camera& whichCamera);
|
void displayOverlayTextureHmd(Camera& whichCamera);
|
||||||
|
|
|
@ -59,6 +59,7 @@ JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) :
|
||||||
connect(_scriptEngine, SIGNAL(evaluationFinished(QScriptValue, bool)),
|
connect(_scriptEngine, SIGNAL(evaluationFinished(QScriptValue, bool)),
|
||||||
this, SLOT(handleEvalutationFinished(QScriptValue, bool)));
|
this, SLOT(handleEvalutationFinished(QScriptValue, bool)));
|
||||||
connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&)));
|
connect(_scriptEngine, SIGNAL(printedMessage(const QString&)), this, SLOT(handlePrint(const QString&)));
|
||||||
|
connect(_scriptEngine, SIGNAL(errorMessage(const QString&)), this, SLOT(handleError(const QString&)));
|
||||||
|
|
||||||
resizeTextInput();
|
resizeTextInput();
|
||||||
}
|
}
|
||||||
|
@ -96,6 +97,10 @@ void JSConsole::handleEvalutationFinished(QScriptValue result, bool isException)
|
||||||
appendMessage(gutter, resultStr);
|
appendMessage(gutter, resultStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JSConsole::handleError(const QString& message) {
|
||||||
|
appendMessage(GUTTER_ERROR, "<span style='" + RESULT_ERROR_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
|
||||||
|
}
|
||||||
|
|
||||||
void JSConsole::handlePrint(const QString& message) {
|
void JSConsole::handlePrint(const QString& message) {
|
||||||
appendMessage("", message);
|
appendMessage("", message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ protected slots:
|
||||||
void resizeTextInput();
|
void resizeTextInput();
|
||||||
void handleEvalutationFinished(QScriptValue result, bool isException);
|
void handleEvalutationFinished(QScriptValue result, bool isException);
|
||||||
void handlePrint(const QString& message);
|
void handlePrint(const QString& message);
|
||||||
|
void handleError(const QString& message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void appendMessage(const QString& gutter, const QString& message);
|
void appendMessage(const QString& gutter, const QString& message);
|
||||||
|
|
|
@ -47,7 +47,7 @@ RearMirrorTools::RearMirrorTools(QRect& bounds) :
|
||||||
_headZoomIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE);
|
_headZoomIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RearMirrorTools::render(bool fullScreen, const QPoint & mousePosition) {
|
void RearMirrorTools::render(RenderArgs* renderArgs, bool fullScreen, const QPoint & mousePosition) {
|
||||||
if (fullScreen) {
|
if (fullScreen) {
|
||||||
_fullScreen = true;
|
_fullScreen = true;
|
||||||
displayIcon(QRect(QPoint(), qApp->getDeviceSize()), _shrinkIconRect, _closeTexture);
|
displayIcon(QRect(QPoint(), qApp->getDeviceSize()), _shrinkIconRect, _closeTexture);
|
||||||
|
|
|
@ -24,7 +24,7 @@ class RearMirrorTools : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
RearMirrorTools(QRect& bounds);
|
RearMirrorTools(QRect& bounds);
|
||||||
void render(bool fullScreen, const QPoint & mousePos);
|
void render(RenderArgs* renderArgs, bool fullScreen, const QPoint & mousePos);
|
||||||
bool mousePressEvent(int x, int y);
|
bool mousePressEvent(int x, int y);
|
||||||
|
|
||||||
static Setting::Handle<int> rearViewZoomLevel;
|
static Setting::Handle<int> rearViewZoomLevel;
|
||||||
|
|
|
@ -224,9 +224,10 @@ void Stats::display(
|
||||||
lines = 5;
|
lines = 5;
|
||||||
int columnOneWidth = _generalStatsWidth;
|
int columnOneWidth = _generalStatsWidth;
|
||||||
|
|
||||||
PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up
|
bool performanceTimerIsActive = PerformanceTimer::isActive();
|
||||||
|
bool displayPerf = _expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails);
|
||||||
if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails)) {
|
if (displayPerf && performanceTimerIsActive) {
|
||||||
|
PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up
|
||||||
|
|
||||||
columnOneWidth = _generalStatsWidth + _pingStatsWidth + _geoStatsWidth; // 3 columns wide...
|
columnOneWidth = _generalStatsWidth + _pingStatsWidth + _geoStatsWidth; // 3 columns wide...
|
||||||
// we will also include room for 1 line per timing record and a header of 4 lines
|
// we will also include room for 1 line per timing record and a header of 4 lines
|
||||||
|
@ -276,7 +277,7 @@ void Stats::display(
|
||||||
|
|
||||||
|
|
||||||
// TODO: the display of these timing details should all be moved to JavaScript
|
// TODO: the display of these timing details should all be moved to JavaScript
|
||||||
if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails)) {
|
if (displayPerf && performanceTimerIsActive) {
|
||||||
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
|
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
|
||||||
// Timing details...
|
// Timing details...
|
||||||
verticalOffset += STATS_PELS_PER_LINE * 4; // skip 3 lines to be under the other columns
|
verticalOffset += STATS_PELS_PER_LINE * 4; // skip 3 lines to be under the other columns
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
static void drawBackground(unsigned int rgba, int x, int y, int width, int height);
|
static void drawBackground(unsigned int rgba, int x, int y, int width, int height);
|
||||||
|
|
||||||
void toggleExpanded();
|
void toggleExpanded();
|
||||||
|
bool isExpanded() { return _expanded; }
|
||||||
|
|
||||||
void checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseDragStartedY, int horizontalOffset);
|
void checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseDragStartedY, int horizontalOffset);
|
||||||
void resetWidth(int width, int horizontalOffset);
|
void resetWidth(int width, int horizontalOffset);
|
||||||
void display(const float* color, int horizontalOffset, float fps, int inPacketsPerSecond, int outPacketsPerSecond,
|
void display(const float* color, int horizontalOffset, float fps, int inPacketsPerSecond, int outPacketsPerSecond,
|
||||||
|
|
|
@ -47,7 +47,7 @@ void LocalModelsOverlay::render(RenderArgs* args) {
|
||||||
Application* app = Application::getInstance();
|
Application* app = Application::getInstance();
|
||||||
glm::vec3 oldTranslation = app->getViewMatrixTranslation();
|
glm::vec3 oldTranslation = app->getViewMatrixTranslation();
|
||||||
app->setViewMatrixTranslation(oldTranslation + _position);
|
app->setViewMatrixTranslation(oldTranslation + _position);
|
||||||
_entityTreeRenderer->render();
|
_entityTreeRenderer->render(args);
|
||||||
Application::getInstance()->setViewMatrixTranslation(oldTranslation);
|
Application::getInstance()->setViewMatrixTranslation(oldTranslation);
|
||||||
} glPopMatrix();
|
} glPopMatrix();
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
|
|
||||||
#include <GlowEffect.h>
|
#include <GlowEffect.h>
|
||||||
|
|
||||||
#include "../../Menu.h"
|
|
||||||
|
|
||||||
#include "ModelOverlay.h"
|
#include "ModelOverlay.h"
|
||||||
|
|
||||||
ModelOverlay::ModelOverlay()
|
ModelOverlay::ModelOverlay()
|
||||||
|
@ -68,7 +66,7 @@ void ModelOverlay::render(RenderArgs* args) {
|
||||||
if (glowLevel > 0.0f) {
|
if (glowLevel > 0.0f) {
|
||||||
glower = new Glower(glowLevel);
|
glower = new Glower(glowLevel);
|
||||||
}
|
}
|
||||||
_model.render(getAlpha(), RenderArgs::DEFAULT_RENDER_MODE, args);
|
_model.render(args, getAlpha());
|
||||||
if (glower) {
|
if (glower) {
|
||||||
delete glower;
|
delete glower;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,34 +82,27 @@ void Overlays::update(float deltatime) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::renderHUD() {
|
void Overlays::renderHUD(RenderArgs* renderArgs) {
|
||||||
QReadLocker lock(&_lock);
|
QReadLocker lock(&_lock);
|
||||||
|
|
||||||
auto lodManager = DependencyManager::get<LODManager>();
|
auto lodManager = DependencyManager::get<LODManager>();
|
||||||
RenderArgs args(NULL, Application::getInstance()->getViewFrustum(),
|
|
||||||
lodManager->getOctreeSizeScale(),
|
|
||||||
lodManager->getBoundaryLevelAdjust(),
|
|
||||||
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
|
||||||
|
|
||||||
foreach(Overlay* thisOverlay, _overlaysHUD) {
|
foreach(Overlay* thisOverlay, _overlaysHUD) {
|
||||||
if (thisOverlay->is3D()) {
|
if (thisOverlay->is3D()) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
thisOverlay->render(&args);
|
thisOverlay->render(renderArgs);
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
} else{
|
} else{
|
||||||
thisOverlay->render(&args);
|
thisOverlay->render(renderArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::renderWorld(bool drawFront,
|
void Overlays::renderWorld(RenderArgs* renderArgs, bool drawFront) {
|
||||||
RenderArgs::RenderMode renderMode,
|
|
||||||
RenderArgs::RenderSide renderSide,
|
|
||||||
RenderArgs::DebugFlags renderDebugFlags) {
|
|
||||||
QReadLocker lock(&_lock);
|
QReadLocker lock(&_lock);
|
||||||
if (_overlaysWorld.size() == 0) {
|
if (_overlaysWorld.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -123,11 +116,6 @@ void Overlays::renderWorld(bool drawFront,
|
||||||
float myAvatarScale = 1.0f;
|
float myAvatarScale = 1.0f;
|
||||||
|
|
||||||
auto lodManager = DependencyManager::get<LODManager>();
|
auto lodManager = DependencyManager::get<LODManager>();
|
||||||
RenderArgs args(NULL, Application::getInstance()->getDisplayViewFrustum(),
|
|
||||||
lodManager->getOctreeSizeScale(),
|
|
||||||
lodManager->getBoundaryLevelAdjust(),
|
|
||||||
renderMode, renderSide, renderDebugFlags);
|
|
||||||
|
|
||||||
|
|
||||||
foreach(Overlay* thisOverlay, _overlaysWorld) {
|
foreach(Overlay* thisOverlay, _overlaysWorld) {
|
||||||
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay);
|
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay);
|
||||||
|
@ -154,7 +142,7 @@ void Overlays::renderWorld(bool drawFront,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
thisOverlay->render(&args);
|
thisOverlay->render(renderArgs);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,8 @@ public:
|
||||||
~Overlays();
|
~Overlays();
|
||||||
void init();
|
void init();
|
||||||
void update(float deltatime);
|
void update(float deltatime);
|
||||||
void renderWorld(bool drawFront, RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE,
|
void renderWorld(RenderArgs* renderArgs, bool drawFront);
|
||||||
RenderArgs::RenderSide renderSide = RenderArgs::MONO,
|
void renderHUD(RenderArgs* renderArgs);
|
||||||
RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE);
|
|
||||||
void renderHUD();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// adds an overlay with the specific properties
|
/// adds an overlay with the specific properties
|
||||||
|
|
|
@ -69,6 +69,7 @@ const quint32 AVATAR_MOTION_DEFAULTS =
|
||||||
const quint32 AVATAR_MOTION_SCRIPTABLE_BITS =
|
const quint32 AVATAR_MOTION_SCRIPTABLE_BITS =
|
||||||
AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED;
|
AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED;
|
||||||
|
|
||||||
|
const qint64 AVATAR_SILENCE_THRESHOLD_USECS = 5 * USECS_PER_SECOND;
|
||||||
|
|
||||||
// Bitset of state flags - we store the key state, hand state, faceshift, chat circling, and existance of
|
// Bitset of state flags - we store the key state, hand state, faceshift, chat circling, and existance of
|
||||||
// referential data in this bit set. The hand state is an octal, but is split into two sections to maintain
|
// referential data in this bit set. The hand state is an octal, but is split into two sections to maintain
|
||||||
|
@ -290,7 +291,6 @@ public:
|
||||||
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
|
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
|
||||||
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
|
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
|
||||||
|
|
||||||
Node* getOwningAvatarMixer() { return _owningAvatarMixer.data(); }
|
|
||||||
void setOwningAvatarMixer(const QWeakPointer<Node>& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; }
|
void setOwningAvatarMixer(const QWeakPointer<Node>& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; }
|
||||||
|
|
||||||
const AABox& getLocalAABox() const { return _localAABox; }
|
const AABox& getLocalAABox() const { return _localAABox; }
|
||||||
|
@ -301,8 +301,10 @@ public:
|
||||||
int getReceiveRate() const;
|
int getReceiveRate() const;
|
||||||
|
|
||||||
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
|
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
|
||||||
Q_INVOKABLE glm::vec3 getVelocity() const { return _velocity; }
|
Q_INVOKABLE const glm::vec3& getVelocity() const { return _velocity; }
|
||||||
glm::vec3 getTargetVelocity() const { return _targetVelocity; }
|
const glm::vec3& getTargetVelocity() const { return _targetVelocity; }
|
||||||
|
|
||||||
|
bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void sendAvatarDataPacket();
|
void sendAvatarDataPacket();
|
||||||
|
|
|
@ -20,19 +20,6 @@ AvatarHashMap::AvatarHashMap() {
|
||||||
connect(DependencyManager::get<NodeList>().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged);
|
connect(DependencyManager::get<NodeList>().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator) {
|
|
||||||
qCDebug(avatars) << "Removing Avatar with UUID" << iterator.key() << "from AvatarHashMap.";
|
|
||||||
return _avatarHash.erase(iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
const qint64 AVATAR_SILENCE_THRESHOLD_USECS = 5 * USECS_PER_SECOND;
|
|
||||||
|
|
||||||
bool AvatarHashMap::shouldKillAvatar(const AvatarSharedPointer& sharedAvatar) {
|
|
||||||
return (sharedAvatar->getOwningAvatarMixer() == NULL
|
|
||||||
|| sharedAvatar->getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
|
void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||||
switch (packetTypeForPacket(datagram)) {
|
switch (packetTypeForPacket(datagram)) {
|
||||||
case PacketTypeBulkAvatarData:
|
case PacketTypeBulkAvatarData:
|
||||||
|
@ -52,10 +39,6 @@ void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvatarHashMap::containsAvatarWithDisplayName(const QString& displayName) {
|
|
||||||
return !avatarWithDisplayName(displayName).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) {
|
bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) {
|
||||||
foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) {
|
foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) {
|
||||||
glm::vec3 avatarPosition = sharedAvatar->getPosition();
|
glm::vec3 avatarPosition = sharedAvatar->getPosition();
|
||||||
|
@ -67,45 +50,19 @@ bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarWeakPointer AvatarHashMap::avatarWithDisplayName(const QString& displayName) {
|
|
||||||
foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) {
|
|
||||||
if (sharedAvatar->getDisplayName() == displayName) {
|
|
||||||
// this is a match
|
|
||||||
// check if this avatar should still be around
|
|
||||||
if (!shouldKillAvatar(sharedAvatar)) {
|
|
||||||
// we have a match, return the AvatarData
|
|
||||||
return sharedAvatar;
|
|
||||||
} else {
|
|
||||||
// we should remove this avatar, but we might not be on a thread that is allowed
|
|
||||||
// so we just return NULL to the caller
|
|
||||||
return AvatarWeakPointer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return AvatarWeakPointer();
|
|
||||||
}
|
|
||||||
|
|
||||||
AvatarSharedPointer AvatarHashMap::newSharedAvatar() {
|
AvatarSharedPointer AvatarHashMap::newSharedAvatar() {
|
||||||
return AvatarSharedPointer(new AvatarData());
|
return AvatarSharedPointer(new AvatarData());
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarSharedPointer AvatarHashMap::matchingOrNewAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||||
AvatarSharedPointer matchingAvatar = _avatarHash.value(sessionUUID);
|
qCDebug(avatars) << "Adding avatar with sessionUUID " << sessionUUID << "to AvatarHashMap.";
|
||||||
|
|
||||||
if (!matchingAvatar) {
|
AvatarSharedPointer avatar = newSharedAvatar();
|
||||||
// insert the new avatar into our hash
|
avatar->setSessionUUID(sessionUUID);
|
||||||
matchingAvatar = newSharedAvatar();
|
avatar->setOwningAvatarMixer(mixerWeakPointer);
|
||||||
|
_avatarHash.insert(sessionUUID, avatar);
|
||||||
qCDebug(avatars) << "Adding avatar with sessionUUID " << sessionUUID << "to AvatarHashMap.";
|
|
||||||
|
return avatar;
|
||||||
matchingAvatar->setSessionUUID(sessionUUID);
|
|
||||||
matchingAvatar->setOwningAvatarMixer(mixerWeakPointer);
|
|
||||||
|
|
||||||
_avatarHash.insert(sessionUUID, matchingAvatar);
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchingAvatar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer<Node> &mixerWeakPointer) {
|
void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer<Node> &mixerWeakPointer) {
|
||||||
|
@ -118,10 +75,13 @@ void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QW
|
||||||
bytesRead += NUM_BYTES_RFC4122_UUID;
|
bytesRead += NUM_BYTES_RFC4122_UUID;
|
||||||
|
|
||||||
if (sessionUUID != _lastOwnerSessionUUID) {
|
if (sessionUUID != _lastOwnerSessionUUID) {
|
||||||
AvatarSharedPointer matchingAvatarData = matchingOrNewAvatar(sessionUUID, mixerWeakPointer);
|
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
|
||||||
|
if (!avatar) {
|
||||||
|
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
||||||
|
}
|
||||||
|
|
||||||
// have the matching (or new) avatar parse the data from the packet
|
// have the matching (or new) avatar parse the data from the packet
|
||||||
bytesRead += matchingAvatarData->parseDataAtOffset(datagram, bytesRead);
|
bytesRead += avatar->parseDataAtOffset(datagram, bytesRead);
|
||||||
} else {
|
} else {
|
||||||
// create a dummy AvatarData class to throw this data on the ground
|
// create a dummy AvatarData class to throw this data on the ground
|
||||||
AvatarData dummyData;
|
AvatarData dummyData;
|
||||||
|
@ -145,24 +105,24 @@ void AvatarHashMap::processAvatarIdentityPacket(const QByteArray &packet, const
|
||||||
identityStream >> sessionUUID >> faceMeshURL >> skeletonURL >> attachmentData >> displayName;
|
identityStream >> sessionUUID >> faceMeshURL >> skeletonURL >> attachmentData >> displayName;
|
||||||
|
|
||||||
// mesh URL for a UUID, find avatar in our list
|
// mesh URL for a UUID, find avatar in our list
|
||||||
AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer);
|
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
|
||||||
if (matchingAvatar) {
|
if (!avatar) {
|
||||||
|
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
||||||
if (matchingAvatar->getFaceModelURL() != faceMeshURL) {
|
}
|
||||||
matchingAvatar->setFaceModelURL(faceMeshURL);
|
if (avatar->getFaceModelURL() != faceMeshURL) {
|
||||||
}
|
avatar->setFaceModelURL(faceMeshURL);
|
||||||
|
}
|
||||||
if (matchingAvatar->getSkeletonModelURL() != skeletonURL) {
|
|
||||||
matchingAvatar->setSkeletonModelURL(skeletonURL);
|
if (avatar->getSkeletonModelURL() != skeletonURL) {
|
||||||
}
|
avatar->setSkeletonModelURL(skeletonURL);
|
||||||
|
}
|
||||||
if (matchingAvatar->getAttachmentData() != attachmentData) {
|
|
||||||
matchingAvatar->setAttachmentData(attachmentData);
|
if (avatar->getAttachmentData() != attachmentData) {
|
||||||
}
|
avatar->setAttachmentData(attachmentData);
|
||||||
|
}
|
||||||
if (matchingAvatar->getDisplayName() != displayName) {
|
|
||||||
matchingAvatar->setDisplayName(displayName);
|
if (avatar->getDisplayName() != displayName) {
|
||||||
}
|
avatar->setDisplayName(displayName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,24 +131,25 @@ void AvatarHashMap::processAvatarBillboardPacket(const QByteArray& packet, const
|
||||||
int headerSize = numBytesForPacketHeader(packet);
|
int headerSize = numBytesForPacketHeader(packet);
|
||||||
QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.constData() + headerSize, NUM_BYTES_RFC4122_UUID));
|
QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.constData() + headerSize, NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer);
|
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
|
||||||
if (matchingAvatar) {
|
if (!avatar) {
|
||||||
QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID);
|
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
||||||
if (matchingAvatar->getBillboard() != billboard) {
|
}
|
||||||
matchingAvatar->setBillboard(billboard);
|
|
||||||
}
|
QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID);
|
||||||
|
if (avatar->getBillboard() != billboard) {
|
||||||
|
avatar->setBillboard(billboard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarHashMap::processKillAvatar(const QByteArray& datagram) {
|
void AvatarHashMap::processKillAvatar(const QByteArray& datagram) {
|
||||||
// read the node id
|
// read the node id
|
||||||
QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID));
|
QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID));
|
||||||
|
removeAvatar(sessionUUID);
|
||||||
// remove the avatar with that UUID from our hash, if it exists
|
}
|
||||||
AvatarHash::iterator matchedAvatar = _avatarHash.find(sessionUUID);
|
|
||||||
if (matchedAvatar != _avatarHash.end()) {
|
void AvatarHashMap::removeAvatar(const QUuid& sessionUUID) {
|
||||||
erase(matchedAvatar);
|
_avatarHash.remove(sessionUUID);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarHashMap::sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID) {
|
void AvatarHashMap::sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID) {
|
||||||
|
|
|
@ -36,28 +36,26 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer);
|
void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer);
|
||||||
bool containsAvatarWithDisplayName(const QString& displayName);
|
|
||||||
bool isAvatarInRange(const glm::vec3 & position, const float range);
|
bool isAvatarInRange(const glm::vec3 & position, const float range);
|
||||||
AvatarWeakPointer avatarWithDisplayName(const QString& displayname);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
|
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AvatarHashMap();
|
AvatarHashMap();
|
||||||
virtual AvatarHash::iterator erase(const AvatarHash::iterator& iterator);
|
|
||||||
|
|
||||||
bool shouldKillAvatar(const AvatarSharedPointer& sharedAvatar);
|
|
||||||
|
|
||||||
virtual AvatarSharedPointer newSharedAvatar();
|
virtual AvatarSharedPointer newSharedAvatar();
|
||||||
AvatarSharedPointer matchingOrNewAvatar(const QUuid& nodeUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
||||||
|
virtual void removeAvatar(const QUuid& sessionUUID);
|
||||||
|
|
||||||
|
AvatarHash _avatarHash;
|
||||||
|
|
||||||
|
private:
|
||||||
void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
||||||
void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
||||||
void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
||||||
void processKillAvatar(const QByteArray& datagram);
|
void processKillAvatar(const QByteArray& datagram);
|
||||||
|
|
||||||
AvatarHash _avatarHash;
|
|
||||||
QUuid _lastOwnerSessionUUID;
|
QUuid _lastOwnerSessionUUID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ void EntityTreeRenderer::errorInLoadingScript(const QUrl& url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItemID, bool isPreload) {
|
QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItemID, bool isPreload) {
|
||||||
EntityItem* entity = static_cast<EntityTree*>(_tree)->findEntityByEntityItemID(entityItemID);
|
EntityItemPointer entity = static_cast<EntityTree*>(_tree)->findEntityByEntityItemID(entityItemID);
|
||||||
return loadEntityScript(entity, isPreload);
|
return loadEntityScript(entity, isPreload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorTe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPreload) {
|
QScriptValue EntityTreeRenderer::loadEntityScript(EntityItemPointer entity, bool isPreload) {
|
||||||
if (_shuttingDown) {
|
if (_shuttingDown) {
|
||||||
return QScriptValue(); // since we're shutting down, we don't load any more scripts
|
return QScriptValue(); // since we're shutting down, we don't load any more scripts
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||||
|
|
||||||
if (avatarPosition != _lastAvatarPosition) {
|
if (avatarPosition != _lastAvatarPosition) {
|
||||||
float radius = 1.0f; // for now, assume 1 meter radius
|
float radius = 1.0f; // for now, assume 1 meter radius
|
||||||
QVector<const EntityItem*> foundEntities;
|
QVector<EntityItemPointer> foundEntities;
|
||||||
QVector<EntityItemID> entitiesContainingAvatar;
|
QVector<EntityItemID> entitiesContainingAvatar;
|
||||||
|
|
||||||
// find the entities near us
|
// find the entities near us
|
||||||
|
@ -333,7 +333,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||||
static_cast<EntityTree*>(_tree)->findEntities(avatarPosition, radius, foundEntities);
|
static_cast<EntityTree*>(_tree)->findEntities(avatarPosition, radius, foundEntities);
|
||||||
|
|
||||||
// create a list of entities that actually contain the avatar's position
|
// create a list of entities that actually contain the avatar's position
|
||||||
foreach(const EntityItem* entity, foundEntities) {
|
foreach(EntityItemPointer entity, foundEntities) {
|
||||||
if (entity->contains(avatarPosition)) {
|
if (entity->contains(avatarPosition)) {
|
||||||
entitiesContainingAvatar << entity->getEntityItemID();
|
entitiesContainingAvatar << entity->getEntityItemID();
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ void EntityTreeRenderer::leaveAllEntities() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::applyZonePropertiesToScene(const ZoneEntityItem* zone) {
|
void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone) {
|
||||||
QSharedPointer<SceneScriptingInterface> scene = DependencyManager::get<SceneScriptingInterface>();
|
QSharedPointer<SceneScriptingInterface> scene = DependencyManager::get<SceneScriptingInterface>();
|
||||||
if (zone) {
|
if (zone) {
|
||||||
if (!_hasPreviousZone) {
|
if (!_hasPreviousZone) {
|
||||||
|
@ -474,13 +474,11 @@ void EntityTreeRenderer::applyZonePropertiesToScene(const ZoneEntityItem* zone)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
void EntityTreeRenderer::render(RenderArgs* renderArgs) {
|
||||||
RenderArgs::RenderSide renderSide,
|
|
||||||
RenderArgs::DebugFlags renderDebugFlags) {
|
|
||||||
if (_tree && !_shuttingDown) {
|
if (_tree && !_shuttingDown) {
|
||||||
Model::startScene(renderSide);
|
Model::startScene(renderArgs->_renderSide);
|
||||||
|
|
||||||
ViewFrustum* frustum = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
ViewFrustum* frustum = (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||||
_viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum();
|
_viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum();
|
||||||
|
|
||||||
// Setup batch transform matrices
|
// Setup batch transform matrices
|
||||||
|
@ -492,54 +490,54 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
RenderArgs args(this, frustum, getSizeScale(), getBoundaryLevelAdjust(),
|
renderArgs->_renderer = this;
|
||||||
renderMode, renderSide, renderDebugFlags, &batch);
|
renderArgs->_batch = &batch;
|
||||||
|
|
||||||
_tree->lockForRead();
|
_tree->lockForRead();
|
||||||
|
|
||||||
// Whenever you're in an intersection between zones, we will always choose the smallest zone.
|
// Whenever you're in an intersection between zones, we will always choose the smallest zone.
|
||||||
_bestZone = NULL;
|
_bestZone = NULL; // NOTE: Is this what we want?
|
||||||
_bestZoneVolume = std::numeric_limits<float>::max();
|
_bestZoneVolume = std::numeric_limits<float>::max();
|
||||||
_tree->recurseTreeWithOperation(renderOperation, &args);
|
_tree->recurseTreeWithOperation(renderOperation, renderArgs);
|
||||||
|
|
||||||
applyZonePropertiesToScene(_bestZone);
|
applyZonePropertiesToScene(_bestZone);
|
||||||
|
|
||||||
// we must call endScene while we still have the tree locked so that no one deletes a model
|
// we must call endScene while we still have the tree locked so that no one deletes a model
|
||||||
// on us while rendering the scene
|
// on us while rendering the scene
|
||||||
Model::endScene(renderMode, &args);
|
Model::endScene(renderArgs);
|
||||||
_tree->unlock();
|
_tree->unlock();
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
gpu::GLBackend::renderBatch(batch, true);
|
renderArgs->_context->enqueueBatch(batch);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
// stats...
|
// stats...
|
||||||
_meshesConsidered = args._meshesConsidered;
|
_meshesConsidered = renderArgs->_meshesConsidered;
|
||||||
_meshesRendered = args._meshesRendered;
|
_meshesRendered = renderArgs->_meshesRendered;
|
||||||
_meshesOutOfView = args._meshesOutOfView;
|
_meshesOutOfView = renderArgs->_meshesOutOfView;
|
||||||
_meshesTooSmall = args._meshesTooSmall;
|
_meshesTooSmall = renderArgs->_meshesTooSmall;
|
||||||
|
|
||||||
_elementsTouched = args._elementsTouched;
|
_elementsTouched = renderArgs->_elementsTouched;
|
||||||
_itemsRendered = args._itemsRendered;
|
_itemsRendered = renderArgs->_itemsRendered;
|
||||||
_itemsOutOfView = args._itemsOutOfView;
|
_itemsOutOfView = renderArgs->_itemsOutOfView;
|
||||||
_itemsTooSmall = args._itemsTooSmall;
|
_itemsTooSmall = renderArgs->_itemsTooSmall;
|
||||||
|
|
||||||
_materialSwitches = args._materialSwitches;
|
_materialSwitches = renderArgs->_materialSwitches;
|
||||||
_trianglesRendered = args._trianglesRendered;
|
_trianglesRendered = renderArgs->_trianglesRendered;
|
||||||
_quadsRendered = args._quadsRendered;
|
_quadsRendered = renderArgs->_quadsRendered;
|
||||||
|
|
||||||
_translucentMeshPartsRendered = args._translucentMeshPartsRendered;
|
_translucentMeshPartsRendered = renderArgs->_translucentMeshPartsRendered;
|
||||||
_opaqueMeshPartsRendered = args._opaqueMeshPartsRendered;
|
_opaqueMeshPartsRendered = renderArgs->_opaqueMeshPartsRendered;
|
||||||
}
|
}
|
||||||
deleteReleasedModels(); // seems like as good as any other place to do some memory cleanup
|
deleteReleasedModels(); // seems like as good as any other place to do some memory cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(const EntityItem* entityItem) {
|
const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) {
|
||||||
const FBXGeometry* result = NULL;
|
const FBXGeometry* result = NULL;
|
||||||
|
|
||||||
if (entityItem->getType() == EntityTypes::Model) {
|
if (entityItem->getType() == EntityTypes::Model) {
|
||||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||||
assert(modelEntityItem); // we need this!!!
|
assert(modelEntityItem); // we need this!!!
|
||||||
Model* model = modelEntityItem->getModel(this);
|
Model* model = modelEntityItem->getModel(this);
|
||||||
if (model) {
|
if (model) {
|
||||||
|
@ -549,23 +547,23 @@ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(const EntityItem* en
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Model* EntityTreeRenderer::getModelForEntityItem(const EntityItem* entityItem) {
|
const Model* EntityTreeRenderer::getModelForEntityItem(EntityItemPointer entityItem) {
|
||||||
const Model* result = NULL;
|
const Model* result = NULL;
|
||||||
if (entityItem->getType() == EntityTypes::Model) {
|
if (entityItem->getType() == EntityTypes::Model) {
|
||||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||||
result = modelEntityItem->getModel(this);
|
result = modelEntityItem->getModel(this);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(const EntityItem* entityItem) {
|
const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemPointer entityItem) {
|
||||||
const FBXGeometry* result = NULL;
|
const FBXGeometry* result = NULL;
|
||||||
|
|
||||||
if (entityItem->getType() == EntityTypes::Model) {
|
if (entityItem->getType() == EntityTypes::Model) {
|
||||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||||
if (constModelEntityItem->hasCompoundShapeURL()) {
|
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
if (modelEntityItem->hasCompoundShapeURL()) {
|
||||||
Model* model = modelEntityItem->getModel(this);
|
Model* model = modelEntityItem->getModel(this);
|
||||||
if (model) {
|
if (model) {
|
||||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = model->getCollisionGeometry();
|
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = model->getCollisionGeometry();
|
||||||
|
@ -611,7 +609,7 @@ void EntityTreeRenderer::renderElementProxy(EntityTreeElement* entityTreeElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* args) {
|
void EntityTreeRenderer::renderProxies(EntityItemPointer entity, RenderArgs* args) {
|
||||||
bool isShadowMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE;
|
bool isShadowMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE;
|
||||||
if (!isShadowMode && _displayModelBounds) {
|
if (!isShadowMode && _displayModelBounds) {
|
||||||
PerformanceTimer perfTimer("renderProxies");
|
PerformanceTimer perfTimer("renderProxies");
|
||||||
|
@ -658,7 +656,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
||||||
// we need to iterate the actual entityItems of the element
|
// we need to iterate the actual entityItems of the element
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
|
|
||||||
QList<EntityItem*>& entityItems = entityTreeElement->getEntities();
|
EntityItems& entityItems = entityTreeElement->getEntities();
|
||||||
|
|
||||||
|
|
||||||
uint16_t numberOfEntities = entityItems.size();
|
uint16_t numberOfEntities = entityItems.size();
|
||||||
|
@ -670,7 +668,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||||
EntityItem* entityItem = entityItems[i];
|
EntityItemPointer entityItem = entityItems[i];
|
||||||
|
|
||||||
if (entityItem->isVisible()) {
|
if (entityItem->isVisible()) {
|
||||||
|
|
||||||
|
@ -680,17 +678,17 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
||||||
float entityVolumeEstimate = entityItem->getVolumeEstimate();
|
float entityVolumeEstimate = entityItem->getVolumeEstimate();
|
||||||
if (entityVolumeEstimate < _bestZoneVolume) {
|
if (entityVolumeEstimate < _bestZoneVolume) {
|
||||||
_bestZoneVolume = entityVolumeEstimate;
|
_bestZoneVolume = entityVolumeEstimate;
|
||||||
_bestZone = dynamic_cast<const ZoneEntityItem*>(entityItem);
|
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
||||||
} else if (entityVolumeEstimate == _bestZoneVolume) {
|
} else if (entityVolumeEstimate == _bestZoneVolume) {
|
||||||
if (!_bestZone) {
|
if (!_bestZone) {
|
||||||
_bestZoneVolume = entityVolumeEstimate;
|
_bestZoneVolume = entityVolumeEstimate;
|
||||||
_bestZone = dynamic_cast<const ZoneEntityItem*>(entityItem);
|
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
||||||
} else {
|
} else {
|
||||||
// in the case of the volume being equal, we will use the
|
// in the case of the volume being equal, we will use the
|
||||||
// EntityItemID to deterministically pick one entity over the other
|
// EntityItemID to deterministically pick one entity over the other
|
||||||
if (entityItem->getEntityItemID() < _bestZone->getEntityItemID()) {
|
if (entityItem->getEntityItemID() < _bestZone->getEntityItemID()) {
|
||||||
_bestZoneVolume = entityVolumeEstimate;
|
_bestZoneVolume = entityVolumeEstimate;
|
||||||
_bestZone = dynamic_cast<const ZoneEntityItem*>(entityItem);
|
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -713,7 +711,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
||||||
|
|
||||||
Glower* glower = NULL;
|
Glower* glower = NULL;
|
||||||
if (entityItem->getGlowLevel() > 0.0f) {
|
if (entityItem->getGlowLevel() > 0.0f) {
|
||||||
glower = new Glower(entityItem->getGlowLevel());
|
glower = new Glower(args, entityItem->getGlowLevel());
|
||||||
}
|
}
|
||||||
entityItem->render(args);
|
entityItem->render(args);
|
||||||
args->_itemsRendered++;
|
args->_itemsRendered++;
|
||||||
|
@ -819,7 +817,7 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons
|
||||||
EntityTree* entityTree = static_cast<EntityTree*>(_tree);
|
EntityTree* entityTree = static_cast<EntityTree*>(_tree);
|
||||||
|
|
||||||
OctreeElement* element;
|
OctreeElement* element;
|
||||||
EntityItem* intersectedEntity = NULL;
|
EntityItemPointer intersectedEntity = NULL;
|
||||||
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
(void**)&intersectedEntity, lockType, &result.accurate,
|
||||||
precisionPicking);
|
precisionPicking);
|
||||||
|
@ -1094,7 +1092,7 @@ void EntityTreeRenderer::changingEntityID(const EntityItemID& oldEntityID, const
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityTree* entityTree, const EntityItemID& id, const Collision& collision) {
|
void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityTree* entityTree, const EntityItemID& id, const Collision& collision) {
|
||||||
EntityItem* entity = entityTree->findEntityByEntityItemID(id);
|
EntityItemPointer entity = entityTree->findEntityByEntityItemID(id);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1159,7 +1157,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Don't respond to small continuous contacts.
|
// Don't respond to small continuous contacts.
|
||||||
const float COLLISION_MINUMUM_PENETRATION = 0.005;
|
const float COLLISION_MINUMUM_PENETRATION = 0.005f;
|
||||||
if ((collision.type != CONTACT_EVENT_TYPE_START) && (glm::length(collision.penetration) < COLLISION_MINUMUM_PENETRATION)) {
|
if ((collision.type != CONTACT_EVENT_TYPE_START) && (glm::length(collision.penetration) < COLLISION_MINUMUM_PENETRATION)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,13 +59,11 @@ public:
|
||||||
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE,
|
virtual void render(RenderArgs* renderArgs) override;
|
||||||
RenderArgs::RenderSide renderSide = RenderArgs::MONO,
|
|
||||||
RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE);
|
|
||||||
|
|
||||||
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem);
|
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem);
|
||||||
virtual const Model* getModelForEntityItem(const EntityItem* entityItem);
|
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem);
|
||||||
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem);
|
virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem);
|
||||||
|
|
||||||
/// clears the tree
|
/// clears the tree
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
@ -126,13 +124,13 @@ protected:
|
||||||
virtual Octree* createTree() { return new EntityTree(true); }
|
virtual Octree* createTree() { return new EntityTree(true); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void applyZonePropertiesToScene(const ZoneEntityItem* zone);
|
void applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone);
|
||||||
void renderElementProxy(EntityTreeElement* entityTreeElement, RenderArgs* args);
|
void renderElementProxy(EntityTreeElement* entityTreeElement, RenderArgs* args);
|
||||||
void checkAndCallPreload(const EntityItemID& entityID);
|
void checkAndCallPreload(const EntityItemID& entityID);
|
||||||
void checkAndCallUnload(const EntityItemID& entityID);
|
void checkAndCallUnload(const EntityItemID& entityID);
|
||||||
|
|
||||||
QList<Model*> _releasedModels;
|
QList<Model*> _releasedModels;
|
||||||
void renderProxies(const EntityItem* entity, RenderArgs* args);
|
void renderProxies(EntityItemPointer entity, RenderArgs* args);
|
||||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||||
bool precisionPicking);
|
bool precisionPicking);
|
||||||
|
|
||||||
|
@ -149,7 +147,7 @@ private:
|
||||||
ScriptEngine* _entitiesScriptEngine;
|
ScriptEngine* _entitiesScriptEngine;
|
||||||
ScriptEngine* _sandboxScriptEngine;
|
ScriptEngine* _sandboxScriptEngine;
|
||||||
|
|
||||||
QScriptValue loadEntityScript(EntityItem* entity, bool isPreload = false);
|
QScriptValue loadEntityScript(EntityItemPointer entity, bool isPreload = false);
|
||||||
QScriptValue loadEntityScript(const EntityItemID& entityItemID, bool isPreload = false);
|
QScriptValue loadEntityScript(const EntityItemID& entityItemID, bool isPreload = false);
|
||||||
QScriptValue getPreviouslyLoadedEntityScript(const EntityItemID& entityItemID);
|
QScriptValue getPreviouslyLoadedEntityScript(const EntityItemID& entityItemID);
|
||||||
QString loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL, bool& isPending, QUrl& url);
|
QString loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL, bool& isPending, QUrl& url);
|
||||||
|
@ -175,7 +173,7 @@ private:
|
||||||
QMultiMap<QUrl, EntityItemID> _waitingOnPreload;
|
QMultiMap<QUrl, EntityItemID> _waitingOnPreload;
|
||||||
|
|
||||||
bool _hasPreviousZone = false;
|
bool _hasPreviousZone = false;
|
||||||
const ZoneEntityItem* _bestZone;
|
std::shared_ptr<ZoneEntityItem> _bestZone;
|
||||||
float _bestZoneVolume;
|
float _bestZoneVolume;
|
||||||
|
|
||||||
glm::vec3 _previousKeyLightColor;
|
glm::vec3 _previousKeyLightColor;
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
#include "RenderableBoxEntityItem.h"
|
#include "RenderableBoxEntityItem.h"
|
||||||
|
|
||||||
EntityItem* RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableBoxEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableBoxEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableBoxEntityItem::render(RenderArgs* args) {
|
void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class RenderableBoxEntityItem : public BoxEntityItem {
|
class RenderableBoxEntityItem : public BoxEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableBoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableBoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
BoxEntityItem(entityItemID, properties)
|
BoxEntityItem(entityItemID, properties)
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#include "RenderableLightEntityItem.h"
|
#include "RenderableLightEntityItem.h"
|
||||||
|
|
||||||
EntityItem* RenderableLightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableLightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableLightEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableLightEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableLightEntityItem::render(RenderArgs* args) {
|
void RenderableLightEntityItem::render(RenderArgs* args) {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class RenderableLightEntityItem : public LightEntityItem {
|
class RenderableLightEntityItem : public LightEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableLightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableLightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
LightEntityItem(entityItemID, properties)
|
LightEntityItem(entityItemID, properties)
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
#include "RenderableLineEntityItem.h"
|
#include "RenderableLineEntityItem.h"
|
||||||
|
|
||||||
EntityItem* RenderableLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableLineEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableLineEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableLineEntityItem::render(RenderArgs* args) {
|
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||||
|
@ -29,7 +29,6 @@ void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||||
glm::vec3 p1 = ENTITY_ITEM_ZERO_VEC3;
|
glm::vec3 p1 = ENTITY_ITEM_ZERO_VEC3;
|
||||||
glm::vec3 p2 = getDimensions();
|
glm::vec3 p2 = getDimensions();
|
||||||
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
|
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||||
|
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
batch.setModelTransform(getTransformToCenter());
|
batch.setModelTransform(getTransformToCenter());
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class RenderableLineEntityItem : public LineEntityItem {
|
class RenderableLineEntityItem : public LineEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
LineEntityItem(entityItemID, properties) { }
|
LineEntityItem(entityItemID, properties) { }
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
#include "EntitiesRendererLogging.h"
|
#include "EntitiesRendererLogging.h"
|
||||||
#include "RenderableModelEntityItem.h"
|
#include "RenderableModelEntityItem.h"
|
||||||
|
|
||||||
EntityItem* RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableModelEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableModelEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderableModelEntityItem::~RenderableModelEntityItem() {
|
RenderableModelEntityItem::~RenderableModelEntityItem() {
|
||||||
|
|
|
@ -23,7 +23,7 @@ class EntityTreeRenderer;
|
||||||
|
|
||||||
class RenderableModelEntityItem : public ModelEntityItem {
|
class RenderableModelEntityItem : public ModelEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
ModelEntityItem(entityItemID, properties),
|
ModelEntityItem(entityItemID, properties),
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#include "RenderableParticleEffectEntityItem.h"
|
#include "RenderableParticleEffectEntityItem.h"
|
||||||
|
|
||||||
EntityItem* RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableParticleEffectEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableParticleEffectEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class RenderableParticleEffectEntityItem : public ParticleEffectEntityItem {
|
class RenderableParticleEffectEntityItem : public ParticleEffectEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#include "RenderableSphereEntityItem.h"
|
#include "RenderableSphereEntityItem.h"
|
||||||
|
|
||||||
EntityItem* RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableSphereEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableSphereEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableSphereEntityItem::render(RenderArgs* args) {
|
void RenderableSphereEntityItem::render(RenderArgs* args) {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class RenderableSphereEntityItem : public SphereEntityItem {
|
class RenderableSphereEntityItem : public SphereEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableSphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableSphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
SphereEntityItem(entityItemID, properties)
|
SphereEntityItem(entityItemID, properties)
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
#include "GLMHelpers.h"
|
#include "GLMHelpers.h"
|
||||||
|
|
||||||
|
|
||||||
EntityItem* RenderableTextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableTextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableTextEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableTextEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableTextEntityItem::render(RenderArgs* args) {
|
void RenderableTextEntityItem::render(RenderArgs* args) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ const int FIXED_FONT_POINT_SIZE = 40;
|
||||||
|
|
||||||
class RenderableTextEntityItem : public TextEntityItem {
|
class RenderableTextEntityItem : public TextEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableTextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableTextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
TextEntityItem(entityItemID, properties)
|
TextEntityItem(entityItemID, properties)
|
||||||
|
|
|
@ -25,11 +25,11 @@
|
||||||
|
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
|
|
||||||
const float DPI = 30.47;
|
const float DPI = 30.47f;
|
||||||
const float METERS_TO_INCHES = 39.3701;
|
const float METERS_TO_INCHES = 39.3701f;
|
||||||
|
|
||||||
EntityItem* RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableWebEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableWebEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
|
|
|
@ -17,7 +17,7 @@ class OffscreenQmlSurface;
|
||||||
|
|
||||||
class RenderableWebEntityItem : public WebEntityItem {
|
class RenderableWebEntityItem : public WebEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
~RenderableWebEntityItem();
|
~RenderableWebEntityItem();
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include <GeometryCache.h>
|
#include <GeometryCache.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
|
||||||
EntityItem* RenderableZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new RenderableZoneEntityItem(entityID, properties);
|
return EntityItemPointer(new RenderableZoneEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Lambda>
|
template<typename Lambda>
|
||||||
|
|
|
@ -19,7 +19,7 @@ class NetworkGeometry;
|
||||||
|
|
||||||
class RenderableZoneEntityItem : public ZoneEntityItem {
|
class RenderableZoneEntityItem : public ZoneEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
RenderableZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
RenderableZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
ZoneEntityItem(entityItemID, properties),
|
ZoneEntityItem(entityItemID, properties),
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "AddEntityOperator.h"
|
#include "AddEntityOperator.h"
|
||||||
|
|
||||||
AddEntityOperator::AddEntityOperator(EntityTree* tree,
|
AddEntityOperator::AddEntityOperator(EntityTree* tree,
|
||||||
EntityItem* newEntity) :
|
EntityItemPointer newEntity) :
|
||||||
_tree(tree),
|
_tree(tree),
|
||||||
_newEntity(newEntity),
|
_newEntity(newEntity),
|
||||||
_foundNew(false),
|
_foundNew(false),
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
|
|
||||||
class AddEntityOperator : public RecurseOctreeOperator {
|
class AddEntityOperator : public RecurseOctreeOperator {
|
||||||
public:
|
public:
|
||||||
AddEntityOperator(EntityTree* tree, EntityItem* newEntity);
|
AddEntityOperator(EntityTree* tree, EntityItemPointer newEntity);
|
||||||
|
|
||||||
virtual bool preRecursion(OctreeElement* element);
|
virtual bool preRecursion(OctreeElement* element);
|
||||||
virtual bool postRecursion(OctreeElement* element);
|
virtual bool postRecursion(OctreeElement* element);
|
||||||
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
||||||
private:
|
private:
|
||||||
EntityTree* _tree;
|
EntityTree* _tree;
|
||||||
EntityItem* _newEntity;
|
EntityItemPointer _newEntity;
|
||||||
bool _foundNew;
|
bool _foundNew;
|
||||||
quint64 _changeTime;
|
quint64 _changeTime;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include "EntityTreeElement.h"
|
#include "EntityTreeElement.h"
|
||||||
|
|
||||||
|
|
||||||
EntityItem* BoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer BoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItem* result = new BoxEntityItem(entityID, properties);
|
EntityItemPointer result { new BoxEntityItem(entityID, properties) };
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class BoxEntityItem : public EntityItem {
|
class BoxEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
BoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
BoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ bool DeleteEntityOperator::preRecursion(OctreeElement* element) {
|
||||||
// If this is the element we're looking for, then ask it to remove the old entity
|
// If this is the element we're looking for, then ask it to remove the old entity
|
||||||
// and we can stop searching.
|
// and we can stop searching.
|
||||||
if (entityTreeElement == details.containingElement) {
|
if (entityTreeElement == details.containingElement) {
|
||||||
EntityItem* theEntity = details.entity;
|
EntityItemPointer theEntity = details.entity;
|
||||||
bool entityDeleted = entityTreeElement->removeEntityItem(theEntity); // remove it from the element
|
bool entityDeleted = entityTreeElement->removeEntityItem(theEntity); // remove it from the element
|
||||||
assert(entityDeleted);
|
assert(entityDeleted);
|
||||||
_tree->setContainingElement(details.entity->getEntityItemID(), NULL); // update or id to element lookup
|
_tree->setContainingElement(details.entity->getEntityItemID(), NULL); // update or id to element lookup
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
class EntityToDeleteDetails {
|
class EntityToDeleteDetails {
|
||||||
public:
|
public:
|
||||||
EntityItem* entity;
|
EntityItemPointer entity;
|
||||||
AACube cube;
|
AACube cube;
|
||||||
EntityTreeElement* containingElement;
|
EntityTreeElement* containingElement;
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,7 +78,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
||||||
bool success = true;
|
bool success = true;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->lockForWrite();
|
_entityTree->lockForWrite();
|
||||||
EntityItem* entity = _entityTree->addEntity(id, propertiesWithSimID);
|
EntityItemPointer entity = _entityTree->addEntity(id, propertiesWithSimID);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
entity->setLastBroadcast(usecTimestampNow());
|
entity->setLastBroadcast(usecTimestampNow());
|
||||||
// This Node is creating a new object. If it's in motion, set this Node as the simulator.
|
// This Node is creating a new object. If it's in motion, set this Node as the simulator.
|
||||||
|
@ -102,7 +102,8 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
||||||
EntityItemProperties results;
|
EntityItemProperties results;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->lockForRead();
|
_entityTree->lockForRead();
|
||||||
EntityItem* entity = const_cast<EntityItem*>(_entityTree->findEntityByEntityItemID(EntityItemID(identity)));
|
|
||||||
|
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
||||||
|
|
||||||
if (entity) {
|
if (entity) {
|
||||||
results = entity->getProperties();
|
results = entity->getProperties();
|
||||||
|
@ -137,7 +138,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
||||||
|
|
||||||
// make sure the properties has a type, so that the encode can know which properties to include
|
// make sure the properties has a type, so that the encode can know which properties to include
|
||||||
if (properties.getType() == EntityTypes::Unknown) {
|
if (properties.getType() == EntityTypes::Unknown) {
|
||||||
EntityItem* entity = _entityTree->findEntityByEntityItemID(entityID);
|
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
// we need to change the outgoing properties, so we make a copy, modify, and send.
|
// we need to change the outgoing properties, so we make a copy, modify, and send.
|
||||||
EntityItemProperties modifiedProperties = properties;
|
EntityItemProperties modifiedProperties = properties;
|
||||||
|
@ -161,7 +162,7 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->lockForWrite();
|
_entityTree->lockForWrite();
|
||||||
|
|
||||||
EntityItem* entity = const_cast<EntityItem*>(_entityTree->findEntityByEntityItemID(entityID));
|
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
if (entity->getLocked()) {
|
if (entity->getLocked()) {
|
||||||
shouldDelete = false;
|
shouldDelete = false;
|
||||||
|
@ -183,7 +184,7 @@ QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float
|
||||||
EntityItemID result;
|
EntityItemID result;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->lockForRead();
|
_entityTree->lockForRead();
|
||||||
const EntityItem* closestEntity = _entityTree->findClosestEntity(center, radius);
|
EntityItemPointer closestEntity = _entityTree->findClosestEntity(center, radius);
|
||||||
_entityTree->unlock();
|
_entityTree->unlock();
|
||||||
if (closestEntity) {
|
if (closestEntity) {
|
||||||
result = closestEntity->getEntityItemID();
|
result = closestEntity->getEntityItemID();
|
||||||
|
@ -205,11 +206,11 @@ QVector<QUuid> EntityScriptingInterface::findEntities(const glm::vec3& center, f
|
||||||
QVector<QUuid> result;
|
QVector<QUuid> result;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->lockForRead();
|
_entityTree->lockForRead();
|
||||||
QVector<const EntityItem*> entities;
|
QVector<EntityItemPointer> entities;
|
||||||
_entityTree->findEntities(center, radius, entities);
|
_entityTree->findEntities(center, radius, entities);
|
||||||
_entityTree->unlock();
|
_entityTree->unlock();
|
||||||
|
|
||||||
foreach (const EntityItem* entity, entities) {
|
foreach (EntityItemPointer entity, entities) {
|
||||||
result << entity->getEntityItemID();
|
result << entity->getEntityItemID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,11 +222,11 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->lockForRead();
|
_entityTree->lockForRead();
|
||||||
AABox box(corner, dimensions);
|
AABox box(corner, dimensions);
|
||||||
QVector<EntityItem*> entities;
|
QVector<EntityItemPointer> entities;
|
||||||
_entityTree->findEntities(box, entities);
|
_entityTree->findEntities(box, entities);
|
||||||
_entityTree->unlock();
|
_entityTree->unlock();
|
||||||
|
|
||||||
foreach (const EntityItem* entity, entities) {
|
foreach (EntityItemPointer entity, entities) {
|
||||||
result << entity->getEntityItemID();
|
result << entity->getEntityItemID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +249,7 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorke
|
||||||
RayToEntityIntersectionResult result;
|
RayToEntityIntersectionResult result;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
OctreeElement* element;
|
OctreeElement* element;
|
||||||
EntityItem* intersectedEntity = NULL;
|
EntityItemPointer intersectedEntity = NULL;
|
||||||
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
(void**)&intersectedEntity, lockType, &result.accurate,
|
||||||
precisionPicking);
|
precisionPicking);
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
float distance;
|
float distance;
|
||||||
BoxFace face;
|
BoxFace face;
|
||||||
glm::vec3 intersection;
|
glm::vec3 intersection;
|
||||||
EntityItem* entity;
|
EntityItemPointer entity;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(RayToEntityIntersectionResult)
|
Q_DECLARE_METATYPE(RayToEntityIntersectionResult)
|
||||||
|
|
|
@ -38,22 +38,21 @@ void EntitySimulation::updateEntities() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::getEntitiesToDelete(VectorOfEntities& entitiesToDelete) {
|
void EntitySimulation::getEntitiesToDelete(VectorOfEntities& entitiesToDelete) {
|
||||||
for (auto entityItr : _entitiesToDelete) {
|
|
||||||
EntityItem* entity = &(*entityItr);
|
for (auto entity : _entitiesToDelete) {
|
||||||
// this entity is still in its tree, so we insert into the external list
|
// this entity is still in its tree, so we insert into the external list
|
||||||
entitiesToDelete.push_back(entity);
|
entitiesToDelete.push_back(entity);
|
||||||
++entityItr;
|
|
||||||
}
|
}
|
||||||
_entitiesToDelete.clear();
|
_entitiesToDelete.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::addEntityInternal(EntityItem* entity) {
|
void EntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||||
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
||||||
_simpleKinematicEntities.insert(entity);
|
_simpleKinematicEntities.insert(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::changeEntityInternal(EntityItem* entity) {
|
void EntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||||
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
||||||
_simpleKinematicEntities.insert(entity);
|
_simpleKinematicEntities.insert(entity);
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,7 +67,7 @@ void EntitySimulation::expireMortalEntities(const quint64& now) {
|
||||||
_nextExpiry = quint64(-1);
|
_nextExpiry = quint64(-1);
|
||||||
SetOfEntities::iterator itemItr = _mortalEntities.begin();
|
SetOfEntities::iterator itemItr = _mortalEntities.begin();
|
||||||
while (itemItr != _mortalEntities.end()) {
|
while (itemItr != _mortalEntities.end()) {
|
||||||
EntityItem* entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
quint64 expiry = entity->getExpiry();
|
quint64 expiry = entity->getExpiry();
|
||||||
if (expiry < now) {
|
if (expiry < now) {
|
||||||
_entitiesToDelete.insert(entity);
|
_entitiesToDelete.insert(entity);
|
||||||
|
@ -96,7 +95,7 @@ void EntitySimulation::callUpdateOnEntitiesThatNeedIt(const quint64& now) {
|
||||||
PerformanceTimer perfTimer("updatingEntities");
|
PerformanceTimer perfTimer("updatingEntities");
|
||||||
SetOfEntities::iterator itemItr = _entitiesToUpdate.begin();
|
SetOfEntities::iterator itemItr = _entitiesToUpdate.begin();
|
||||||
while (itemItr != _entitiesToUpdate.end()) {
|
while (itemItr != _entitiesToUpdate.end()) {
|
||||||
EntityItem* entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
// TODO: catch transition from needing update to not as a "change"
|
// TODO: catch transition from needing update to not as a "change"
|
||||||
// so we don't have to scan for it here.
|
// so we don't have to scan for it here.
|
||||||
if (!entity->needsToCallUpdate()) {
|
if (!entity->needsToCallUpdate()) {
|
||||||
|
@ -117,7 +116,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
|
||||||
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE);
|
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE);
|
||||||
SetOfEntities::iterator itemItr = _entitiesToSort.begin();
|
SetOfEntities::iterator itemItr = _entitiesToSort.begin();
|
||||||
while (itemItr != _entitiesToSort.end()) {
|
while (itemItr != _entitiesToSort.end()) {
|
||||||
EntityItem* entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
// check to see if this movement has sent the entity outside of the domain.
|
// check to see if this movement has sent the entity outside of the domain.
|
||||||
AACube newCube = entity->getMaximumAACube();
|
AACube newCube = entity->getMaximumAACube();
|
||||||
if (!domainBounds.touches(newCube)) {
|
if (!domainBounds.touches(newCube)) {
|
||||||
|
@ -145,7 +144,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
|
||||||
_entitiesToSort.clear();
|
_entitiesToSort.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::addEntity(EntityItem* entity) {
|
void EntitySimulation::addEntity(EntityItemPointer entity) {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
if (entity->isMortal()) {
|
if (entity->isMortal()) {
|
||||||
_mortalEntities.insert(entity);
|
_mortalEntities.insert(entity);
|
||||||
|
@ -167,7 +166,7 @@ void EntitySimulation::addEntity(EntityItem* entity) {
|
||||||
entity->clearDirtyFlags();
|
entity->clearDirtyFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::removeEntity(EntityItem* entity) {
|
void EntitySimulation::removeEntity(EntityItemPointer entity) {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
_entitiesToUpdate.remove(entity);
|
_entitiesToUpdate.remove(entity);
|
||||||
_mortalEntities.remove(entity);
|
_mortalEntities.remove(entity);
|
||||||
|
@ -180,7 +179,7 @@ void EntitySimulation::removeEntity(EntityItem* entity) {
|
||||||
entity->_simulated = false;
|
entity->_simulated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntitySimulation::changeEntity(EntityItem* entity) {
|
void EntitySimulation::changeEntity(EntityItemPointer entity) {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
if (!entity->_simulated) {
|
if (!entity->_simulated) {
|
||||||
// This entity was either never added to the simulation or has been removed
|
// This entity was either never added to the simulation or has been removed
|
||||||
|
@ -250,7 +249,7 @@ void EntitySimulation::clearEntities() {
|
||||||
void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
||||||
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
||||||
while (itemItr != _simpleKinematicEntities.end()) {
|
while (itemItr != _simpleKinematicEntities.end()) {
|
||||||
EntityItem* entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
||||||
entity->simulate(now);
|
entity->simulate(now);
|
||||||
_entitiesToSort.insert(entity);
|
_entitiesToSort.insert(entity);
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
|
|
||||||
typedef QSet<EntityItem*> SetOfEntities;
|
typedef QSet<EntityItemPointer> SetOfEntities;
|
||||||
typedef QVector<EntityItem*> VectorOfEntities;
|
typedef QVector<EntityItemPointer> VectorOfEntities;
|
||||||
|
|
||||||
// the EntitySimulation needs to know when these things change on an entity,
|
// the EntitySimulation needs to know when these things change on an entity,
|
||||||
// so it can sort EntityItem or relay its state to the PhysicsEngine.
|
// so it can sort EntityItem or relay its state to the PhysicsEngine.
|
||||||
|
@ -59,16 +59,16 @@ public:
|
||||||
protected: // these only called by the EntityTree?
|
protected: // these only called by the EntityTree?
|
||||||
/// \param entity pointer to EntityItem to be added
|
/// \param entity pointer to EntityItem to be added
|
||||||
/// \sideeffect sets relevant backpointers in entity, but maybe later when appropriate data structures are locked
|
/// \sideeffect sets relevant backpointers in entity, but maybe later when appropriate data structures are locked
|
||||||
void addEntity(EntityItem* entity);
|
void addEntity(EntityItemPointer entity);
|
||||||
|
|
||||||
/// \param entity pointer to EntityItem to be removed
|
/// \param entity pointer to EntityItem to be removed
|
||||||
/// \brief the actual removal may happen later when appropriate data structures are locked
|
/// \brief the actual removal may happen later when appropriate data structures are locked
|
||||||
/// \sideeffect nulls relevant backpointers in entity
|
/// \sideeffect nulls relevant backpointers in entity
|
||||||
void removeEntity(EntityItem* entity);
|
void removeEntity(EntityItemPointer entity);
|
||||||
|
|
||||||
/// \param entity pointer to EntityItem to that may have changed in a way that would affect its simulation
|
/// \param entity pointer to EntityItem to that may have changed in a way that would affect its simulation
|
||||||
/// call this whenever an entity was changed from some EXTERNAL event (NOT by the EntitySimulation itself)
|
/// call this whenever an entity was changed from some EXTERNAL event (NOT by the EntitySimulation itself)
|
||||||
void changeEntity(EntityItem* entity);
|
void changeEntity(EntityItemPointer entity);
|
||||||
|
|
||||||
void clearEntities();
|
void clearEntities();
|
||||||
|
|
||||||
|
@ -88,9 +88,9 @@ protected:
|
||||||
// These pure virtual methods are protected because they are not to be called will-nilly. The base class
|
// These pure virtual methods are protected because they are not to be called will-nilly. The base class
|
||||||
// calls them in the right places.
|
// calls them in the right places.
|
||||||
virtual void updateEntitiesInternal(const quint64& now) = 0;
|
virtual void updateEntitiesInternal(const quint64& now) = 0;
|
||||||
virtual void addEntityInternal(EntityItem* entity);
|
virtual void addEntityInternal(EntityItemPointer entity);
|
||||||
virtual void removeEntityInternal(EntityItem* entity) = 0;
|
virtual void removeEntityInternal(EntityItemPointer entity) = 0;
|
||||||
virtual void changeEntityInternal(EntityItem* entity);
|
virtual void changeEntityInternal(EntityItemPointer entity);
|
||||||
virtual void clearEntitiesInternal() = 0;
|
virtual void clearEntitiesInternal() = 0;
|
||||||
|
|
||||||
void expireMortalEntities(const quint64& now);
|
void expireMortalEntities(const quint64& now);
|
||||||
|
|
|
@ -75,7 +75,7 @@ bool EntityTree::handlesEditPacketType(PacketType packetType) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new entity item to the tree
|
/// Adds a new entity item to the tree
|
||||||
void EntityTree::postAddEntity(EntityItem* entity) {
|
void EntityTree::postAddEntity(EntityItemPointer entity) {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
// check to see if we need to simulate this entity..
|
// check to see if we need to simulate this entity..
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
|
@ -94,7 +94,7 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||||
if (!existingEntity) {
|
if (!existingEntity) {
|
||||||
qCDebug(entities) << "UNEXPECTED!!!! don't call updateEntity() on entity items that don't exist. entityID=" << entityID;
|
qCDebug(entities) << "UNEXPECTED!!!! don't call updateEntity() on entity items that don't exist. entityID=" << entityID;
|
||||||
return false;
|
return false;
|
||||||
|
@ -103,7 +103,7 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
|
||||||
return updateEntityWithElement(existingEntity, properties, containingElement, senderNode);
|
return updateEntityWithElement(existingEntity, properties, containingElement, senderNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::updateEntity(EntityItem* entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
||||||
EntityTreeElement* containingElement = getContainingElement(entity->getEntityItemID());
|
EntityTreeElement* containingElement = getContainingElement(entity->getEntityItemID());
|
||||||
if (!containingElement) {
|
if (!containingElement) {
|
||||||
qCDebug(entities) << "UNEXPECTED!!!! EntityTree::updateEntity() entity-->element lookup failed!!! entityID="
|
qCDebug(entities) << "UNEXPECTED!!!! EntityTree::updateEntity() entity-->element lookup failed!!! entityID="
|
||||||
|
@ -113,7 +113,7 @@ bool EntityTree::updateEntity(EntityItem* entity, const EntityItemProperties& pr
|
||||||
return updateEntityWithElement(entity, properties, containingElement, senderNode);
|
return updateEntityWithElement(entity, properties, containingElement, senderNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemProperties& origProperties,
|
bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& origProperties,
|
||||||
EntityTreeElement* containingElement, const SharedNodePointer& senderNode) {
|
EntityTreeElement* containingElement, const SharedNodePointer& senderNode) {
|
||||||
EntityItemProperties properties = origProperties;
|
EntityItemProperties properties = origProperties;
|
||||||
|
|
||||||
|
@ -220,8 +220,8 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItem* result = NULL;
|
EntityItemPointer result = NULL;
|
||||||
|
|
||||||
if (getIsClient()) {
|
if (getIsClient()) {
|
||||||
// if our Node isn't allowed to create entities in this domain, don't try.
|
// if our Node isn't allowed to create entities in this domain, don't try.
|
||||||
|
@ -291,7 +291,7 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||||
if (!existingEntity) {
|
if (!existingEntity) {
|
||||||
if (!ignoreWarnings) {
|
if (!ignoreWarnings) {
|
||||||
qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. "
|
qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. "
|
||||||
|
@ -328,7 +328,7 @@ void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force, bool i
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||||
if (!existingEntity) {
|
if (!existingEntity) {
|
||||||
if (!ignoreWarnings) {
|
if (!ignoreWarnings) {
|
||||||
qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. "
|
qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. "
|
||||||
|
@ -362,7 +362,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
||||||
_simulation->lock();
|
_simulation->lock();
|
||||||
}
|
}
|
||||||
foreach(const EntityToDeleteDetails& details, entities) {
|
foreach(const EntityToDeleteDetails& details, entities) {
|
||||||
EntityItem* theEntity = details.entity;
|
EntityItemPointer theEntity = details.entity;
|
||||||
|
|
||||||
if (getIsServer()) {
|
if (getIsServer()) {
|
||||||
// set up the deleted entities ID
|
// set up the deleted entities ID
|
||||||
|
@ -374,8 +374,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
||||||
|
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
_simulation->removeEntity(theEntity);
|
_simulation->removeEntity(theEntity);
|
||||||
}
|
}
|
||||||
delete theEntity; // we can delete the entity immediately
|
|
||||||
}
|
}
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
_simulation->unlock();
|
_simulation->unlock();
|
||||||
|
@ -388,7 +387,7 @@ public:
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
float targetRadius;
|
float targetRadius;
|
||||||
bool found;
|
bool found;
|
||||||
const EntityItem* closestEntity;
|
EntityItemPointer closestEntity;
|
||||||
float closestEntityDistance;
|
float closestEntityDistance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -402,7 +401,7 @@ bool EntityTree::findNearPointOperation(OctreeElement* element, void* extraData)
|
||||||
|
|
||||||
// If this entityTreeElement contains the point, then search it...
|
// If this entityTreeElement contains the point, then search it...
|
||||||
if (sphereIntersection) {
|
if (sphereIntersection) {
|
||||||
const EntityItem* thisClosestEntity = entityTreeElement->getClosestEntity(args->position);
|
EntityItemPointer thisClosestEntity = entityTreeElement->getClosestEntity(args->position);
|
||||||
|
|
||||||
// we may have gotten NULL back, meaning no entity was available
|
// we may have gotten NULL back, meaning no entity was available
|
||||||
if (thisClosestEntity) {
|
if (thisClosestEntity) {
|
||||||
|
@ -428,7 +427,7 @@ bool EntityTree::findNearPointOperation(OctreeElement* element, void* extraData)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntityItem* EntityTree::findClosestEntity(glm::vec3 position, float targetRadius) {
|
EntityItemPointer EntityTree::findClosestEntity(glm::vec3 position, float targetRadius) {
|
||||||
FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX };
|
FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX };
|
||||||
lockForRead();
|
lockForRead();
|
||||||
// NOTE: This should use recursion, since this is a spatial operation
|
// NOTE: This should use recursion, since this is a spatial operation
|
||||||
|
@ -441,7 +440,7 @@ class FindAllNearPointArgs {
|
||||||
public:
|
public:
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
float targetRadius;
|
float targetRadius;
|
||||||
QVector<const EntityItem*> entities;
|
QVector<EntityItemPointer> entities;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -462,8 +461,8 @@ bool EntityTree::findInSphereOperation(OctreeElement* element, void* extraData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: assumes caller has handled locking
|
// NOTE: assumes caller has handled locking
|
||||||
void EntityTree::findEntities(const glm::vec3& center, float radius, QVector<const EntityItem*>& foundEntities) {
|
void EntityTree::findEntities(const glm::vec3& center, float radius, QVector<EntityItemPointer>& foundEntities) {
|
||||||
FindAllNearPointArgs args = { center, radius, QVector<const EntityItem*>() };
|
FindAllNearPointArgs args = { center, radius, QVector<EntityItemPointer>() };
|
||||||
// NOTE: This should use recursion, since this is a spatial operation
|
// NOTE: This should use recursion, since this is a spatial operation
|
||||||
recurseTreeWithOperation(findInSphereOperation, &args);
|
recurseTreeWithOperation(findInSphereOperation, &args);
|
||||||
|
|
||||||
|
@ -478,7 +477,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
AACube _cube;
|
AACube _cube;
|
||||||
QVector<EntityItem*> _foundEntities;
|
QVector<EntityItemPointer> _foundEntities;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool EntityTree::findInCubeOperation(OctreeElement* element, void* extraData) {
|
bool EntityTree::findInCubeOperation(OctreeElement* element, void* extraData) {
|
||||||
|
@ -492,7 +491,7 @@ bool EntityTree::findInCubeOperation(OctreeElement* element, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: assumes caller has handled locking
|
// NOTE: assumes caller has handled locking
|
||||||
void EntityTree::findEntities(const AACube& cube, QVector<EntityItem*>& foundEntities) {
|
void EntityTree::findEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities) {
|
||||||
FindEntitiesInCubeArgs args(cube);
|
FindEntitiesInCubeArgs args(cube);
|
||||||
// NOTE: This should use recursion, since this is a spatial operation
|
// NOTE: This should use recursion, since this is a spatial operation
|
||||||
recurseTreeWithOperation(findInCubeOperation, &args);
|
recurseTreeWithOperation(findInCubeOperation, &args);
|
||||||
|
@ -507,7 +506,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
AABox _box;
|
AABox _box;
|
||||||
QVector<EntityItem*> _foundEntities;
|
QVector<EntityItemPointer> _foundEntities;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool EntityTree::findInBoxOperation(OctreeElement* element, void* extraData) {
|
bool EntityTree::findInBoxOperation(OctreeElement* element, void* extraData) {
|
||||||
|
@ -521,7 +520,7 @@ bool EntityTree::findInBoxOperation(OctreeElement* element, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: assumes caller has handled locking
|
// NOTE: assumes caller has handled locking
|
||||||
void EntityTree::findEntities(const AABox& box, QVector<EntityItem*>& foundEntities) {
|
void EntityTree::findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities) {
|
||||||
FindEntitiesInBoxArgs args(box);
|
FindEntitiesInBoxArgs args(box);
|
||||||
// NOTE: This should use recursion, since this is a spatial operation
|
// NOTE: This should use recursion, since this is a spatial operation
|
||||||
recurseTreeWithOperation(findInBoxOperation, &args);
|
recurseTreeWithOperation(findInBoxOperation, &args);
|
||||||
|
@ -529,13 +528,13 @@ void EntityTree::findEntities(const AABox& box, QVector<EntityItem*>& foundEntit
|
||||||
foundEntities.swap(args._foundEntities);
|
foundEntities.swap(args._foundEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* EntityTree::findEntityByID(const QUuid& id) {
|
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
||||||
EntityItemID entityID(id);
|
EntityItemID entityID(id);
|
||||||
return findEntityByEntityItemID(entityID);
|
return findEntityByEntityItemID(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) /*const*/ {
|
EntityItemPointer EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) /*const*/ {
|
||||||
EntityItem* foundEntity = NULL;
|
EntityItemPointer foundEntity = NULL;
|
||||||
EntityTreeElement* containingElement = getContainingElement(entityID);
|
EntityTreeElement* containingElement = getContainingElement(entityID);
|
||||||
if (containingElement) {
|
if (containingElement) {
|
||||||
foundEntity = containingElement->getEntityWithEntityItemID(entityID);
|
foundEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||||
|
@ -571,7 +570,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
// an existing entity... handle appropriately
|
// an existing entity... handle appropriately
|
||||||
if (validEditPacket) {
|
if (validEditPacket) {
|
||||||
// search for the entity by EntityItemID
|
// search for the entity by EntityItemID
|
||||||
EntityItem* existingEntity = findEntityByEntityItemID(entityItemID);
|
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
|
||||||
if (existingEntity && packetType == PacketTypeEntityEdit) {
|
if (existingEntity && packetType == PacketTypeEntityEdit) {
|
||||||
// if the EntityItem exists, then update it
|
// if the EntityItem exists, then update it
|
||||||
if (wantEditLogging()) {
|
if (wantEditLogging()) {
|
||||||
|
@ -588,7 +587,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
qCDebug(entities) << " properties:" << properties;
|
qCDebug(entities) << " properties:" << properties;
|
||||||
}
|
}
|
||||||
properties.setCreated(properties.getLastEdited());
|
properties.setCreated(properties.getLastEdited());
|
||||||
EntityItem* newEntity = addEntity(entityItemID, properties);
|
EntityItemPointer newEntity = addEntity(entityItemID, properties);
|
||||||
if (newEntity) {
|
if (newEntity) {
|
||||||
newEntity->markAsChangedOnServer();
|
newEntity->markAsChangedOnServer();
|
||||||
notifyNewlyCreatedEntity(*newEntity, senderNode);
|
notifyNewlyCreatedEntity(*newEntity, senderNode);
|
||||||
|
@ -604,7 +603,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
<< "] attempted to add an entity.";
|
<< "] attempted to add an entity.";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity;
|
qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -652,7 +651,7 @@ void EntityTree::releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncod
|
||||||
extraEncodeData->clear();
|
extraEncodeData->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTree::entityChanged(EntityItem* entity) {
|
void EntityTree::entityChanged(EntityItemPointer entity) {
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
_simulation->lock();
|
_simulation->lock();
|
||||||
_simulation->changeEntity(entity);
|
_simulation->changeEntity(entity);
|
||||||
|
@ -672,11 +671,12 @@ void EntityTree::update() {
|
||||||
if (pendingDeletes.size() > 0) {
|
if (pendingDeletes.size() > 0) {
|
||||||
// translate into list of ID's
|
// translate into list of ID's
|
||||||
QSet<EntityItemID> idsToDelete;
|
QSet<EntityItemID> idsToDelete;
|
||||||
for (auto entityItr : pendingDeletes) {
|
|
||||||
EntityItem* entity = &(*entityItr);
|
for (auto entity : pendingDeletes) {
|
||||||
assert(!entity->getPhysicsInfo()); // TODO: Andrew to remove this after testing
|
assert(!entity->getPhysicsInfo()); // TODO: Andrew to remove this after testing
|
||||||
idsToDelete.insert(entity->getEntityItemID());
|
idsToDelete.insert(entity->getEntityItemID());
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete these things the roundabout way
|
// delete these things the roundabout way
|
||||||
deleteEntities(idsToDelete, true);
|
deleteEntities(idsToDelete, true);
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1004,7 @@ bool EntityTree::sendEntitiesOperation(OctreeElement* element, void* extraData)
|
||||||
SendEntitiesOperationArgs* args = static_cast<SendEntitiesOperationArgs*>(extraData);
|
SendEntitiesOperationArgs* args = static_cast<SendEntitiesOperationArgs*>(extraData);
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
|
|
||||||
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
const EntityItems& entities = entityTreeElement->getEntities();
|
||||||
for (int i = 0; i < entities.size(); i++) {
|
for (int i = 0; i < entities.size(); i++) {
|
||||||
EntityItemID newID(QUuid::createUuid());
|
EntityItemID newID(QUuid::createUuid());
|
||||||
args->newEntityIDs->append(newID);
|
args->newEntityIDs->append(newID);
|
||||||
|
@ -1056,7 +1056,7 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
||||||
entityItemID = EntityItemID(QUuid::createUuid());
|
entityItemID = EntityItemID(QUuid::createUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* entity = addEntity(entityItemID, properties);
|
EntityItemPointer entity = addEntity(entityItemID, properties);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@ public:
|
||||||
|
|
||||||
class EntityItemFBXService {
|
class EntityItemFBXService {
|
||||||
public:
|
public:
|
||||||
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem) = 0;
|
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) = 0;
|
||||||
virtual const Model* getModelForEntityItem(const EntityItem* entityItem) = 0;
|
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem) = 0;
|
||||||
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem) = 0;
|
virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,24 +83,24 @@ public:
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
// The newer API...
|
// The newer API...
|
||||||
void postAddEntity(EntityItem* entityItem);
|
void postAddEntity(EntityItemPointer entityItem);
|
||||||
|
|
||||||
EntityItem* addEntity(const EntityItemID& entityID, const EntityItemProperties& properties);
|
EntityItemPointer addEntity(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
// use this method if you only know the entityID
|
// use this method if you only know the entityID
|
||||||
bool updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
bool updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||||
|
|
||||||
// use this method if you have a pointer to the entity (avoid an extra entity lookup)
|
// use this method if you have a pointer to the entity (avoid an extra entity lookup)
|
||||||
bool updateEntity(EntityItem* entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
bool updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||||
|
|
||||||
void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false);
|
void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false);
|
||||||
void deleteEntities(QSet<EntityItemID> entityIDs, bool force = false, bool ignoreWarnings = false);
|
void deleteEntities(QSet<EntityItemID> entityIDs, bool force = false, bool ignoreWarnings = false);
|
||||||
|
|
||||||
/// \param position point of query in world-frame (meters)
|
/// \param position point of query in world-frame (meters)
|
||||||
/// \param targetRadius radius of query (meters)
|
/// \param targetRadius radius of query (meters)
|
||||||
const EntityItem* findClosestEntity(glm::vec3 position, float targetRadius);
|
EntityItemPointer findClosestEntity(glm::vec3 position, float targetRadius);
|
||||||
EntityItem* findEntityByID(const QUuid& id);
|
EntityItemPointer findEntityByID(const QUuid& id);
|
||||||
EntityItem* findEntityByEntityItemID(const EntityItemID& entityID);
|
EntityItemPointer findEntityByEntityItemID(const EntityItemID& entityID);
|
||||||
|
|
||||||
EntityItemID assignEntityID(const EntityItemID& entityItemID); /// Assigns a known ID for a creator token ID
|
EntityItemID assignEntityID(const EntityItemID& entityItemID); /// Assigns a known ID for a creator token ID
|
||||||
|
|
||||||
|
@ -108,21 +108,21 @@ public:
|
||||||
/// finds all entities that touch a sphere
|
/// finds all entities that touch a sphere
|
||||||
/// \param center the center of the sphere in world-frame (meters)
|
/// \param center the center of the sphere in world-frame (meters)
|
||||||
/// \param radius the radius of the sphere in world-frame (meters)
|
/// \param radius the radius of the sphere in world-frame (meters)
|
||||||
/// \param foundEntities[out] vector of const EntityItem*
|
/// \param foundEntities[out] vector of EntityItemPointer
|
||||||
/// \remark Side effect: any initial contents in foundEntities will be lost
|
/// \remark Side effect: any initial contents in foundEntities will be lost
|
||||||
void findEntities(const glm::vec3& center, float radius, QVector<const EntityItem*>& foundEntities);
|
void findEntities(const glm::vec3& center, float radius, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
/// finds all entities that touch a cube
|
/// finds all entities that touch a cube
|
||||||
/// \param cube the query cube in world-frame (meters)
|
/// \param cube the query cube in world-frame (meters)
|
||||||
/// \param foundEntities[out] vector of non-const EntityItem*
|
/// \param foundEntities[out] vector of non-EntityItemPointer
|
||||||
/// \remark Side effect: any initial contents in entities will be lost
|
/// \remark Side effect: any initial contents in entities will be lost
|
||||||
void findEntities(const AACube& cube, QVector<EntityItem*>& foundEntities);
|
void findEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
/// finds all entities that touch a box
|
/// finds all entities that touch a box
|
||||||
/// \param box the query box in world-frame (meters)
|
/// \param box the query box in world-frame (meters)
|
||||||
/// \param foundEntities[out] vector of non-const EntityItem*
|
/// \param foundEntities[out] vector of non-EntityItemPointer
|
||||||
/// \remark Side effect: any initial contents in entities will be lost
|
/// \remark Side effect: any initial contents in entities will be lost
|
||||||
void findEntities(const AABox& box, QVector<EntityItem*>& foundEntities);
|
void findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
|
@ -138,10 +138,10 @@ public:
|
||||||
|
|
||||||
EntityItemFBXService* getFBXService() const { return _fbxService; }
|
EntityItemFBXService* getFBXService() const { return _fbxService; }
|
||||||
void setFBXService(EntityItemFBXService* service) { _fbxService = service; }
|
void setFBXService(EntityItemFBXService* service) { _fbxService = service; }
|
||||||
const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem) {
|
const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) {
|
||||||
return _fbxService ? _fbxService->getGeometryForEntity(entityItem) : NULL;
|
return _fbxService ? _fbxService->getGeometryForEntity(entityItem) : NULL;
|
||||||
}
|
}
|
||||||
const Model* getModelForEntityItem(const EntityItem* entityItem) {
|
const Model* getModelForEntityItem(EntityItemPointer entityItem) {
|
||||||
return _fbxService ? _fbxService->getModelForEntityItem(entityItem) : NULL;
|
return _fbxService ? _fbxService->getModelForEntityItem(entityItem) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ public:
|
||||||
|
|
||||||
QVector<EntityItemID> sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z);
|
QVector<EntityItemID> sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z);
|
||||||
|
|
||||||
void entityChanged(EntityItem* entity);
|
void entityChanged(EntityItemPointer entity);
|
||||||
|
|
||||||
void emitEntityScriptChanging(const EntityItemID& entityItemID);
|
void emitEntityScriptChanging(const EntityItemID& entityItemID);
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ signals:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void processRemovedEntities(const DeleteEntityOperator& theOperator);
|
void processRemovedEntities(const DeleteEntityOperator& theOperator);
|
||||||
bool updateEntityWithElement(EntityItem* entity, const EntityItemProperties& properties,
|
bool updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& properties,
|
||||||
EntityTreeElement* containingElement,
|
EntityTreeElement* containingElement,
|
||||||
const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||||
static bool findNearPointOperation(OctreeElement* element, void* extraData);
|
static bool findNearPointOperation(OctreeElement* element, void* extraData);
|
||||||
|
|
|
@ -39,7 +39,7 @@ OctreeElement* EntityTreeElement::createNewElement(unsigned char* octalCode) {
|
||||||
|
|
||||||
void EntityTreeElement::init(unsigned char* octalCode) {
|
void EntityTreeElement::init(unsigned char* octalCode) {
|
||||||
OctreeElement::init(octalCode);
|
OctreeElement::init(octalCode);
|
||||||
_entityItems = new QList<EntityItem*>;
|
_entityItems = new EntityItems;
|
||||||
_octreeMemoryUsage += sizeof(EntityTreeElement);
|
_octreeMemoryUsage += sizeof(EntityTreeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ void EntityTreeElement::initializeExtraEncodeData(EncodeBitstreamParams& params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||||
EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
entityTreeElementExtraEncodeData->entities.insert(entity->getEntityItemID(), entity->getEntityProperties(params));
|
entityTreeElementExtraEncodeData->entities.insert(entity->getEntityItemID(), entity->getEntityProperties(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||||
EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
entityTreeElementExtraEncodeData->entities.insert(entity->getEntityItemID(), entity->getEntityProperties(params));
|
entityTreeElementExtraEncodeData->entities.insert(entity->getEntityItemID(), entity->getEntityProperties(params));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
||||||
// need to handle the case where our sibling elements need encoding but we don't.
|
// need to handle the case where our sibling elements need encoding but we don't.
|
||||||
if (!entityTreeElementExtraEncodeData->elementCompleted) {
|
if (!entityTreeElementExtraEncodeData->elementCompleted) {
|
||||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||||
EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
bool includeThisEntity = true;
|
bool includeThisEntity = true;
|
||||||
|
|
||||||
if (!params.forceSendScene && entity->getLastChangedOnServer() < params.lastViewFrustumSent) {
|
if (!params.forceSendScene && entity->getLastChangedOnServer() < params.lastViewFrustumSent) {
|
||||||
|
@ -320,7 +320,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
||||||
|
|
||||||
if (successAppendEntityCount) {
|
if (successAppendEntityCount) {
|
||||||
foreach (uint16_t i, indexesOfEntitiesToInclude) {
|
foreach (uint16_t i, indexesOfEntitiesToInclude) {
|
||||||
EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
LevelDetails entityLevel = packetData->startLevel();
|
LevelDetails entityLevel = packetData->startLevel();
|
||||||
OctreeElement::AppendState appendEntityState = entity->appendEntityData(packetData,
|
OctreeElement::AppendState appendEntityState = entity->appendEntityData(packetData,
|
||||||
params, entityTreeElementExtraEncodeData);
|
params, entityTreeElementExtraEncodeData);
|
||||||
|
@ -408,11 +408,11 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
||||||
return appendElementState;
|
return appendElementState;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTreeElement::containsEntityBounds(const EntityItem* entity) const {
|
bool EntityTreeElement::containsEntityBounds(EntityItemPointer entity) const {
|
||||||
return containsBounds(entity->getMaximumAACube());
|
return containsBounds(entity->getMaximumAACube());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTreeElement::bestFitEntityBounds(const EntityItem* entity) const {
|
bool EntityTreeElement::bestFitEntityBounds(EntityItemPointer entity) const {
|
||||||
return bestFitBounds(entity->getMaximumAACube());
|
return bestFitBounds(entity->getMaximumAACube());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,14 +476,14 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
||||||
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||||
int entityNumber = 0;
|
int entityNumber = 0;
|
||||||
|
|
||||||
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
|
EntityItems::iterator entityItr = _entityItems->begin();
|
||||||
QList<EntityItem*>::const_iterator entityEnd = _entityItems->end();
|
EntityItems::const_iterator entityEnd = _entityItems->end();
|
||||||
bool somethingIntersected = false;
|
bool somethingIntersected = false;
|
||||||
|
|
||||||
//float bestEntityDistance = distance;
|
//float bestEntityDistance = distance;
|
||||||
|
|
||||||
while(entityItr != entityEnd) {
|
while(entityItr != entityEnd) {
|
||||||
EntityItem* entity = (*entityItr);
|
EntityItemPointer entity = (*entityItr);
|
||||||
|
|
||||||
AABox entityBox = entity->getAABox();
|
AABox entityBox = entity->getAABox();
|
||||||
float localDistance;
|
float localDistance;
|
||||||
|
@ -519,7 +519,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
||||||
if (localDistance < distance) {
|
if (localDistance < distance) {
|
||||||
distance = localDistance;
|
distance = localDistance;
|
||||||
face = localFace;
|
face = localFace;
|
||||||
*intersectedObject = (void*)entity;
|
*intersectedObject = (void*)entity.get();
|
||||||
somethingIntersected = true;
|
somethingIntersected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,7 +528,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
||||||
if (localDistance < distance) {
|
if (localDistance < distance) {
|
||||||
distance = localDistance;
|
distance = localDistance;
|
||||||
face = localFace;
|
face = localFace;
|
||||||
*intersectedObject = (void*)entity;
|
*intersectedObject = (void*)entity.get();
|
||||||
somethingIntersected = true;
|
somethingIntersected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,10 +545,10 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
||||||
// TODO: change this to use better bounding shape for entity than sphere
|
// TODO: change this to use better bounding shape for entity than sphere
|
||||||
bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float radius,
|
bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float radius,
|
||||||
glm::vec3& penetration, void** penetratedObject) const {
|
glm::vec3& penetration, void** penetratedObject) const {
|
||||||
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
|
EntityItems::iterator entityItr = _entityItems->begin();
|
||||||
QList<EntityItem*>::const_iterator entityEnd = _entityItems->end();
|
EntityItems::const_iterator entityEnd = _entityItems->end();
|
||||||
while(entityItr != entityEnd) {
|
while(entityItr != entityEnd) {
|
||||||
EntityItem* entity = (*entityItr);
|
EntityItemPointer entity = (*entityItr);
|
||||||
glm::vec3 entityCenter = entity->getPosition();
|
glm::vec3 entityCenter = entity->getPosition();
|
||||||
float entityRadius = entity->getRadius();
|
float entityRadius = entity->getRadius();
|
||||||
|
|
||||||
|
@ -559,7 +559,9 @@ bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float rad
|
||||||
|
|
||||||
if (findSphereSpherePenetration(center, radius, entityCenter, entityRadius, penetration)) {
|
if (findSphereSpherePenetration(center, radius, entityCenter, entityRadius, penetration)) {
|
||||||
// return true on first valid entity penetration
|
// return true on first valid entity penetration
|
||||||
*penetratedObject = (void*)(entity);
|
|
||||||
|
*penetratedObject = (void*)(entity.get());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
++entityItr;
|
++entityItr;
|
||||||
|
@ -567,8 +569,8 @@ bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float rad
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntityItem* EntityTreeElement::getClosestEntity(glm::vec3 position) const {
|
EntityItemPointer EntityTreeElement::getClosestEntity(glm::vec3 position) const {
|
||||||
const EntityItem* closestEntity = NULL;
|
EntityItemPointer closestEntity = NULL;
|
||||||
float closestEntityDistance = FLT_MAX;
|
float closestEntityDistance = FLT_MAX;
|
||||||
uint16_t numberOfEntities = _entityItems->size();
|
uint16_t numberOfEntities = _entityItems->size();
|
||||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||||
|
@ -581,10 +583,10 @@ const EntityItem* EntityTreeElement::getClosestEntity(glm::vec3 position) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: change this to use better bounding shape for entity than sphere
|
// TODO: change this to use better bounding shape for entity than sphere
|
||||||
void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector<const EntityItem*>& foundEntities) const {
|
void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector<EntityItemPointer>& foundEntities) const {
|
||||||
uint16_t numberOfEntities = _entityItems->size();
|
uint16_t numberOfEntities = _entityItems->size();
|
||||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||||
const EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
float distance = glm::length(entity->getPosition() - searchPosition);
|
float distance = glm::length(entity->getPosition() - searchPosition);
|
||||||
if (distance < searchRadius + entity->getRadius()) {
|
if (distance < searchRadius + entity->getRadius()) {
|
||||||
foundEntities.push_back(entity);
|
foundEntities.push_back(entity);
|
||||||
|
@ -593,12 +595,12 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: change this to use better bounding shape for entity than sphere
|
// TODO: change this to use better bounding shape for entity than sphere
|
||||||
void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItem*>& foundEntities) {
|
void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItemPointer>& foundEntities) {
|
||||||
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
|
EntityItems::iterator entityItr = _entityItems->begin();
|
||||||
QList<EntityItem*>::iterator entityEnd = _entityItems->end();
|
EntityItems::iterator entityEnd = _entityItems->end();
|
||||||
AACube entityCube;
|
AACube entityCube;
|
||||||
while(entityItr != entityEnd) {
|
while(entityItr != entityEnd) {
|
||||||
EntityItem* entity = (*entityItr);
|
EntityItemPointer entity = (*entityItr);
|
||||||
float radius = entity->getRadius();
|
float radius = entity->getRadius();
|
||||||
// NOTE: we actually do cube-cube collision queries here, which is sloppy but good enough for now
|
// NOTE: we actually do cube-cube collision queries here, which is sloppy but good enough for now
|
||||||
// TODO: decide whether to replace entityCube-cube query with sphere-cube (requires a square root
|
// TODO: decide whether to replace entityCube-cube query with sphere-cube (requires a square root
|
||||||
|
@ -611,8 +613,8 @@ void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItem*>& fou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
||||||
const EntityItem* foundEntity = NULL;
|
EntityItemPointer foundEntity = NULL;
|
||||||
uint16_t numberOfEntities = _entityItems->size();
|
uint16_t numberOfEntities = _entityItems->size();
|
||||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||||
if ((*_entityItems)[i]->getEntityItemID() == id) {
|
if ((*_entityItems)[i]->getEntityItemID() == id) {
|
||||||
|
@ -623,8 +625,8 @@ const EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemI
|
||||||
return foundEntity;
|
return foundEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) {
|
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) {
|
||||||
EntityItem* foundEntity = NULL;
|
EntityItemPointer foundEntity = NULL;
|
||||||
uint16_t numberOfEntities = _entityItems->size();
|
uint16_t numberOfEntities = _entityItems->size();
|
||||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||||
if ((*_entityItems)[i]->getEntityItemID() == id) {
|
if ((*_entityItems)[i]->getEntityItemID() == id) {
|
||||||
|
@ -638,9 +640,13 @@ EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id)
|
||||||
void EntityTreeElement::cleanupEntities() {
|
void EntityTreeElement::cleanupEntities() {
|
||||||
uint16_t numberOfEntities = _entityItems->size();
|
uint16_t numberOfEntities = _entityItems->size();
|
||||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||||
EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
entity->_element = NULL;
|
entity->_element = NULL;
|
||||||
delete entity;
|
|
||||||
|
// NOTE: We explicitly don't delete the EntityItem here because since we only
|
||||||
|
// access it by smart pointers, when we remove it from the _entityItems
|
||||||
|
// we know that it will be deleted.
|
||||||
|
//delete entity;
|
||||||
}
|
}
|
||||||
_entityItems->clear();
|
_entityItems->clear();
|
||||||
}
|
}
|
||||||
|
@ -659,7 +665,7 @@ bool EntityTreeElement::removeEntityWithEntityItemID(const EntityItemID& id) {
|
||||||
return foundEntity;
|
return foundEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTreeElement::removeEntityItem(EntityItem* entity) {
|
bool EntityTreeElement::removeEntityItem(EntityItemPointer entity) {
|
||||||
int numEntries = _entityItems->removeAll(entity);
|
int numEntries = _entityItems->removeAll(entity);
|
||||||
if (numEntries > 0) {
|
if (numEntries > 0) {
|
||||||
assert(entity->_element == this);
|
assert(entity->_element == this);
|
||||||
|
@ -706,7 +712,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
|
||||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||||
int bytesForThisEntity = 0;
|
int bytesForThisEntity = 0;
|
||||||
EntityItemID entityItemID;
|
EntityItemID entityItemID;
|
||||||
EntityItem* entityItem = NULL;
|
EntityItemPointer entityItem = NULL;
|
||||||
|
|
||||||
// Old model files don't have UUIDs in them. So we don't want to try to read those IDs from the stream.
|
// Old model files don't have UUIDs in them. So we don't want to try to read those IDs from the stream.
|
||||||
// Since this can only happen on loading an old file, we can safely treat these as new entity cases,
|
// Since this can only happen on loading an old file, we can safely treat these as new entity cases,
|
||||||
|
@ -771,7 +777,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeElement::addEntityItem(EntityItem* entity) {
|
void EntityTreeElement::addEntityItem(EntityItemPointer entity) {
|
||||||
assert(entity);
|
assert(entity);
|
||||||
assert(entity->_element == NULL);
|
assert(entity->_element == NULL);
|
||||||
_entityItems->push_back(entity);
|
_entityItems->push_back(entity);
|
||||||
|
@ -809,7 +815,7 @@ bool EntityTreeElement::pruneChildren() {
|
||||||
void EntityTreeElement::expandExtentsToContents(Extents& extents) {
|
void EntityTreeElement::expandExtentsToContents(Extents& extents) {
|
||||||
if (_entityItems->size()) {
|
if (_entityItems->size()) {
|
||||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||||
EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
extents.add(entity->getAABox());
|
extents.add(entity->getAABox());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -825,7 +831,7 @@ void EntityTreeElement::debugDump() {
|
||||||
qCDebug(entities) << " has entities:" << _entityItems->size();
|
qCDebug(entities) << " has entities:" << _entityItems->size();
|
||||||
qCDebug(entities) << "--------------------------------------------------";
|
qCDebug(entities) << "--------------------------------------------------";
|
||||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||||
EntityItem* entity = (*_entityItems)[i];
|
EntityItemPointer entity = (*_entityItems)[i];
|
||||||
entity->debugDump();
|
entity->debugDump();
|
||||||
}
|
}
|
||||||
qCDebug(entities) << "--------------------------------------------------";
|
qCDebug(entities) << "--------------------------------------------------";
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_EntityTreeElement_h
|
#ifndef hifi_EntityTreeElement_h
|
||||||
#define hifi_EntityTreeElement_h
|
#define hifi_EntityTreeElement_h
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <OctreeElement.h>
|
#include <OctreeElement.h>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
@ -19,6 +21,8 @@
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
|
|
||||||
|
typedef QVector<EntityItemPointer> EntityItems;
|
||||||
|
|
||||||
class EntityTree;
|
class EntityTree;
|
||||||
class EntityTreeElement;
|
class EntityTreeElement;
|
||||||
|
|
||||||
|
@ -30,7 +34,7 @@ public:
|
||||||
_movingItems(0)
|
_movingItems(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
QList<EntityItem*> _movingEntities;
|
QList<EntityItemPointer> _movingEntities;
|
||||||
int _totalElements;
|
int _totalElements;
|
||||||
int _totalItems;
|
int _totalItems;
|
||||||
int _movingItems;
|
int _movingItems;
|
||||||
|
@ -142,40 +146,41 @@ public:
|
||||||
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
||||||
glm::vec3& penetration, void** penetratedObject) const;
|
glm::vec3& penetration, void** penetratedObject) const;
|
||||||
|
|
||||||
const QList<EntityItem*>& getEntities() const { return *_entityItems; }
|
const EntityItems& getEntities() const { return *_entityItems; }
|
||||||
QList<EntityItem*>& getEntities() { return *_entityItems; }
|
EntityItems& getEntities() { return *_entityItems; }
|
||||||
|
|
||||||
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
||||||
|
|
||||||
void setTree(EntityTree* tree) { _myTree = tree; }
|
void setTree(EntityTree* tree) { _myTree = tree; }
|
||||||
|
|
||||||
bool updateEntity(const EntityItem& entity);
|
bool updateEntity(const EntityItem& entity);
|
||||||
void addEntityItem(EntityItem* entity);
|
void addEntityItem(EntityItemPointer entity);
|
||||||
|
|
||||||
const EntityItem* getClosestEntity(glm::vec3 position) const;
|
EntityItemPointer getClosestEntity(glm::vec3 position) const;
|
||||||
|
|
||||||
/// finds all entities that touch a sphere
|
/// finds all entities that touch a sphere
|
||||||
/// \param position the center of the query sphere
|
/// \param position the center of the query sphere
|
||||||
/// \param radius the radius of the query sphere
|
/// \param radius the radius of the query sphere
|
||||||
/// \param entities[out] vector of const EntityItem*
|
/// \param entities[out] vector of const EntityItemPointer
|
||||||
void getEntities(const glm::vec3& position, float radius, QVector<const EntityItem*>& foundEntities) const;
|
void getEntities(const glm::vec3& position, float radius, QVector<EntityItemPointer>& foundEntities) const;
|
||||||
|
|
||||||
/// finds all entities that touch a box
|
/// finds all entities that touch a box
|
||||||
/// \param box the query box
|
/// \param box the query box
|
||||||
/// \param entities[out] vector of non-const EntityItem*
|
/// \param entities[out] vector of non-const EntityItemPointer
|
||||||
void getEntities(const AACube& box, QVector<EntityItem*>& foundEntities);
|
void getEntities(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
const EntityItem* getEntityWithID(uint32_t id) const;
|
EntityItemPointer getEntityWithID(uint32_t id) const;
|
||||||
const EntityItem* getEntityWithEntityItemID(const EntityItemID& id) const;
|
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
||||||
void getEntitiesInside(const AACube& box, QVector<EntityItem*>& foundEntities);
|
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
EntityItem* getEntityWithEntityItemID(const EntityItemID& id);
|
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id);
|
||||||
|
|
||||||
void cleanupEntities(); /// called by EntityTree on cleanup this will free all entities
|
void cleanupEntities(); /// called by EntityTree on cleanup this will free all entities
|
||||||
bool removeEntityWithEntityItemID(const EntityItemID& id);
|
bool removeEntityWithEntityItemID(const EntityItemID& id);
|
||||||
bool removeEntityItem(EntityItem* entity);
|
bool removeEntityItem(EntityItemPointer entity);
|
||||||
|
|
||||||
bool containsEntityBounds(const EntityItem* entity) const;
|
bool containsEntityBounds(EntityItemPointer entity) const;
|
||||||
bool bestFitEntityBounds(const EntityItem* entity) const;
|
bool bestFitEntityBounds(EntityItemPointer entity) const;
|
||||||
|
|
||||||
bool containsBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
|
bool containsBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
|
||||||
bool bestFitBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
|
bool bestFitBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
|
||||||
|
@ -198,7 +203,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual void init(unsigned char * octalCode);
|
virtual void init(unsigned char * octalCode);
|
||||||
EntityTree* _myTree;
|
EntityTree* _myTree;
|
||||||
QList<EntityItem*>* _entityItems;
|
EntityItems* _entityItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityTreeElement_h
|
#endif // hifi_EntityTreeElement_h
|
||||||
|
|
|
@ -76,9 +76,9 @@ bool EntityTypes::registerEntityType(EntityType entityType, const char* name, En
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
|
EntityItemPointer EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
|
||||||
const EntityItemProperties& properties) {
|
const EntityItemProperties& properties) {
|
||||||
EntityItem* newEntityItem = NULL;
|
EntityItemPointer newEntityItem = NULL;
|
||||||
EntityTypeFactory factory = NULL;
|
EntityTypeFactory factory = NULL;
|
||||||
if (entityType >= 0 && entityType <= LAST) {
|
if (entityType >= 0 && entityType <= LAST) {
|
||||||
factory = _factories[entityType];
|
factory = _factories[entityType];
|
||||||
|
@ -91,7 +91,7 @@ EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const Entity
|
||||||
return newEntityItem;
|
return newEntityItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItem* EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead,
|
EntityItemPointer EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead,
|
||||||
ReadBitstreamToTreeParams& args) {
|
ReadBitstreamToTreeParams& args) {
|
||||||
|
|
||||||
if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) {
|
if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) {
|
||||||
|
|
|
@ -20,11 +20,17 @@
|
||||||
#include <OctreeRenderer.h> // for RenderArgs
|
#include <OctreeRenderer.h> // for RenderArgs
|
||||||
|
|
||||||
class EntityItem;
|
class EntityItem;
|
||||||
|
typedef std::shared_ptr<EntityItem> EntityItemPointer;
|
||||||
|
|
||||||
|
inline uint qHash(const EntityItemPointer& a, uint seed) {
|
||||||
|
return qHash(a.get(), seed);
|
||||||
|
}
|
||||||
|
|
||||||
class EntityItemID;
|
class EntityItemID;
|
||||||
class EntityItemProperties;
|
class EntityItemProperties;
|
||||||
class ReadBitstreamToTreeParams;
|
class ReadBitstreamToTreeParams;
|
||||||
|
|
||||||
typedef EntityItem* (*EntityTypeFactory)(const EntityItemID& entityID, const EntityItemProperties& properties);
|
typedef EntityItemPointer (*EntityTypeFactory)(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
class EntityTypes {
|
class EntityTypes {
|
||||||
public:
|
public:
|
||||||
|
@ -45,8 +51,8 @@ public:
|
||||||
static const QString& getEntityTypeName(EntityType entityType);
|
static const QString& getEntityTypeName(EntityType entityType);
|
||||||
static EntityTypes::EntityType getEntityTypeFromName(const QString& name);
|
static EntityTypes::EntityType getEntityTypeFromName(const QString& name);
|
||||||
static bool registerEntityType(EntityType entityType, const char* name, EntityTypeFactory factoryMethod);
|
static bool registerEntityType(EntityType entityType, const char* name, EntityTypeFactory factoryMethod);
|
||||||
static EntityItem* constructEntityItem(EntityType entityType, const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer constructEntityItem(EntityType entityType, const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
static EntityItem* constructEntityItem(const unsigned char* data, int bytesToRead, ReadBitstreamToTreeParams& args);
|
static EntityItemPointer constructEntityItem(const unsigned char* data, int bytesToRead, ReadBitstreamToTreeParams& args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QMap<EntityType, QString> _typeToNameMap;
|
static QMap<EntityType, QString> _typeToNameMap;
|
||||||
|
@ -59,7 +65,7 @@ private:
|
||||||
/// Macro for registering entity types. Make sure to add an element to the EntityType enum with your name, and your class should be
|
/// Macro for registering entity types. Make sure to add an element to the EntityType enum with your name, and your class should be
|
||||||
/// named NameEntityItem and must of a static method called factory that takes an EnityItemID, and EntityItemProperties and return a newly
|
/// named NameEntityItem and must of a static method called factory that takes an EnityItemID, and EntityItemProperties and return a newly
|
||||||
/// constructed (heap allocated) instance of your type. e.g. The following prototype:
|
/// constructed (heap allocated) instance of your type. e.g. The following prototype:
|
||||||
// static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
// static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
#define REGISTER_ENTITY_TYPE(x) static bool x##Registration = \
|
#define REGISTER_ENTITY_TYPE(x) static bool x##Registration = \
|
||||||
EntityTypes::registerEntityType(EntityTypes::x, #x, x##EntityItem::factory);
|
EntityTypes::registerEntityType(EntityTypes::x, #x, x##EntityItem::factory);
|
||||||
|
|
||||||
|
@ -67,7 +73,7 @@ private:
|
||||||
/// an element to the EntityType enum with your name. But unlike REGISTER_ENTITY_TYPE, your class can be named anything
|
/// an element to the EntityType enum with your name. But unlike REGISTER_ENTITY_TYPE, your class can be named anything
|
||||||
/// so long as you provide a static method passed to the macro, that takes an EnityItemID, and EntityItemProperties and
|
/// so long as you provide a static method passed to the macro, that takes an EnityItemID, and EntityItemProperties and
|
||||||
/// returns a newly constructed (heap allocated) instance of your type. e.g. The following prototype:
|
/// returns a newly constructed (heap allocated) instance of your type. e.g. The following prototype:
|
||||||
// static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
// static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
#define REGISTER_ENTITY_TYPE_WITH_FACTORY(x,y) static bool x##Registration = \
|
#define REGISTER_ENTITY_TYPE_WITH_FACTORY(x,y) static bool x##Registration = \
|
||||||
EntityTypes::registerEntityType(EntityTypes::x, #x, y); \
|
EntityTypes::registerEntityType(EntityTypes::x, #x, y); \
|
||||||
if (!x##Registration) { \
|
if (!x##Registration) { \
|
||||||
|
|
|
@ -22,8 +22,9 @@
|
||||||
|
|
||||||
bool LightEntityItem::_lightsArePickable = false;
|
bool LightEntityItem::_lightsArePickable = false;
|
||||||
|
|
||||||
EntityItem* LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new LightEntityItem(entityID, properties);
|
EntityItemPointer result { new LightEntityItem(entityID, properties) };
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// our non-pure virtual subclass for now...
|
// our non-pure virtual subclass for now...
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class LightEntityItem : public EntityItem {
|
class LightEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
LightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
LightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include "EntityTreeElement.h"
|
#include "EntityTreeElement.h"
|
||||||
|
|
||||||
|
|
||||||
EntityItem* LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItem* result = new LineEntityItem(entityID, properties);
|
EntityItemPointer result { new LineEntityItem(entityID, properties) };
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class LineEntityItem : public EntityItem {
|
class LineEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
LineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
LineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ const bool ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false;
|
||||||
const float ModelEntityItem::DEFAULT_ANIMATION_FPS = 30.0f;
|
const float ModelEntityItem::DEFAULT_ANIMATION_FPS = 30.0f;
|
||||||
|
|
||||||
|
|
||||||
EntityItem* ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new ModelEntityItem(entityID, properties);
|
return EntityItemPointer(new ModelEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
class ModelEntityItem : public EntityItem {
|
class ModelEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ MovingEntitiesOperator::~MovingEntitiesOperator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACube& newCube) {
|
void MovingEntitiesOperator::addEntityToMoveList(EntityItemPointer entity, const AACube& newCube) {
|
||||||
EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID());
|
EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID());
|
||||||
AABox newCubeClamped = newCube.clamp(0.0f, (float)TREE_SCALE);
|
AABox newCubeClamped = newCube.clamp(0.0f, (float)TREE_SCALE);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
class EntityToMoveDetails {
|
class EntityToMoveDetails {
|
||||||
public:
|
public:
|
||||||
EntityItem* entity;
|
EntityItemPointer entity;
|
||||||
AACube oldCube; // meters
|
AACube oldCube; // meters
|
||||||
AACube newCube; // meters
|
AACube newCube; // meters
|
||||||
AABox newCubeClamped; // meters
|
AABox newCubeClamped; // meters
|
||||||
|
@ -37,7 +37,7 @@ public:
|
||||||
MovingEntitiesOperator(EntityTree* tree);
|
MovingEntitiesOperator(EntityTree* tree);
|
||||||
~MovingEntitiesOperator();
|
~MovingEntitiesOperator();
|
||||||
|
|
||||||
void addEntityToMoveList(EntityItem* entity, const AACube& newCube);
|
void addEntityToMoveList(EntityItemPointer entity, const AACube& newCube);
|
||||||
virtual bool preRecursion(OctreeElement* element);
|
virtual bool preRecursion(OctreeElement* element);
|
||||||
virtual bool postRecursion(OctreeElement* element);
|
virtual bool postRecursion(OctreeElement* element);
|
||||||
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
||||||
|
|
|
@ -55,8 +55,8 @@ const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f;
|
||||||
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
|
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
|
||||||
|
|
||||||
|
|
||||||
EntityItem* ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new ParticleEffectEntityItem(entityID, properties);
|
return EntityItemPointer(new ParticleEffectEntityItem(entityID, properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
// our non-pure virtual subclass for now...
|
// our non-pure virtual subclass for now...
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
class ParticleEffectEntityItem : public EntityItem {
|
class ParticleEffectEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
ParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
ParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
virtual ~ParticleEffectEntityItem();
|
virtual ~ParticleEffectEntityItem();
|
||||||
|
|
|
@ -43,11 +43,11 @@ bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
||||||
EntityItemProperties defaultProperties;
|
EntityItemProperties defaultProperties;
|
||||||
|
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
const EntityItems& entities = entityTreeElement->getEntities();
|
||||||
|
|
||||||
QVariantList entitiesQList = qvariant_cast<QVariantList>(_map["Entities"]);
|
QVariantList entitiesQList = qvariant_cast<QVariantList>(_map["Entities"]);
|
||||||
|
|
||||||
foreach (EntityItem* entityItem, entities) {
|
foreach (EntityItemPointer entityItem, entities) {
|
||||||
EntityItemProperties properties = entityItem->getProperties();
|
EntityItemProperties properties = entityItem->getProperties();
|
||||||
QScriptValue qScriptValues;
|
QScriptValue qScriptValues;
|
||||||
if (_skipDefaultValues) {
|
if (_skipDefaultValues) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
||||||
|
|
||||||
SetOfEntities::iterator itemItr = _hasSimulationOwnerEntities.begin();
|
SetOfEntities::iterator itemItr = _hasSimulationOwnerEntities.begin();
|
||||||
while (itemItr != _hasSimulationOwnerEntities.end()) {
|
while (itemItr != _hasSimulationOwnerEntities.end()) {
|
||||||
EntityItem* entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
if (entity->getSimulatorID().isNull()) {
|
if (entity->getSimulatorID().isNull()) {
|
||||||
itemItr = _hasSimulationOwnerEntities.erase(itemItr);
|
itemItr = _hasSimulationOwnerEntities.erase(itemItr);
|
||||||
} else if (now - entity->getLastChangedOnServer() >= AUTO_REMOVE_SIMULATION_OWNER_USEC) {
|
} else if (now - entity->getLastChangedOnServer() >= AUTO_REMOVE_SIMULATION_OWNER_USEC) {
|
||||||
|
@ -44,18 +44,18 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleEntitySimulation::addEntityInternal(EntityItem* entity) {
|
void SimpleEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||||
EntitySimulation::addEntityInternal(entity);
|
EntitySimulation::addEntityInternal(entity);
|
||||||
if (!entity->getSimulatorID().isNull()) {
|
if (!entity->getSimulatorID().isNull()) {
|
||||||
_hasSimulationOwnerEntities.insert(entity);
|
_hasSimulationOwnerEntities.insert(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleEntitySimulation::removeEntityInternal(EntityItem* entity) {
|
void SimpleEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||||
_hasSimulationOwnerEntities.remove(entity);
|
_hasSimulationOwnerEntities.remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleEntitySimulation::changeEntityInternal(EntityItem* entity) {
|
void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||||
EntitySimulation::changeEntityInternal(entity);
|
EntitySimulation::changeEntityInternal(entity);
|
||||||
if (!entity->getSimulatorID().isNull()) {
|
if (!entity->getSimulatorID().isNull()) {
|
||||||
_hasSimulationOwnerEntities.insert(entity);
|
_hasSimulationOwnerEntities.insert(entity);
|
||||||
|
|
|
@ -23,9 +23,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void updateEntitiesInternal(const quint64& now);
|
virtual void updateEntitiesInternal(const quint64& now);
|
||||||
virtual void addEntityInternal(EntityItem* entity);
|
virtual void addEntityInternal(EntityItemPointer entity);
|
||||||
virtual void removeEntityInternal(EntityItem* entity);
|
virtual void removeEntityInternal(EntityItemPointer entity);
|
||||||
virtual void changeEntityInternal(EntityItem* entity);
|
virtual void changeEntityInternal(EntityItemPointer entity);
|
||||||
virtual void clearEntitiesInternal();
|
virtual void clearEntitiesInternal();
|
||||||
|
|
||||||
SetOfEntities _hasSimulationOwnerEntities;
|
SetOfEntities _hasSimulationOwnerEntities;
|
||||||
|
|
|
@ -23,8 +23,9 @@
|
||||||
#include "SphereEntityItem.h"
|
#include "SphereEntityItem.h"
|
||||||
|
|
||||||
|
|
||||||
EntityItem* SphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer SphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return new SphereEntityItem(entityID, properties);
|
EntityItemPointer result { new SphereEntityItem(entityID, properties) };
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// our non-pure virtual subclass for now...
|
// our non-pure virtual subclass for now...
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class SphereEntityItem : public EntityItem {
|
class SphereEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
SphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
SphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,8 @@ const float TextEntityItem::DEFAULT_LINE_HEIGHT = 0.1f;
|
||||||
const xColor TextEntityItem::DEFAULT_TEXT_COLOR = { 255, 255, 255 };
|
const xColor TextEntityItem::DEFAULT_TEXT_COLOR = { 255, 255, 255 };
|
||||||
const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0};
|
const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0};
|
||||||
|
|
||||||
EntityItem* TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItem* result = new TextEntityItem(entityID, properties);
|
return EntityItemPointer(new TextEntityItem(entityID, properties));
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
class TextEntityItem : public EntityItem {
|
class TextEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
||||||
EntityTreeElement* containingElement,
|
EntityTreeElement* containingElement,
|
||||||
EntityItem* existingEntity,
|
EntityItemPointer existingEntity,
|
||||||
const EntityItemProperties& properties) :
|
const EntityItemProperties& properties) :
|
||||||
_tree(tree),
|
_tree(tree),
|
||||||
_existingEntity(existingEntity),
|
_existingEntity(existingEntity),
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
class UpdateEntityOperator : public RecurseOctreeOperator {
|
class UpdateEntityOperator : public RecurseOctreeOperator {
|
||||||
public:
|
public:
|
||||||
UpdateEntityOperator(EntityTree* tree, EntityTreeElement* containingElement,
|
UpdateEntityOperator(EntityTree* tree, EntityTreeElement* containingElement,
|
||||||
EntityItem* existingEntity, const EntityItemProperties& properties);
|
EntityItemPointer existingEntity, const EntityItemProperties& properties);
|
||||||
~UpdateEntityOperator();
|
~UpdateEntityOperator();
|
||||||
|
|
||||||
virtual bool preRecursion(OctreeElement* element);
|
virtual bool preRecursion(OctreeElement* element);
|
||||||
|
@ -23,7 +23,7 @@ public:
|
||||||
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
||||||
private:
|
private:
|
||||||
EntityTree* _tree;
|
EntityTree* _tree;
|
||||||
EntityItem* _existingEntity;
|
EntityItemPointer _existingEntity;
|
||||||
EntityTreeElement* _containingElement;
|
EntityTreeElement* _containingElement;
|
||||||
AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element
|
AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element
|
||||||
EntityItemProperties _properties;
|
EntityItemProperties _properties;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue