mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-06 18:01:03 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels
This commit is contained in:
commit
e9be9537a4
32 changed files with 691 additions and 170 deletions
126
examples/avatarLocalLight.js
Normal file
126
examples/avatarLocalLight.js
Normal file
|
@ -0,0 +1,126 @@
|
|||
//
|
||||
// avatarLocalLight.js
|
||||
//
|
||||
// Created by Tony Peng on July 2nd, 2014
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Set the local light direction and color on the avatar
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var localLightDirections = [ {x: 1.0, y:0.0, z: 0.0}, {x: 0.0, y:1.0, z: 1.0}, {x: 0.0, y:0.0, z: 1.0}, {x: 1.0, y:1.0, z: 1.0} ];
|
||||
var localLightColors = [ {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0} ];
|
||||
|
||||
var currentSelection = 0;
|
||||
var currentNumLights = 1;
|
||||
var maxNumLights = 2;
|
||||
|
||||
function keyPressEvent(event) {
|
||||
|
||||
var choice = parseInt(event.text);
|
||||
|
||||
if (event.text == "1") {
|
||||
currentSelection = 0;
|
||||
print("light election = " + currentSelection);
|
||||
}
|
||||
else if (event.text == "2" ) {
|
||||
currentSelection = 1;
|
||||
print("light selection = " + currentSelection);
|
||||
}
|
||||
else if (event.text == "3" ) {
|
||||
currentSelection = 2;
|
||||
print("light selection = " + currentSelection);
|
||||
}
|
||||
else if (event.text == "4" ) {
|
||||
currentSelection = 3;
|
||||
print("light selection = " + currentSelection);
|
||||
}
|
||||
else if (event.text == "5" ) {
|
||||
localLightColors[currentSelection].x += 0.01;
|
||||
if ( localLightColors[currentSelection].x > 1.0) {
|
||||
localLightColors[currentSelection].x = 0.0;
|
||||
}
|
||||
|
||||
MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection);
|
||||
}
|
||||
else if (event.text == "6" ) {
|
||||
localLightColors[currentSelection].y += 0.01;
|
||||
if ( localLightColors[currentSelection].y > 1.0) {
|
||||
localLightColors[currentSelection].y = 0.0;
|
||||
}
|
||||
|
||||
MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection);
|
||||
}
|
||||
else if (event.text == "7" ) {
|
||||
localLightColors[currentSelection].z += 0.01;
|
||||
if ( localLightColors[currentSelection].z > 1.0) {
|
||||
localLightColors[currentSelection].z = 0.0;
|
||||
}
|
||||
|
||||
MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection);
|
||||
}
|
||||
else if (event.text == "8" ) {
|
||||
localLightDirections[currentSelection].x += 0.01;
|
||||
if (localLightDirections[currentSelection].x > 1.0) {
|
||||
localLightDirections[currentSelection].x = -1.0;
|
||||
}
|
||||
|
||||
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||
}
|
||||
else if (event.text == "9" ) {
|
||||
localLightDirections[currentSelection].x -= 0.01;
|
||||
if (localLightDirections[currentSelection].x < -1.0) {
|
||||
localLightDirections[currentSelection].x = 1.0;
|
||||
}
|
||||
|
||||
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||
}
|
||||
else if (event.text == "[" ) {
|
||||
localLightDirections[currentSelection].y += 0.01;
|
||||
if (localLightDirections[currentSelection].y > 1.0) {
|
||||
localLightDirections[currentSelection].y = -1.0;
|
||||
}
|
||||
|
||||
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||
}
|
||||
else if (event.text == "]" ) {
|
||||
localLightDirections[currentSelection].y -= 0.01;
|
||||
if (localLightDirections[currentSelection].y < -1.0) {
|
||||
localLightDirections[currentSelection].y = 1.0;
|
||||
}
|
||||
|
||||
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||
}
|
||||
else if (event.text == "," ) {
|
||||
if (currentNumLights + 1 <= maxNumLights) {
|
||||
var darkGrayColor = {x:0.3, y:0.3, z:0.3};
|
||||
|
||||
// default light
|
||||
localLightColors[currentNumLights].x = darkGrayColor.x;
|
||||
localLightColors[currentNumLights].y = darkGrayColor.y;
|
||||
localLightColors[currentNumLights].z = darkGrayColor.z;
|
||||
|
||||
MyAvatar.addLocalLight();
|
||||
MyAvatar.setLocalLightColor(localLightColors[currentNumLights], currentNumLights);
|
||||
MyAvatar.setLocalLightDirection(localLightDirections[currentNumLights], currentNumLights);
|
||||
|
||||
++currentNumLights;
|
||||
}
|
||||
}
|
||||
else if (event.text == "." ) {
|
||||
if (currentNumLights - 1 >= 0 ) {
|
||||
|
||||
// no light contribution
|
||||
localLightColors[currentNumLights - 1].x = 0.0;
|
||||
localLightColors[currentNumLights - 1].y = 0.0;
|
||||
localLightColors[currentNumLights - 1].z = 0.0;
|
||||
|
||||
MyAvatar.removeLocalLight();
|
||||
--currentNumLights;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
72
examples/concertCamera_kims.js
Normal file
72
examples/concertCamera_kims.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// concertCamera.js
|
||||
//
|
||||
// Created by Philip Rosedale on June 24, 2014
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Move a camera through a series of pre-set locations by pressing number keys
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var oldMode;
|
||||
var avatarPosition;
|
||||
|
||||
var cameraNumber = 0;
|
||||
var freeCamera = false;
|
||||
|
||||
var cameraLocations = [ {x: 8027.5, y: 237.5, z: 7305.7}, {x: 8027.5, y: 237.5, z: 7306.6}, {x: 8027.5, y: 237.5, z: 7308.0}, {x: 8027.5, y: 237.5, z: 7303.0}, {x: 8030.8, y: 238.6, z: 7311.4}, {x: 8030.9, y: 237.1, z: 7308.0} ];
|
||||
var cameraLookAts = [ {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7305.7}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0}, {x: 8027.5, y: 237.5, z: 7304.0} ];
|
||||
|
||||
function saveCameraState() {
|
||||
oldMode = Camera.getMode();
|
||||
avatarPosition = MyAvatar.position;
|
||||
Camera.setModeShiftPeriod(0.0);
|
||||
Camera.setMode("independent");
|
||||
}
|
||||
|
||||
function restoreCameraState() {
|
||||
Camera.stopLooking();
|
||||
Camera.setMode(oldMode);
|
||||
}
|
||||
|
||||
function update(deltaTime) {
|
||||
if (freeCamera) {
|
||||
var delta = Vec3.subtract(MyAvatar.position, avatarPosition);
|
||||
if (Vec3.length(delta) > 0.05) {
|
||||
cameraNumber = 0;
|
||||
freeCamera = false;
|
||||
restoreCameraState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function keyPressEvent(event) {
|
||||
|
||||
var choice = parseInt(event.text);
|
||||
|
||||
if ((choice > 0) && (choice <= cameraLocations.length)) {
|
||||
print("camera " + choice);
|
||||
if (!freeCamera) {
|
||||
saveCameraState();
|
||||
freeCamera = true;
|
||||
}
|
||||
Camera.setMode("independent");
|
||||
Camera.setPosition(cameraLocations[choice - 1]);
|
||||
Camera.keepLookingAt(cameraLookAts[choice - 1]);
|
||||
}
|
||||
if (event.text == "ESC") {
|
||||
cameraNumber = 0;
|
||||
freeCamera = false;
|
||||
restoreCameraState();
|
||||
}
|
||||
if (event.text == "0") {
|
||||
// Show camera location in log
|
||||
var cameraLocation = Camera.getPosition();
|
||||
print(cameraLocation.x + ", " + cameraLocation.y + ", " + cameraLocation.z);
|
||||
}
|
||||
}
|
||||
|
||||
Script.update.connect(update);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
72
examples/concertCamera_kyrs.js
Normal file
72
examples/concertCamera_kyrs.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// concertCamera.js
|
||||
//
|
||||
// Created by Philip Rosedale on June 24, 2014
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Move a camera through a series of pre-set locations by pressing number keys
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var oldMode;
|
||||
var avatarPosition;
|
||||
|
||||
var cameraNumber = 0;
|
||||
var freeCamera = false;
|
||||
|
||||
var cameraLocations = [ {x: 2921.5, y: 251.3, z: 8254.8}, {x: 2921.5, y: 251.3, z: 8254.4}, {x: 2921.5, y: 251.3, z: 8252.2}, {x: 2921.5, y: 251.3, z: 8247.2}, {x: 2921.4, y: 251.3, z: 8255.7} ];
|
||||
var cameraLookAts = [ {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.5, y: 251.3, z: 8255.7}, {x: 2921.4 , y: 251.3, z: 8255.1} ];
|
||||
|
||||
function saveCameraState() {
|
||||
oldMode = Camera.getMode();
|
||||
avatarPosition = MyAvatar.position;
|
||||
Camera.setModeShiftPeriod(0.0);
|
||||
Camera.setMode("independent");
|
||||
}
|
||||
|
||||
function restoreCameraState() {
|
||||
Camera.stopLooking();
|
||||
Camera.setMode(oldMode);
|
||||
}
|
||||
|
||||
function update(deltaTime) {
|
||||
if (freeCamera) {
|
||||
var delta = Vec3.subtract(MyAvatar.position, avatarPosition);
|
||||
if (Vec3.length(delta) > 0.05) {
|
||||
cameraNumber = 0;
|
||||
freeCamera = false;
|
||||
restoreCameraState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function keyPressEvent(event) {
|
||||
|
||||
var choice = parseInt(event.text);
|
||||
|
||||
if ((choice > 0) && (choice <= cameraLocations.length)) {
|
||||
print("camera " + choice);
|
||||
if (!freeCamera) {
|
||||
saveCameraState();
|
||||
freeCamera = true;
|
||||
}
|
||||
Camera.setMode("independent");
|
||||
Camera.setPosition(cameraLocations[choice - 1]);
|
||||
Camera.keepLookingAt(cameraLookAts[choice - 1]);
|
||||
}
|
||||
if (event.text == "ESC") {
|
||||
cameraNumber = 0;
|
||||
freeCamera = false;
|
||||
restoreCameraState();
|
||||
}
|
||||
if (event.text == "0") {
|
||||
// Show camera location in log
|
||||
var cameraLocation = Camera.getPosition();
|
||||
print(cameraLocation.x + ", " + cameraLocation.y + ", " + cameraLocation.z);
|
||||
}
|
||||
}
|
||||
|
||||
Script.update.connect(update);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
|
@ -11,9 +11,16 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// local lights
|
||||
const int MAX_LOCAL_LIGHTS = 2; // 2 lights for now, will probably need more later on
|
||||
uniform int numLocalLights;
|
||||
uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
uniform vec3 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
|
@ -25,8 +32,19 @@ void main(void) {
|
|||
vec4 normalizedNormal = normalize(normal);
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
|
||||
// the local light that is always present
|
||||
vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
for (int i = 0; i < numLocalLights; i++) {
|
||||
float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0));
|
||||
float localLight = step(0.0, localDiffuse);
|
||||
float localLightVal = localDiffuse * localLight;
|
||||
|
||||
totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0));
|
||||
}
|
||||
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + totalLocalLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
const int MAX_LOCAL_LIGHTS = 4;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
|
@ -37,3 +39,4 @@ void main(void) {
|
|||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
||||
|
|
|
@ -37,9 +37,14 @@ void main(void) {
|
|||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
float localDiffuse = dot(viewNormal, gl_LightSource[1].position);
|
||||
float localLight = step(0.0, localDiffuse);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + gl_FrontLightProduct[1].diffuse * (localDiffuse * localLight));
|
||||
|
||||
|
||||
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||
normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal));
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
uniform int numLocalLights;
|
||||
uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
uniform vec3 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
@ -28,8 +33,19 @@ void main(void) {
|
|||
vec4 normalizedNormal = normalize(normal);
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
|
||||
// the local light that is always present
|
||||
vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
for (int i = 0; i < numLocalLights; i++) {
|
||||
float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0));
|
||||
float localLight = step(0.0, localDiffuse);
|
||||
float localLightVal = localDiffuse * localLight;
|
||||
|
||||
totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0));
|
||||
}
|
||||
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + totalLocalLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
|
@ -38,4 +54,5 @@ void main(void) {
|
|||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) *
|
||||
gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0);
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ void main(void) {
|
|||
position += clusterMatrix * gl_Vertex * clusterWeight;
|
||||
normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight;
|
||||
}
|
||||
|
||||
position = gl_ModelViewMatrix * position;
|
||||
normal = normalize(gl_ModelViewMatrix * normal);
|
||||
|
||||
|
|
|
@ -604,9 +604,19 @@ void Application::paintGL() {
|
|||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
_myCamera.setTightness(0.0f);
|
||||
_myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||
_myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||
_myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0));
|
||||
//Only behave like a true mirror when in the OR
|
||||
if (OculusManager::isConnected()) {
|
||||
_myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||
_myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||
_myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition() + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0));
|
||||
} else {
|
||||
_myCamera.setTightness(0.0f);
|
||||
glm::vec3 eyePosition = _myAvatar->getHead()->calculateAverageEyePosition();
|
||||
float headHeight = eyePosition.y - _myAvatar->getPosition().y;
|
||||
_myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||
_myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight + (_raiseMirror * _myAvatar->getScale()), 0));
|
||||
_myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||
}
|
||||
}
|
||||
|
||||
// Update camera position
|
||||
|
@ -685,7 +695,7 @@ void Application::paintGL() {
|
|||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("paintGL/renderOverlay");
|
||||
PerformanceTimer perfTimer("renderOverlay");
|
||||
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
|
||||
_applicationOverlay.renderOverlay(true);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) {
|
||||
|
@ -1359,18 +1369,18 @@ void Application::idle() {
|
|||
if (timeSinceLastUpdate > IDLE_SIMULATE_MSECS) {
|
||||
_lastTimeUpdated.start();
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update");
|
||||
PerformanceTimer perfTimer("update");
|
||||
PerformanceWarning warn(showWarnings, "Application::idle()... update()");
|
||||
const float BIGGEST_DELTA_TIME_SECS = 0.25f;
|
||||
update(glm::clamp((float)timeSinceLastUpdate / 1000.f, 0.f, BIGGEST_DELTA_TIME_SECS));
|
||||
}
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/updateGL");
|
||||
PerformanceTimer perfTimer("updateGL");
|
||||
PerformanceWarning warn(showWarnings, "Application::idle()... updateGL()");
|
||||
_glWidget->updateGL();
|
||||
}
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/rest");
|
||||
PerformanceTimer perfTimer("rest");
|
||||
PerformanceWarning warn(showWarnings, "Application::idle()... rest of it");
|
||||
_idleLoopStdev.addValue(timeSinceLastUpdate);
|
||||
|
||||
|
@ -1382,7 +1392,7 @@ void Application::idle() {
|
|||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
|
||||
PerformanceTimer perfTimer("idle/rest/_buckyBalls");
|
||||
PerformanceTimer perfTimer("buckyBalls");
|
||||
_buckyBalls.simulate(timeSinceLastUpdate / 1000.f, Application::getInstance()->getAvatar()->getHandData());
|
||||
}
|
||||
|
||||
|
@ -1800,7 +1810,7 @@ bool Application::isLookingAtMyAvatar(Avatar* avatar) {
|
|||
}
|
||||
|
||||
void Application::updateLOD() {
|
||||
PerformanceTimer perfTimer("idle/update/updateLOD");
|
||||
PerformanceTimer perfTimer("LOD");
|
||||
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD) && !isThrottleRendering()) {
|
||||
Menu::getInstance()->autoAdjustLOD(_fps);
|
||||
|
@ -1810,7 +1820,7 @@ void Application::updateLOD() {
|
|||
}
|
||||
|
||||
void Application::updateMouseRay() {
|
||||
PerformanceTimer perfTimer("idle/update/updateMouseRay");
|
||||
PerformanceTimer perfTimer("mouseRay");
|
||||
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
|
||||
|
@ -1843,8 +1853,6 @@ void Application::updateMouseRay() {
|
|||
}
|
||||
|
||||
void Application::updateFaceshift() {
|
||||
PerformanceTimer perfTimer("idle/update/updateFaceshift");
|
||||
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateFaceshift()");
|
||||
|
||||
|
@ -1858,8 +1866,6 @@ void Application::updateFaceshift() {
|
|||
}
|
||||
|
||||
void Application::updateVisage() {
|
||||
PerformanceTimer perfTimer("idle/update/updateVisage");
|
||||
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateVisage()");
|
||||
|
||||
|
@ -1868,11 +1874,11 @@ void Application::updateVisage() {
|
|||
}
|
||||
|
||||
void Application::updateMyAvatarLookAtPosition() {
|
||||
PerformanceTimer perfTimer("idle/update/updateMyAvatarLookAtPosition");
|
||||
|
||||
PerformanceTimer perfTimer("lookAt");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()");
|
||||
|
||||
_myAvatar->updateLookAtTargetAvatar();
|
||||
FaceTracker* tracker = getActiveFaceTracker();
|
||||
|
||||
bool isLookingAtSomeone = false;
|
||||
|
@ -1935,7 +1941,7 @@ void Application::updateMyAvatarLookAtPosition() {
|
|||
}
|
||||
|
||||
void Application::updateThreads(float deltaTime) {
|
||||
PerformanceTimer perfTimer("idle/update/updateThreads");
|
||||
PerformanceTimer perfTimer("updateThreads");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateThreads()");
|
||||
|
||||
|
@ -1950,7 +1956,7 @@ void Application::updateThreads(float deltaTime) {
|
|||
}
|
||||
|
||||
void Application::updateMetavoxels(float deltaTime) {
|
||||
PerformanceTimer perfTimer("idle/update/updateMetavoxels");
|
||||
PerformanceTimer perfTimer("updateMetavoxels");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateMetavoxels()");
|
||||
|
||||
|
@ -1980,7 +1986,7 @@ void Application::cameraMenuChanged() {
|
|||
}
|
||||
|
||||
void Application::updateCamera(float deltaTime) {
|
||||
PerformanceTimer perfTimer("idle/update/updateCamera");
|
||||
PerformanceTimer perfTimer("updateCamera");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateCamera()");
|
||||
|
||||
|
@ -1998,7 +2004,7 @@ void Application::updateCamera(float deltaTime) {
|
|||
}
|
||||
|
||||
void Application::updateDialogs(float deltaTime) {
|
||||
PerformanceTimer perfTimer("idle/update/updateDialogs");
|
||||
PerformanceTimer perfTimer("updateDialogs");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateDialogs()");
|
||||
|
||||
|
@ -2015,7 +2021,7 @@ void Application::updateDialogs(float deltaTime) {
|
|||
}
|
||||
|
||||
void Application::updateCursor(float deltaTime) {
|
||||
PerformanceTimer perfTimer("idle/update/updateCursor");
|
||||
PerformanceTimer perfTimer("updateCursor");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateCursor()");
|
||||
|
||||
|
@ -2040,83 +2046,69 @@ void Application::updateCursor(float deltaTime) {
|
|||
}
|
||||
|
||||
void Application::update(float deltaTime) {
|
||||
//PerformanceTimer perfTimer("idle/update"); // NOTE: we track this above in Application::idle()
|
||||
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::update()");
|
||||
|
||||
updateLOD();
|
||||
updateMouseRay(); // check what's under the mouse and update the mouse voxel
|
||||
updateFaceshift();
|
||||
updateVisage();
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/updateLookAtTargetAvatar");
|
||||
_myAvatar->updateLookAtTargetAvatar();
|
||||
}
|
||||
updateMyAvatarLookAtPosition();
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/sixense,joystick,prioVR");
|
||||
PerformanceTimer perfTimer("devices");
|
||||
updateFaceshift();
|
||||
updateVisage();
|
||||
_sixenseManager.update(deltaTime);
|
||||
_joystickManager.update();
|
||||
_prioVR.update(deltaTime);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/updateMyAvatar");
|
||||
PerformanceTimer perfTimer("myAvatar");
|
||||
updateMyAvatarLookAtPosition();
|
||||
updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
||||
}
|
||||
|
||||
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/_avatarManager");
|
||||
_avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them...
|
||||
}
|
||||
_avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them...
|
||||
|
||||
updateMetavoxels(deltaTime); // update metavoxels
|
||||
updateCamera(deltaTime); // handle various camera tweaks like off axis projection
|
||||
updateDialogs(deltaTime); // update various stats dialogs if present
|
||||
updateCursor(deltaTime); // Handle cursor updates
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/_particles");
|
||||
PerformanceTimer perfTimer("particles");
|
||||
_particles.update(); // update the particles...
|
||||
}
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/_particleCollisionSystem");
|
||||
_particleCollisionSystem.update(); // collide the particles...
|
||||
{
|
||||
PerformanceTimer perfTimer("collisions");
|
||||
_particleCollisionSystem.update(); // collide the particles...
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/_models");
|
||||
PerformanceTimer perfTimer("models");
|
||||
_models.update(); // update the models...
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/_overlays");
|
||||
PerformanceTimer perfTimer("overlays");
|
||||
_overlays.update(deltaTime);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("idle/update/emit simulating");
|
||||
PerformanceTimer perfTimer("emitSimulating");
|
||||
// let external parties know we're updating
|
||||
emit simulating(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateMyAvatar(float deltaTime) {
|
||||
PerformanceTimer perfTimer("updateMyAvatar");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateMyAvatar()");
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("updateMyAvatar/_myAvatar->update()");
|
||||
_myAvatar->update(deltaTime);
|
||||
}
|
||||
_myAvatar->update(deltaTime);
|
||||
|
||||
{
|
||||
// send head/hand data to the avatar mixer and voxel server
|
||||
PerformanceTimer perfTimer("updateMyAvatar/sendToAvatarMixer");
|
||||
PerformanceTimer perfTimer("send");
|
||||
QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
||||
packet.append(_myAvatar->toByteArray());
|
||||
controlledBroadcastToNodes(packet, NodeSet() << NodeType::AvatarMixer);
|
||||
|
@ -2129,13 +2121,13 @@ void Application::updateMyAvatar(float deltaTime) {
|
|||
// actually need to calculate the view frustum planes to send these details
|
||||
// to the server.
|
||||
{
|
||||
PerformanceTimer perfTimer("updateMyAvatar/loadViewFrustum");
|
||||
PerformanceTimer perfTimer("loadViewFrustum");
|
||||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
}
|
||||
|
||||
// Update my voxel servers with my current voxel query...
|
||||
{
|
||||
PerformanceTimer perfTimer("updateMyAvatar/queryOctree");
|
||||
PerformanceTimer perfTimer("queryOctree");
|
||||
quint64 now = usecTimestampNow();
|
||||
quint64 sinceLastQuery = now - _lastQueriedTime;
|
||||
const quint64 TOO_LONG_SINCE_LAST_QUERY = 3 * USECS_PER_SECOND;
|
||||
|
@ -2468,7 +2460,7 @@ glm::vec3 Application::getSunDirection() {
|
|||
}
|
||||
|
||||
void Application::updateShadowMap() {
|
||||
PerformanceTimer perfTimer("paintGL/updateShadowMap");
|
||||
PerformanceTimer perfTimer("shadowMap");
|
||||
QOpenGLFramebufferObject* fbo = _textureCache.getShadowFramebufferObject();
|
||||
fbo->bind();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -2630,7 +2622,7 @@ QImage Application::renderAvatarBillboard() {
|
|||
}
|
||||
|
||||
void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide");
|
||||
PerformanceTimer perfTimer("display");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||
// transform by eye offset
|
||||
|
||||
|
@ -2664,7 +2656,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// Setup 3D lights (after the camera transform, so that they are positioned in world space)
|
||||
{
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/setupWorldLight");
|
||||
PerformanceTimer perfTimer("lights");
|
||||
setupWorldLight();
|
||||
}
|
||||
|
||||
|
@ -2683,7 +2675,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
}
|
||||
|
||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/stars");
|
||||
PerformanceTimer perfTimer("stars");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... stars...");
|
||||
if (!_stars.isStarsLoaded()) {
|
||||
|
@ -2712,7 +2704,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// draw the sky dome
|
||||
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/atmosphere");
|
||||
PerformanceTimer perfTimer("atmosphere");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... atmosphere...");
|
||||
_environment.renderAtmospheres(whichCamera);
|
||||
|
@ -2733,13 +2725,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// draw the audio reflector overlay
|
||||
{
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/audioReflector");
|
||||
PerformanceTimer perfTimer("audio");
|
||||
_audioReflector.render();
|
||||
}
|
||||
|
||||
// Draw voxels
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/voxels");
|
||||
PerformanceTimer perfTimer("voxels");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... voxels...");
|
||||
_voxels.render();
|
||||
|
@ -2747,14 +2739,14 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// also, metavoxels
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Metavoxels)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/metavoxels");
|
||||
PerformanceTimer perfTimer("metavoxels");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... metavoxels...");
|
||||
_metavoxels.render();
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/buckyBalls");
|
||||
PerformanceTimer perfTimer("buckyBalls");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... bucky balls...");
|
||||
_buckyBalls.render();
|
||||
|
@ -2762,7 +2754,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// render particles...
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Particles)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/particles");
|
||||
PerformanceTimer perfTimer("particles");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... particles...");
|
||||
_particles.render();
|
||||
|
@ -2770,7 +2762,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// render models...
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Models)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/models");
|
||||
PerformanceTimer perfTimer("models");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... models...");
|
||||
_models.render();
|
||||
|
@ -2778,7 +2770,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// render the ambient occlusion effect if enabled
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/AmbientOcclusion");
|
||||
PerformanceTimer perfTimer("ambientOcclusion");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... AmbientOcclusion...");
|
||||
_ambientOcclusionEffect.render();
|
||||
|
@ -2793,20 +2785,21 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR);
|
||||
{
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/renderAvatars");
|
||||
PerformanceTimer perfTimer("avatars");
|
||||
_avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, selfAvatarOnly);
|
||||
}
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
// Render the world box
|
||||
if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) && Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/renderWorldBox");
|
||||
if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) {
|
||||
PerformanceTimer perfTimer("worldBox");
|
||||
renderWorldBox();
|
||||
}
|
||||
|
||||
// view frustum for debugging
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum) && whichCamera.getMode() != CAMERA_MODE_MIRROR) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/ViewFrustum");
|
||||
PerformanceTimer perfTimer("viewFrustum");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... renderViewFrustum...");
|
||||
renderViewFrustum(_viewFrustum);
|
||||
|
@ -2814,7 +2807,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// render voxel fades if they exist
|
||||
if (_voxelFades.size() > 0) {
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/voxel fades");
|
||||
PerformanceTimer perfTimer("voxelFades");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... voxel fades...");
|
||||
_voxelFadesLock.lockForWrite();
|
||||
|
@ -2831,13 +2824,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
|
||||
// give external parties a change to hook in
|
||||
{
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/inWorldInterface");
|
||||
PerformanceTimer perfTimer("inWorldInterface");
|
||||
emit renderingInWorldInterface();
|
||||
}
|
||||
|
||||
// render JS/scriptable overlays
|
||||
{
|
||||
PerformanceTimer perfTimer("paintGL/displaySide/3dOverlays");
|
||||
PerformanceTimer perfTimer("3dOverlays");
|
||||
_overlays.render3D();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false,
|
||||
appInstance, SLOT(cameraMenuChanged()));
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash, true);
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0,
|
||||
false,
|
||||
|
|
|
@ -439,7 +439,7 @@ namespace MenuOption {
|
|||
const QString UploadAttachment = "Upload Attachment Model";
|
||||
const QString UploadHead = "Upload Head Model";
|
||||
const QString UploadSkeleton = "Upload Skeleton Model";
|
||||
const QString UserInterface = "UserInterface";
|
||||
const QString UserInterface = "User Interface";
|
||||
const QString Visage = "Visage";
|
||||
const QString VoxelMode = "Cycle Voxel Mode";
|
||||
const QString Voxels = "Voxels";
|
||||
|
|
|
@ -14,12 +14,13 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <GeometryUtil.h>
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Avatar.h"
|
||||
|
@ -60,7 +61,8 @@ Avatar::Avatar() :
|
|||
_moving(false),
|
||||
_collisionGroups(0),
|
||||
_initialized(false),
|
||||
_shouldRenderBillboard(true)
|
||||
_shouldRenderBillboard(true),
|
||||
_numLocalLights(1)
|
||||
{
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
moveToThread(Application::getInstance()->thread());
|
||||
|
@ -81,6 +83,23 @@ void Avatar::init() {
|
|||
_initialized = true;
|
||||
_shouldRenderBillboard = (getLODDistance() >= BILLBOARD_LOD_DISTANCE);
|
||||
initializeHair();
|
||||
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
_localLightColors[i] = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
_localLightDirections[i] = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
glm::vec3 darkGrayColor(0.3f, 0.3f, 0.3f);
|
||||
glm::vec3 greenColor(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 directionX(1.0f, 0.0f, 0.0f);
|
||||
glm::vec3 directionY(0.0f, 1.0f, 0.0f);
|
||||
|
||||
// initialize local lights
|
||||
_localLightColors[0] = darkGrayColor;
|
||||
_localLightColors[1] = greenColor;
|
||||
|
||||
_localLightDirections[0] = directionX;
|
||||
_localLightDirections[1] = directionY;
|
||||
}
|
||||
|
||||
glm::vec3 Avatar::getChestPosition() const {
|
||||
|
@ -99,6 +118,7 @@ float Avatar::getLODDistance() const {
|
|||
}
|
||||
|
||||
void Avatar::simulate(float deltaTime) {
|
||||
PerformanceTimer perfTimer("simulate");
|
||||
if (_scale != _targetScale) {
|
||||
setScale(_targetScale);
|
||||
}
|
||||
|
@ -118,29 +138,36 @@ void Avatar::simulate(float deltaTime) {
|
|||
bool inViewFrustum = Application::getInstance()->getViewFrustum()->sphereInFrustum(_position, boundingRadius) !=
|
||||
ViewFrustum::OUTSIDE;
|
||||
|
||||
getHand()->simulate(deltaTime, false);
|
||||
{
|
||||
PerformanceTimer perfTimer("hand");
|
||||
getHand()->simulate(deltaTime, false);
|
||||
}
|
||||
_skeletonModel.setLODDistance(getLODDistance());
|
||||
|
||||
if (!_shouldRenderBillboard && inViewFrustum) {
|
||||
if (_hasNewJointRotations) {
|
||||
PerformanceTimer perfTimer("skeleton");
|
||||
for (int i = 0; i < _jointData.size(); i++) {
|
||||
const JointData& data = _jointData.at(i);
|
||||
_skeletonModel.setJointState(i, data.valid, data.rotation);
|
||||
}
|
||||
_skeletonModel.simulate(deltaTime);
|
||||
}
|
||||
_skeletonModel.simulate(deltaTime, _hasNewJointRotations);
|
||||
simulateAttachments(deltaTime);
|
||||
_hasNewJointRotations = false;
|
||||
{
|
||||
PerformanceTimer perfTimer("head");
|
||||
_skeletonModel.simulate(deltaTime, _hasNewJointRotations);
|
||||
simulateAttachments(deltaTime);
|
||||
_hasNewJointRotations = false;
|
||||
|
||||
glm::vec3 headPosition = _position;
|
||||
_skeletonModel.getHeadPosition(headPosition);
|
||||
Head* head = getHead();
|
||||
head->setPosition(headPosition);
|
||||
head->setScale(_scale);
|
||||
head->simulate(deltaTime, false, _shouldRenderBillboard);
|
||||
|
||||
glm::vec3 headPosition = _position;
|
||||
_skeletonModel.getHeadPosition(headPosition);
|
||||
Head* head = getHead();
|
||||
head->setPosition(headPosition);
|
||||
head->setScale(_scale);
|
||||
head->simulate(deltaTime, false, _shouldRenderBillboard);
|
||||
}
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) {
|
||||
PerformanceTimer perfTimer("hair");
|
||||
simulateHair(deltaTime);
|
||||
}
|
||||
|
||||
|
@ -224,7 +251,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
|||
const float GLOW_DISTANCE = 20.0f;
|
||||
const float GLOW_MAX_LOUDNESS = 2500.0f;
|
||||
const float MAX_GLOW = 0.5f;
|
||||
|
||||
|
||||
float GLOW_FROM_AVERAGE_LOUDNESS = ((this == Application::getInstance()->getAvatar())
|
||||
? 0.0f
|
||||
: MAX_GLOW * getHeadData()->getAudioLoudness() / GLOW_MAX_LOUDNESS);
|
||||
|
@ -235,7 +262,23 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
|||
float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE
|
||||
? 1.0f
|
||||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||
|
||||
|
||||
|
||||
// local lights directions and colors
|
||||
getSkeletonModel().setNumLocalLights(_numLocalLights);
|
||||
getHead()->getFaceModel().setNumLocalLights(_numLocalLights);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
glm::vec3 normalized = glm::normalize(_localLightDirections[i]);
|
||||
|
||||
// body
|
||||
getSkeletonModel().setLocalLightColor(_localLightColors[i], i);
|
||||
getSkeletonModel().setLocalLightDirection(normalized, i);
|
||||
|
||||
// head
|
||||
getHead()->getFaceModel().setLocalLightColor(_localLightColors[i], i);
|
||||
getHead()->getFaceModel().setLocalLightDirection(_localLightDirections[i], i);
|
||||
}
|
||||
|
||||
// render body
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
renderBody(renderMode, glowLevel);
|
||||
|
@ -1114,3 +1157,29 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
|||
|
||||
}
|
||||
|
||||
void Avatar::setLocalLightDirection(const glm::vec3& direction, int lightIndex) {
|
||||
_localLightDirections[lightIndex] = direction;
|
||||
qDebug( "set light %d direction ( %f, %f, %f )\n", lightIndex, direction.x, direction.y, direction.z );
|
||||
}
|
||||
|
||||
void Avatar::setLocalLightColor(const glm::vec3& color, int lightIndex) {
|
||||
_localLightColors[lightIndex] = color;
|
||||
qDebug( "set light %d color ( %f, %f, %f )\n", lightIndex, color.x, color.y, color.z );
|
||||
}
|
||||
|
||||
void Avatar::addLocalLight() {
|
||||
if (_numLocalLights + 1 <= MAX_LOCAL_LIGHTS) {
|
||||
++_numLocalLights;
|
||||
}
|
||||
|
||||
qDebug("ADD LOCAL LIGHT (numLocalLights = %d)\n", _numLocalLights);
|
||||
}
|
||||
|
||||
void Avatar::removeLocalLight() {
|
||||
if (_numLocalLights - 1 >= 0) {
|
||||
--_numLocalLights;
|
||||
}
|
||||
|
||||
qDebug("REMOVE LOCAL LIGHT (numLocalLights = %d)\n", _numLocalLights);
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,11 @@ public:
|
|||
|
||||
public slots:
|
||||
void updateCollisionGroups();
|
||||
|
||||
void setLocalLightDirection(const glm::vec3& direction, int lightIndex);
|
||||
void setLocalLightColor(const glm::vec3& color, int lightIndex);
|
||||
void addLocalLight();
|
||||
void removeLocalLight();
|
||||
|
||||
signals:
|
||||
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
||||
|
||||
|
@ -176,9 +180,14 @@ protected:
|
|||
glm::vec3 _mouseRayDirection;
|
||||
float _stringLength;
|
||||
bool _moving; ///< set when position is changing
|
||||
|
||||
|
||||
quint32 _collisionGroups;
|
||||
|
||||
|
||||
// always-present local lighting for the avatar
|
||||
glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS];
|
||||
int _numLocalLights;
|
||||
|
||||
// protected methods...
|
||||
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
|
||||
|
|
|
@ -41,9 +41,13 @@ void AvatarManager::init() {
|
|||
}
|
||||
|
||||
void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||
if (_avatarHash.size() > 1) {
|
||||
return;
|
||||
}
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
|
||||
|
||||
PerformanceTimer perfTimer("otherAvatars");
|
||||
Application* applicationInstance = Application::getInstance();
|
||||
glm::vec3 mouseOrigin = applicationInstance->getMouseRayOrigin();
|
||||
glm::vec3 mouseDirection = applicationInstance->getMouseRayDirection();
|
||||
|
|
|
@ -108,15 +108,10 @@ void MyAvatar::reset() {
|
|||
}
|
||||
|
||||
void MyAvatar::update(float deltaTime) {
|
||||
PerformanceTimer perfTimer("MyAvatar::update/");
|
||||
Head* head = getHead();
|
||||
head->relaxLean(deltaTime);
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::update/updateFromTrackers");
|
||||
updateFromTrackers(deltaTime);
|
||||
}
|
||||
updateFromTrackers(deltaTime);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::MoveWithLean)) {
|
||||
PerformanceTimer perfTimer("MyAvatar::update/moveWithLean");
|
||||
// Faceshift drive is enabled, set the avatar drive based on the head position
|
||||
moveWithLean();
|
||||
}
|
||||
|
@ -127,19 +122,14 @@ void MyAvatar::update(float deltaTime) {
|
|||
head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
|
||||
|
||||
if (_motionBehaviors & AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY) {
|
||||
PerformanceTimer perfTimer("MyAvatar::update/gravityWork");
|
||||
setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition()));
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::update/simulate");
|
||||
simulate(deltaTime);
|
||||
}
|
||||
simulate(deltaTime);
|
||||
}
|
||||
|
||||
void MyAvatar::simulate(float deltaTime) {
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate");
|
||||
|
||||
PerformanceTimer perfTimer("simulate");
|
||||
if (_scale != _targetScale) {
|
||||
float scale = (1.0f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale;
|
||||
setScale(scale);
|
||||
|
@ -150,31 +140,28 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
_handState = HAND_STATE_NULL;
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/updateOrientation");
|
||||
PerformanceTimer perfTimer("transform");
|
||||
updateOrientation(deltaTime);
|
||||
}
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/updatePosition");
|
||||
updatePosition(deltaTime);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/hand Collision,simulate");
|
||||
PerformanceTimer perfTimer("hand");
|
||||
// update avatar skeleton and simulate hand and head
|
||||
getHand()->simulate(deltaTime, true);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/_skeletonModel.simulate()");
|
||||
PerformanceTimer perfTimer("skeleton");
|
||||
_skeletonModel.simulate(deltaTime);
|
||||
}
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/simulateAttachments");
|
||||
PerformanceTimer perfTimer("attachments");
|
||||
simulateAttachments(deltaTime);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/copy joints");
|
||||
PerformanceTimer perfTimer("joints");
|
||||
// copy out the skeleton joints from the model
|
||||
_jointData.resize(_skeletonModel.getJointStateCount());
|
||||
for (int i = 0; i < _jointData.size(); i++) {
|
||||
|
@ -184,7 +171,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/head Simulate");
|
||||
PerformanceTimer perfTimer("head");
|
||||
Head* head = getHead();
|
||||
glm::vec3 headPosition;
|
||||
if (!_skeletonModel.getHeadPosition(headPosition)) {
|
||||
|
@ -196,7 +183,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/hair Simulate");
|
||||
PerformanceTimer perfTimer("hair");
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) {
|
||||
simulateHair(deltaTime);
|
||||
foreach (Hair* hair, _hairs) {
|
||||
|
@ -206,7 +193,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/ragdoll");
|
||||
PerformanceTimer perfTimer("ragdoll");
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideAsRagdoll)) {
|
||||
const int minError = 0.01f;
|
||||
const float maxIterations = 10;
|
||||
|
@ -219,7 +206,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
|
||||
// now that we're done stepping the avatar forward in time, compute new collisions
|
||||
if (_collisionGroups != 0) {
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/_collisionGroups");
|
||||
PerformanceTimer perfTimer("collisions");
|
||||
Camera* myCamera = Application::getInstance()->getCamera();
|
||||
|
||||
float radius = getSkeletonHeight() * COLLISION_RADIUS_SCALE;
|
||||
|
@ -228,18 +215,18 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
radius *= COLLISION_RADIUS_SCALAR;
|
||||
}
|
||||
if (_collisionGroups & COLLISION_GROUP_ENVIRONMENT) {
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/updateCollisionWithEnvironment");
|
||||
PerformanceTimer perfTimer("environment");
|
||||
updateCollisionWithEnvironment(deltaTime, radius);
|
||||
}
|
||||
if (_collisionGroups & COLLISION_GROUP_VOXELS) {
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/updateCollisionWithVoxels");
|
||||
PerformanceTimer perfTimer("voxels");
|
||||
updateCollisionWithVoxels(deltaTime, radius);
|
||||
} else {
|
||||
_trapDuration = 0.0f;
|
||||
}
|
||||
/* TODO: Andrew to make this work
|
||||
if (_collisionGroups & COLLISION_GROUP_AVATARS) {
|
||||
PerformanceTimer perfTimer("MyAvatar::simulate/updateCollisionWithAvatars");
|
||||
PerformanceTimer perfTimer("avatars");
|
||||
updateCollisionWithAvatars(deltaTime);
|
||||
}
|
||||
*/
|
||||
|
@ -916,7 +903,6 @@ bool MyAvatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode rend
|
|||
}
|
||||
|
||||
float MyAvatar::computeDistanceToFloor(const glm::vec3& startPoint) {
|
||||
PerformanceTimer perfTimer("MyAvatar::computeDistanceToFloor()");
|
||||
glm::vec3 direction = -_worldUpDirection;
|
||||
OctreeElement* elementHit; // output from findRayIntersection
|
||||
float distance = FLT_MAX; // output from findRayIntersection
|
||||
|
@ -982,7 +968,6 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
const float NEARBY_FLOOR_THRESHOLD = 5.0f;
|
||||
|
||||
void MyAvatar::updatePosition(float deltaTime) {
|
||||
PerformanceTimer perfTimer("MyAvatar::updatePosition");
|
||||
float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) +
|
||||
fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT]) +
|
||||
fabsf(_driveKeys[UP] - _driveKeys[DOWN]);
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
void resetShapePositionsToDefaultPose(); // DEBUG method
|
||||
|
||||
void renderRagdoll();
|
||||
|
||||
protected:
|
||||
|
||||
// virtual overrrides from Ragdoll
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <QTimer>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -75,6 +76,7 @@ void Faceshift::update() {
|
|||
if (!isActive()) {
|
||||
return;
|
||||
}
|
||||
PerformanceTimer perfTimer("faceshift");
|
||||
// get the euler angles relative to the window
|
||||
glm::vec3 eulers = glm::degrees(safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3(
|
||||
(_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f)))));
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
#include <limits>
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "JoystickManager.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -46,6 +47,7 @@ JoystickManager::~JoystickManager() {
|
|||
|
||||
void JoystickManager::update() {
|
||||
#ifdef HAVE_SDL
|
||||
PerformanceTimer perfTimer("joystick");
|
||||
SDL_JoystickUpdate();
|
||||
|
||||
for (int i = 0; i < _joystickStates.size(); i++) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <QtDebug>
|
||||
|
||||
#include <FBXReader.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "PrioVR.h"
|
||||
|
@ -166,6 +167,7 @@ void PrioVR::update(float deltaTime) {
|
|||
if (!_skeletalDevice) {
|
||||
return;
|
||||
}
|
||||
PerformanceTimer perfTimer("PrioVR");
|
||||
unsigned int timestamp;
|
||||
yei_getLastStreamDataAll(_skeletalDevice, (char*)_jointRotations.data(),
|
||||
_jointRotations.size() * sizeof(glm::quat), ×tamp);
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "SixenseManager.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
@ -83,7 +85,10 @@ void SixenseManager::update(float deltaTime) {
|
|||
if (sixenseGetNumActiveControllers() == 0) {
|
||||
_hydrasConnected = false;
|
||||
return;
|
||||
} else if (!_hydrasConnected) {
|
||||
}
|
||||
|
||||
PerformanceTimer perfTimer("sixense");
|
||||
if (!_hydrasConnected) {
|
||||
_hydrasConnected = true;
|
||||
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <QHash>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include <FBXReader.h>
|
||||
|
@ -128,6 +129,7 @@ void Visage::update() {
|
|||
if (!_active) {
|
||||
return;
|
||||
}
|
||||
PerformanceTimer perfTimer("visage");
|
||||
_headRotation = glm::quat(glm::vec3(-_data->faceRotation[0], -_data->faceRotation[1], _data->faceRotation[2]));
|
||||
_headTranslation = (glm::vec3(_data->faceTranslation[0], _data->faceTranslation[1], _data->faceTranslation[2]) -
|
||||
_headOrigin) * TRANSLATION_SCALE;
|
||||
|
|
|
@ -121,7 +121,7 @@ static void maybeRelease(QOpenGLFramebufferObject* fbo) {
|
|||
}
|
||||
|
||||
QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
|
||||
PerformanceTimer perfTimer("paintGL/glowEffect");
|
||||
PerformanceTimer perfTimer("glowEffect");
|
||||
|
||||
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
|
||||
primaryFBO->release();
|
||||
|
|
|
@ -1488,14 +1488,19 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re
|
|||
if (cascadedShadows) {
|
||||
program->setUniform(skinLocations->shadowDistances, Application::getInstance()->getShadowDistances());
|
||||
}
|
||||
} else {
|
||||
|
||||
// local light uniforms
|
||||
skinProgram->setUniformValue("numLocalLights", _numLocalLights);
|
||||
skinProgram->setUniformArray("localLightDirections", _localLightDirections, MAX_LOCAL_LIGHTS);
|
||||
skinProgram->setUniformArray("localLightColors", _localLightColors, MAX_LOCAL_LIGHTS);
|
||||
} else {
|
||||
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
||||
program->bind();
|
||||
if (cascadedShadows) {
|
||||
program->setUniform(shadowDistancesLocation, Application::getInstance()->getShadowDistances());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mesh.blendshapes.isEmpty()) {
|
||||
if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) {
|
||||
activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
|
||||
|
@ -1622,6 +1627,20 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re
|
|||
}
|
||||
}
|
||||
|
||||
void Model::setLocalLightDirection(const glm::vec3& direction, int lightIndex) {
|
||||
assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS);
|
||||
_localLightDirections[lightIndex] = direction;
|
||||
}
|
||||
|
||||
void Model::setLocalLightColor(const glm::vec3& color, int lightIndex) {
|
||||
assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS);
|
||||
_localLightColors[lightIndex] = color;
|
||||
}
|
||||
|
||||
void Model::setNumLocalLights(int numLocalLights) {
|
||||
_numLocalLights = numLocalLights;
|
||||
}
|
||||
|
||||
void AnimationHandle::setURL(const QUrl& url) {
|
||||
if (_url != url) {
|
||||
_animation = Application::getInstance()->getAnimationCache()->getAnimation(_url = url);
|
||||
|
|
|
@ -32,6 +32,8 @@ class Shape;
|
|||
typedef QSharedPointer<AnimationHandle> AnimationHandlePointer;
|
||||
typedef QWeakPointer<AnimationHandle> WeakAnimationHandlePointer;
|
||||
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
/// A generic 3D model displaying geometry loaded from a URL.
|
||||
class Model : public QObject, public PhysicsEntity {
|
||||
Q_OBJECT
|
||||
|
@ -143,6 +145,10 @@ public:
|
|||
/// Sets blended vertices computed in a separate thread.
|
||||
void setBlendedVertices(const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals);
|
||||
|
||||
void setLocalLightDirection(const glm::vec3& direction, int lightIndex);
|
||||
void setLocalLightColor(const glm::vec3& color, int lightIndex);
|
||||
void setNumLocalLights(int numLocalLights);
|
||||
|
||||
protected:
|
||||
QSharedPointer<NetworkGeometry> _geometry;
|
||||
|
||||
|
@ -158,6 +164,10 @@ protected:
|
|||
bool _showTrueJointTransforms;
|
||||
int _rootIndex;
|
||||
|
||||
glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS];
|
||||
int _numLocalLights;
|
||||
|
||||
QVector<JointState> _jointStates;
|
||||
|
||||
class MeshState {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
|
||||
#include "ProgramObject.h"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
ProgramObject::ProgramObject(QObject* parent) : QGLShaderProgram(parent) {
|
||||
}
|
||||
|
@ -22,3 +23,17 @@ void ProgramObject::setUniform(const char* name, const glm::vec3& value) {
|
|||
setUniformValue(name, value.x, value.y, value.z);
|
||||
}
|
||||
|
||||
void ProgramObject::setUniformArray(const char* name, const glm::vec3* values, int count) {
|
||||
GLfloat* floatVal = new GLfloat[count*3];
|
||||
int index = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
assert(index < count*3);
|
||||
const float* valPtr = glm::value_ptr(values[i]);
|
||||
floatVal[index++] = valPtr[0];
|
||||
floatVal[index++] = valPtr[1];
|
||||
floatVal[index++] = valPtr[2];
|
||||
}
|
||||
|
||||
setUniformValueArray(name, floatVal, count, 3);
|
||||
delete[] floatVal;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
|
||||
void setUniform(int location, const glm::vec3& value);
|
||||
void setUniform(const char* name, const glm::vec3& value);
|
||||
void setUniformArray(const char* name, const glm::vec3* values, int count);
|
||||
};
|
||||
|
||||
#endif // hifi_ProgramObject_h
|
||||
|
|
|
@ -601,6 +601,8 @@ void Stats::display(
|
|||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
}
|
||||
|
||||
PerformanceTimer::tallyAllTimerRecords();
|
||||
|
||||
// TODO: the display of these timing details should all be moved to JavaScript
|
||||
if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayTimingDetails)) {
|
||||
// Timing details...
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <SharedUtil.h>
|
||||
#include <NodeList.h>
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "Application.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "Menu.h"
|
||||
|
@ -57,6 +59,8 @@ GLubyte identityIndicesRight[] = { 1, 2, 6, 1, 6, 5 };
|
|||
GLubyte identityIndicesFront[] = { 0, 2, 1, 0, 3, 2 };
|
||||
GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 };
|
||||
|
||||
static glm::vec3 grayColor = glm::vec3(0.3f, 0.3f, 0.3f);
|
||||
|
||||
VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree)
|
||||
: NodeData(),
|
||||
_treeScale(treeScale),
|
||||
|
@ -67,7 +71,10 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree)
|
|||
_inOcclusions(false),
|
||||
_showCulledSharedFaces(false),
|
||||
_usePrimitiveRenderer(false),
|
||||
_renderer(0)
|
||||
_renderer(0),
|
||||
_drawHaze(false),
|
||||
_farHazeDistance(300.0f),
|
||||
_hazeColor(grayColor)
|
||||
{
|
||||
|
||||
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
|
||||
|
@ -373,6 +380,7 @@ void VoxelSystem::cleanupVoxelMemory() {
|
|||
delete[] _readVoxelDirtyArray;
|
||||
_writeVoxelDirtyArray = _readVoxelDirtyArray = NULL;
|
||||
_readArraysLock.unlock();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,6 +462,7 @@ void VoxelSystem::initVoxelMemory() {
|
|||
|
||||
_readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
|
||||
_memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels);
|
||||
|
||||
} else {
|
||||
|
||||
// Global Normals mode uses a technique of not including normals on any voxel vertices, and instead
|
||||
|
@ -521,13 +530,23 @@ void VoxelSystem::initVoxelMemory() {
|
|||
_shadowDistancesLocation = _cascadedShadowMapProgram.uniformLocation("shadowDistances");
|
||||
_cascadedShadowMapProgram.release();
|
||||
}
|
||||
|
||||
}
|
||||
_renderer = new PrimitiveRenderer(_maxVoxels);
|
||||
|
||||
_initialized = true;
|
||||
|
||||
|
||||
_writeArraysLock.unlock();
|
||||
_readArraysLock.unlock();
|
||||
|
||||
// fog for haze
|
||||
if (_drawHaze) {
|
||||
GLfloat fogColor[] = {_hazeColor.x, _hazeColor.y, _hazeColor.z, 1.0f};
|
||||
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||
glFogfv(GL_FOG_COLOR, fogColor);
|
||||
glFogf(GL_FOG_START, 0.0f);
|
||||
glFogf(GL_FOG_END, _farHazeDistance);
|
||||
}
|
||||
}
|
||||
|
||||
int VoxelSystem::parseData(const QByteArray& packet) {
|
||||
|
@ -1114,6 +1133,7 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo
|
|||
node->setBufferIndex(nodeIndex);
|
||||
node->setVoxelSystem(this);
|
||||
}
|
||||
|
||||
// populate the array with points for the 8 vertices and RGB color for each added vertex
|
||||
updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor());
|
||||
}
|
||||
|
@ -1131,11 +1151,13 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo
|
|||
|
||||
void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||
float voxelScale, const nodeColor& color) {
|
||||
|
||||
|
||||
if (_initialized && nodeIndex <= _maxVoxels) {
|
||||
_writeVoxelDirtyArray[nodeIndex] = true;
|
||||
|
||||
|
||||
if (_useVoxelShader) {
|
||||
// write in position, scale, and color for the voxel
|
||||
|
||||
if (_writeVoxelShaderData) {
|
||||
VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
|
||||
writeVerticesAt->x = startVertex.x * TREE_SCALE;
|
||||
|
@ -1157,6 +1179,7 @@ void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3&
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1407,6 +1430,10 @@ void VoxelSystem::render() {
|
|||
}
|
||||
} else
|
||||
if (!_usePrimitiveRenderer) {
|
||||
if (_drawHaze) {
|
||||
glEnable(GL_FOG);
|
||||
}
|
||||
|
||||
PerformanceWarning warn(showWarnings, "render().. TRIANGLES...");
|
||||
|
||||
{
|
||||
|
@ -1478,6 +1505,10 @@ void VoxelSystem::render() {
|
|||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
if (_drawHaze) {
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
}
|
||||
else {
|
||||
applyScaleAndBindProgram(texture);
|
||||
|
|
|
@ -273,7 +273,11 @@ private:
|
|||
static unsigned short _sSwizzledOcclusionBits[64]; ///< Swizzle value of bit pairs of the value of index
|
||||
static unsigned char _sOctantIndexToBitMask[8]; ///< Map octant index to partition mask
|
||||
static unsigned char _sOctantIndexToSharedBitMask[8][8]; ///< Map octant indices to shared partition mask
|
||||
|
||||
|
||||
// haze
|
||||
bool _drawHaze;
|
||||
float _farHazeDistance;
|
||||
glm::vec3 _hazeColor;
|
||||
};
|
||||
|
||||
#endif // hifi_VoxelSystem_h
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
|
||||
#include "PerfStat.h"
|
||||
|
||||
#include "SharedUtil.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PerformanceWarning
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Static class members initialization here!
|
||||
bool PerformanceWarning::_suppressShortTimings = false;
|
||||
|
||||
|
@ -52,14 +58,50 @@ PerformanceWarning::~PerformanceWarning() {
|
|||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PerformanceTimerRecord
|
||||
// ----------------------------------------------------------------------------
|
||||
const quint64 STALE_STAT_PERIOD = 4 * USECS_PER_SECOND;
|
||||
|
||||
void PerformanceTimerRecord::tallyResult(const quint64& now) {
|
||||
if (_numAccumulations > 0) {
|
||||
_numTallies++;
|
||||
_movingAverage.updateAverage(_runningTotal - _lastTotal);
|
||||
_lastTotal = _runningTotal;
|
||||
_numAccumulations = 0;
|
||||
_expiry = now + STALE_STAT_PERIOD;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PerformanceTimer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
QString PerformanceTimer::_fullName;
|
||||
QMap<QString, PerformanceTimerRecord> PerformanceTimer::_records;
|
||||
|
||||
|
||||
PerformanceTimer::~PerformanceTimer() {
|
||||
quint64 end = usecTimestampNow();
|
||||
quint64 elapsedusec = (end - _start);
|
||||
PerformanceTimerRecord& namedRecord = _records[_name];
|
||||
namedRecord.recordResult(elapsedusec);
|
||||
quint64 elapsedusec = (usecTimestampNow() - _start);
|
||||
PerformanceTimerRecord& namedRecord = _records[_fullName];
|
||||
namedRecord.accumulateResult(elapsedusec);
|
||||
_fullName.resize(_fullName.size() - (_name.size() + 1));
|
||||
}
|
||||
|
||||
// static
|
||||
void PerformanceTimer::tallyAllTimerRecords() {
|
||||
QMap<QString, PerformanceTimerRecord>::iterator recordsItr = _records.begin();
|
||||
QMap<QString, PerformanceTimerRecord>::const_iterator recordsEnd = _records.end();
|
||||
quint64 now = usecTimestampNow();
|
||||
while (recordsItr != recordsEnd) {
|
||||
recordsItr.value().tallyResult(now);
|
||||
if (recordsItr.value().isStale(now)) {
|
||||
// purge stale records
|
||||
recordsItr = _records.erase(recordsItr);
|
||||
} else {
|
||||
++recordsItr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerformanceTimer::dumpAllTimerRecords() {
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
class PerformanceWarning {
|
||||
private:
|
||||
quint64 _start;
|
||||
const char* _message;
|
||||
bool _renderWarningsOn;
|
||||
bool _alwaysDisplay;
|
||||
quint64* _runningTotal;
|
||||
quint64* _totalCalls;
|
||||
static bool _suppressShortTimings;
|
||||
quint64 _start;
|
||||
const char* _message;
|
||||
bool _renderWarningsOn;
|
||||
bool _alwaysDisplay;
|
||||
quint64* _runningTotal;
|
||||
quint64* _totalCalls;
|
||||
static bool _suppressShortTimings;
|
||||
public:
|
||||
|
||||
PerformanceWarning(bool renderWarnings, const char* message, bool alwaysDisplay = false,
|
||||
|
@ -52,38 +52,47 @@ public:
|
|||
|
||||
class PerformanceTimerRecord {
|
||||
public:
|
||||
PerformanceTimerRecord() : _runningTotal(0), _totalCalls(0) {}
|
||||
PerformanceTimerRecord() : _runningTotal(0), _lastTotal(0), _numAccumulations(0), _numTallies(0), _expiry(0) {}
|
||||
|
||||
void recordResult(quint64 elapsed) { _runningTotal += elapsed; _totalCalls++; _movingAverage.updateAverage(elapsed); }
|
||||
quint64 getAverage() const { return (_totalCalls == 0) ? 0 : _runningTotal / _totalCalls; }
|
||||
quint64 getMovingAverage() const { return (_totalCalls == 0) ? 0 : _movingAverage.getAverage(); }
|
||||
quint64 getCount() const { return _totalCalls; }
|
||||
void accumulateResult(const quint64& elapsed) { _runningTotal += elapsed; ++_numAccumulations; }
|
||||
void tallyResult(const quint64& now);
|
||||
bool isStale(const quint64& now) const { return now > _expiry; }
|
||||
quint64 getAverage() const { return (_numTallies == 0) ? 0 : _runningTotal / _numTallies; }
|
||||
quint64 getMovingAverage() const { return (_numTallies == 0) ? 0 : _movingAverage.getAverage(); }
|
||||
quint64 getCount() const { return _numTallies; }
|
||||
|
||||
private:
|
||||
quint64 _runningTotal;
|
||||
quint64 _totalCalls;
|
||||
SimpleMovingAverage _movingAverage;
|
||||
quint64 _runningTotal;
|
||||
quint64 _lastTotal;
|
||||
quint64 _numAccumulations;
|
||||
quint64 _numTallies;
|
||||
quint64 _expiry;
|
||||
SimpleMovingAverage _movingAverage;
|
||||
};
|
||||
|
||||
class PerformanceTimer {
|
||||
public:
|
||||
|
||||
PerformanceTimer(const QString& name) :
|
||||
_start(usecTimestampNow()),
|
||||
_name(name) { }
|
||||
_start(0),
|
||||
_name(name) {
|
||||
_fullName.append("/");
|
||||
_fullName.append(_name);
|
||||
_start = usecTimestampNow();
|
||||
}
|
||||
|
||||
quint64 elapsed() const { return (usecTimestampNow() - _start); };
|
||||
|
||||
~PerformanceTimer();
|
||||
|
||||
static const PerformanceTimerRecord& getTimerRecord(const QString& name) { return _records[name]; };
|
||||
static const QMap<QString, PerformanceTimerRecord>& getAllTimerRecords() { return _records; };
|
||||
static void tallyAllTimerRecords();
|
||||
static void dumpAllTimerRecords();
|
||||
|
||||
private:
|
||||
quint64 _start;
|
||||
QString _name;
|
||||
static QMap<QString, PerformanceTimerRecord> _records;
|
||||
quint64 _start;
|
||||
QString _name;
|
||||
static QString _fullName;
|
||||
static QMap<QString, PerformanceTimerRecord> _records;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
SimpleMovingAverage::SimpleMovingAverage(int numSamplesToAverage) :
|
||||
_numSamples(0),
|
||||
_average(0),
|
||||
_eventDeltaAverage(0),
|
||||
_average(0.0f),
|
||||
_eventDeltaAverage(0.0f),
|
||||
WEIGHTING(1.0f / numSamplesToAverage),
|
||||
ONE_MINUS_WEIGHTING(1 - WEIGHTING) {
|
||||
|
||||
|
@ -45,8 +45,8 @@ int SimpleMovingAverage::updateAverage(float sample) {
|
|||
|
||||
void SimpleMovingAverage::reset() {
|
||||
_numSamples = 0;
|
||||
_average = 0;
|
||||
_eventDeltaAverage = 0;
|
||||
_average = 0.0f;
|
||||
_eventDeltaAverage = 0.0f;
|
||||
}
|
||||
|
||||
float SimpleMovingAverage::getEventDeltaAverage() const {
|
||||
|
@ -55,5 +55,5 @@ float SimpleMovingAverage::getEventDeltaAverage() const {
|
|||
}
|
||||
|
||||
float SimpleMovingAverage::getAverageSampleValuePerSecond() const {
|
||||
return _average * (1 / getEventDeltaAverage());
|
||||
return _average * (1.0f / getEventDeltaAverage());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue