mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 10:43:56 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into applications_diet_cpp11
Conflicts: interface/src/Application.cpp interface/src/devices/OculusManager.cpp libraries/networking/src/NodeList.cpp
This commit is contained in:
commit
327daacecd
107 changed files with 1336 additions and 825 deletions
|
@ -12,6 +12,10 @@ if (POLICY CMP0043)
|
|||
cmake_policy(SET CMP0043 OLD)
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
endif ()
|
||||
|
||||
project(hifi)
|
||||
add_definitions(-DGLM_FORCE_RADIANS)
|
||||
|
||||
|
|
|
@ -15,4 +15,4 @@ if (UNIX)
|
|||
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
|
||||
endif (UNIX)
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# LinkSharedDependencies.cmake
|
||||
# IncludeDependencyIncludes.cmake
|
||||
# cmake/macros
|
||||
#
|
||||
# Copyright 2014 High Fidelity, Inc.
|
||||
|
@ -9,7 +9,7 @@
|
|||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(LINK_SHARED_DEPENDENCIES)
|
||||
macro(INCLUDE_DEPENDENCY_INCLUDES)
|
||||
if (${TARGET_NAME}_DEPENDENCY_INCLUDES)
|
||||
list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_INCLUDES)
|
||||
|
||||
|
@ -19,4 +19,4 @@ macro(LINK_SHARED_DEPENDENCIES)
|
|||
|
||||
# set the property on this target so it can be retreived by targets linking to us
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}")
|
||||
endmacro(LINK_SHARED_DEPENDENCIES)
|
||||
endmacro(INCLUDE_DEPENDENCY_INCLUDES)
|
|
@ -1,47 +0,0 @@
|
|||
#
|
||||
# FindGLUT.cmake
|
||||
#
|
||||
# Try to find GLUT library and include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# GLUT_FOUND
|
||||
# GLUT_INCLUDE_DIRS
|
||||
# GLUT_LIBRARIES
|
||||
#
|
||||
# Created on 2/6/2014 by Stephen Birarda
|
||||
# Copyright 2014 High Fidelity, Inc.
|
||||
#
|
||||
# Adapted from FindGLUT.cmake available in tlorach's OpenGLText Repository
|
||||
# https://raw.github.com/tlorach/OpenGLText/master/cmake/FindGLUT.cmake
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("freeglut")
|
||||
|
||||
if (WIN32)
|
||||
set(GLUT_HINT_DIRS "${FREEGLUT_SEARCH_DIRS} ${OPENGL_INCLUDE_DIR}")
|
||||
|
||||
find_path(GLUT_INCLUDE_DIRS GL/glut.h PATH_SUFFIXES include HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
find_library(GLUT_LIBRARY freeglut PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
else ()
|
||||
find_path(GLUT_INCLUDE_DIRS GL/glut.h PATH_SUFFIXES include HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
find_library(GLUT_LIBRARY glut PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
set(GLUT_LIBRARIES "${GLUT_LIBRARY}" "${XMU_LIBRARY}" "${XI_LIBRARY}")
|
||||
|
||||
if (UNIX)
|
||||
find_library(XI_LIBRARY Xi PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
find_library(XMU_LIBRARY Xmu PATH_SUFFIXES lib HINTS ${FREEGLUT_SEARCH_DIRS})
|
||||
|
||||
find_package_handle_standard_args(GLUT DEFAULT_MSG GLUT_INCLUDE_DIRS GLUT_LIBRARIES XI_LIBRARY XMU_LIBRARY)
|
||||
else ()
|
||||
find_package_handle_standard_args(GLUT DEFAULT_MSG GLUT_INCLUDE_DIRS GLUT_LIBRARIES)
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(GLUT_INCLUDE_DIRS GLUT_LIBRARIES GLUT_LIBRARY XI_LIBRARY XMU_LIBRARY FREEGLUT_SEARCH_DIRS)
|
|
@ -52,4 +52,4 @@ include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
|
|||
# append OpenSSL to our list of libraries to link
|
||||
target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES})
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
|
@ -1,131 +1,3 @@
|
|||
// Add your JavaScript for assignment below this line
|
||||
|
||||
// The following is an example of Conway's Game of Life (http://en.wikipedia.org/wiki/Conway's_Game_of_Life)
|
||||
|
||||
var NUMBER_OF_CELLS_EACH_DIMENSION = 64;
|
||||
var NUMBER_OF_CELLS = NUMBER_OF_CELLS_EACH_DIMENSION * NUMBER_OF_CELLS_EACH_DIMENSION;
|
||||
|
||||
var currentCells = [];
|
||||
var nextCells = [];
|
||||
|
||||
var METER_LENGTH = 1;
|
||||
var cellScale = (NUMBER_OF_CELLS_EACH_DIMENSION * METER_LENGTH) / NUMBER_OF_CELLS_EACH_DIMENSION;
|
||||
|
||||
// randomly populate the cell start values
|
||||
for (var i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
|
||||
// create the array to hold this row
|
||||
currentCells[i] = [];
|
||||
|
||||
// create the array to hold this row in the nextCells array
|
||||
nextCells[i] = [];
|
||||
|
||||
for (var j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
|
||||
currentCells[i][j] = Math.floor(Math.random() * 2);
|
||||
|
||||
// put the same value in the nextCells array for first board draw
|
||||
nextCells[i][j] = currentCells[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
function isNeighbourAlive(i, j) {
|
||||
if (i < 0 || i >= NUMBER_OF_CELLS_EACH_DIMENSION
|
||||
|| i < 0 || j >= NUMBER_OF_CELLS_EACH_DIMENSION) {
|
||||
return 0;
|
||||
} else {
|
||||
return currentCells[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
function updateCells() {
|
||||
var i = 0;
|
||||
var j = 0;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
|
||||
for (j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
|
||||
// figure out the number of live neighbours for the i-j cell
|
||||
var liveNeighbours =
|
||||
isNeighbourAlive(i + 1, j - 1) + isNeighbourAlive(i + 1, j) + isNeighbourAlive(i + 1, j + 1) +
|
||||
isNeighbourAlive(i, j - 1) + isNeighbourAlive(i, j + 1) +
|
||||
isNeighbourAlive(i - 1, j - 1) + isNeighbourAlive(i - 1, j) + isNeighbourAlive(i - 1, j + 1);
|
||||
|
||||
if (currentCells[i][j]) {
|
||||
// live cell
|
||||
|
||||
if (liveNeighbours < 2) {
|
||||
// rule #1 - under-population - this cell will die
|
||||
// mark it zero to mark the change
|
||||
nextCells[i][j] = 0;
|
||||
} else if (liveNeighbours < 4) {
|
||||
// rule #2 - this cell lives
|
||||
// mark it -1 to mark no change
|
||||
nextCells[i][j] = -1;
|
||||
} else {
|
||||
// rule #3 - overcrowding - this cell dies
|
||||
// mark it zero to mark the change
|
||||
nextCells[i][j] = 0;
|
||||
}
|
||||
} else {
|
||||
// dead cell
|
||||
if (liveNeighbours == 3) {
|
||||
// rule #4 - reproduction - this cell revives
|
||||
// mark it one to mark the change
|
||||
nextCells[i][j] = 1;
|
||||
} else {
|
||||
// this cell stays dead
|
||||
// mark it -1 for no change
|
||||
nextCells[i][j] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.random() < 0.001) {
|
||||
// Random mutation to keep things interesting in there.
|
||||
nextCells[i][j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
|
||||
for (j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
|
||||
if (nextCells[i][j] != -1) {
|
||||
// there has been a change to this cell, change the value in the currentCells array
|
||||
currentCells[i][j] = nextCells[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendNextCells() {
|
||||
for (var i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
|
||||
for (var j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
|
||||
if (nextCells[i][j] != -1) {
|
||||
// there has been a change to the state of this cell, send it
|
||||
|
||||
// find the x and y position for this voxel, z = 0
|
||||
var x = j * cellScale;
|
||||
var y = i * cellScale;
|
||||
|
||||
// queue a packet to add a voxel for the new cell
|
||||
var color = (nextCells[i][j] == 1) ? 255 : 1;
|
||||
Voxels.setVoxel(x, y, 0, cellScale, color, color, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sentFirstBoard = false;
|
||||
|
||||
function step(deltaTime) {
|
||||
if (sentFirstBoard) {
|
||||
// we've already sent the first full board, perform a step in time
|
||||
updateCells();
|
||||
} else {
|
||||
// this will be our first board send
|
||||
sentFirstBoard = true;
|
||||
}
|
||||
|
||||
sendNextCells();
|
||||
}
|
||||
|
||||
|
||||
Script.update.connect(step);
|
||||
Voxels.setPacketsPerSecond(200);
|
||||
// Here you can put a script that will be run by an assignment-client (AC)
|
||||
// For examples, please go to http://public.highfidelity.io/scripts
|
||||
// The directory named acScripts contains assignment-client specific scripts you can try.
|
||||
|
|
|
@ -551,7 +551,9 @@ void DomainServer::populateDefaultStaticAssignmentsExcludingTypes(const QSet<Ass
|
|||
for (Assignment::Type defaultedType = Assignment::AudioMixerType;
|
||||
defaultedType != Assignment::AllTypes;
|
||||
defaultedType = static_cast<Assignment::Type>(static_cast<int>(defaultedType) + 1)) {
|
||||
if (!excludedTypes.contains(defaultedType) && defaultedType != Assignment::AgentType) {
|
||||
if (!excludedTypes.contains(defaultedType)
|
||||
&& defaultedType != Assignment::UNUSED
|
||||
&& defaultedType != Assignment::AgentType) {
|
||||
// type has not been set from a command line or config file config, use the default
|
||||
// by clearing whatever exists and writing a single default assignment with no payload
|
||||
Assignment* newAssignment = new Assignment(Assignment::CreateCommand, (Assignment::Type) defaultedType);
|
||||
|
|
|
@ -15,3 +15,4 @@ Script.load("hydraMove.js");
|
|||
Script.load("headMove.js");
|
||||
Script.load("inspect.js");
|
||||
Script.load("lobby.js");
|
||||
Script.load("notifications.js");
|
||||
|
|
|
@ -13,34 +13,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function(){
|
||||
this.oldColor = {};
|
||||
this.oldColorKnown = false;
|
||||
this.storeOldColor = function(entityID) {
|
||||
var oldProperties = Entities.getEntityProperties(entityID);
|
||||
this.oldColor = oldProperties.color;
|
||||
this.oldColorKnown = true;
|
||||
print("storing old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
};
|
||||
|
||||
this.preload = function(entityID) {
|
||||
print("preload");
|
||||
this.storeOldColor(entityID);
|
||||
};
|
||||
|
||||
this.hoverEnterEntity = function(entityID, mouseEvent) {
|
||||
print("hoverEnterEntity");
|
||||
if (!this.oldColorKnown) {
|
||||
this.storeOldColor(entityID);
|
||||
}
|
||||
Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} });
|
||||
};
|
||||
this.hoverLeaveEntity = function(entityID, mouseEvent) {
|
||||
print("hoverLeaveEntity");
|
||||
if (this.oldColorKnown) {
|
||||
print("leave restoring old color... this.oldColor="
|
||||
+ this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
Entities.editEntity(entityID, { color: this.oldColor });
|
||||
}
|
||||
};
|
||||
})
|
||||
(function() {
|
||||
Script.include("changeColorOnHoverClass.js");
|
||||
return new ChangeColorOnHover();
|
||||
})
|
||||
|
|
55
examples/entityScripts/changeColorOnHoverClass.js
Normal file
55
examples/entityScripts/changeColorOnHoverClass.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// changeColorOnHover.js
|
||||
// examples/entityScripts
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 11/1/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This is an example of an entity script which when assigned to a non-model entity like a box or sphere, will
|
||||
// change the color of the entity when you hover over it. This script uses the JavaScript prototype/class functionality
|
||||
// to construct an object that has methods for hoverEnterEntity and hoverLeaveEntity;
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
ChangeColorOnHover = function(){
|
||||
this.oldColor = {};
|
||||
this.oldColorKnown = false;
|
||||
};
|
||||
|
||||
ChangeColorOnHover.prototype = {
|
||||
|
||||
storeOldColor: function(entityID) {
|
||||
var oldProperties = Entities.getEntityProperties(entityID);
|
||||
this.oldColor = oldProperties.color;
|
||||
this.oldColorKnown = true;
|
||||
print("storing old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
},
|
||||
|
||||
preload: function(entityID) {
|
||||
print("preload");
|
||||
this.storeOldColor(entityID);
|
||||
},
|
||||
|
||||
hoverEnterEntity: function(entityID, mouseEvent) {
|
||||
print("hoverEnterEntity");
|
||||
if (!this.oldColorKnown) {
|
||||
this.storeOldColor(entityID);
|
||||
}
|
||||
Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} });
|
||||
},
|
||||
|
||||
|
||||
hoverLeaveEntity: function(entityID, mouseEvent) {
|
||||
print("hoverLeaveEntity");
|
||||
if (this.oldColorKnown) {
|
||||
print("leave restoring old color... this.oldColor="
|
||||
+ this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
|
||||
Entities.editEntity(entityID, { color: this.oldColor });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -27,10 +27,12 @@
|
|||
};
|
||||
|
||||
this.enterEntity = function(entityID) {
|
||||
print("enterEntity("+entityID.id+")");
|
||||
playSound();
|
||||
};
|
||||
|
||||
this.leaveEntity = function(entityID) {
|
||||
print("leaveEntity("+entityID.id+")");
|
||||
playSound();
|
||||
};
|
||||
})
|
||||
|
|
|
@ -5,19 +5,89 @@
|
|||
// Created by Clément Brisset on 7/18/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// If using Hydra controllers, pulling the triggers makes laser pointers emanate from the respective hands.
|
||||
// If using a Leap Motion or similar to control your avatar's hands and fingers, pointing with your index fingers makes
|
||||
// laser pointers emanate from the respective index fingers.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var LEFT = 0;
|
||||
var RIGHT = 1;
|
||||
var LEFT_HAND_FLAG = 1;
|
||||
var RIGHT_HAND_FLAG = 2;
|
||||
var laserPointer = (function () {
|
||||
|
||||
function update() {
|
||||
var state = ((Controller.getTriggerValue(LEFT) > 0.9) ? LEFT_HAND_FLAG : 0) +
|
||||
((Controller.getTriggerValue(RIGHT) > 0.9) ? RIGHT_HAND_FLAG : 0);
|
||||
MyAvatar.setHandState(state);
|
||||
}
|
||||
var NUM_FINGERs = 4, // Excluding thumb
|
||||
fingers = [
|
||||
[ "LeftHandIndex", "LeftHandMiddle", "LeftHandRing", "LeftHandPinky" ],
|
||||
[ "RightHandIndex", "RightHandMiddle", "RightHandRing", "RightHandPinky" ]
|
||||
];
|
||||
|
||||
Script.update.connect(update);
|
||||
function isHandPointing(hand) {
|
||||
var MINIMUM_TRIGGER_PULL = 0.9;
|
||||
return Controller.getTriggerValue(hand) > MINIMUM_TRIGGER_PULL;
|
||||
}
|
||||
|
||||
function isFingerPointing(hand) {
|
||||
// Index finger is pointing if final two bones of middle, ring, and pinky fingers are > 90 degrees w.r.t. index finger
|
||||
|
||||
var pointing,
|
||||
indexDirection,
|
||||
otherDirection,
|
||||
f;
|
||||
|
||||
pointing = true;
|
||||
|
||||
indexDirection = Vec3.subtract(
|
||||
MyAvatar.getJointPosition(fingers[hand][0] + "4"),
|
||||
MyAvatar.getJointPosition(fingers[hand][0] + "2")
|
||||
);
|
||||
|
||||
for (f = 1; f < NUM_FINGERs; f += 1) {
|
||||
otherDirection = Vec3.subtract(
|
||||
MyAvatar.getJointPosition(fingers[hand][f] + "4"),
|
||||
MyAvatar.getJointPosition(fingers[hand][f] + "2")
|
||||
);
|
||||
pointing = pointing && Vec3.dot(indexDirection, otherDirection) < 0;
|
||||
}
|
||||
|
||||
return pointing;
|
||||
}
|
||||
|
||||
function update() {
|
||||
var LEFT_HAND = 0,
|
||||
RIGHT_HAND = 1,
|
||||
LEFT_HAND_POINTING_FLAG = 1,
|
||||
RIGHT_HAND_POINTING_FLAG = 2,
|
||||
FINGER_POINTING_FLAG = 4,
|
||||
handState;
|
||||
|
||||
handState = 0;
|
||||
|
||||
if (isHandPointing(LEFT_HAND)) {
|
||||
handState += LEFT_HAND_POINTING_FLAG;
|
||||
}
|
||||
if (isHandPointing(RIGHT_HAND)) {
|
||||
handState += RIGHT_HAND_POINTING_FLAG;
|
||||
}
|
||||
|
||||
if (handState === 0) {
|
||||
if (isFingerPointing(LEFT_HAND)) {
|
||||
handState += LEFT_HAND_POINTING_FLAG;
|
||||
}
|
||||
if (isFingerPointing(RIGHT_HAND)) {
|
||||
handState += RIGHT_HAND_POINTING_FLAG;
|
||||
}
|
||||
if (handState !== 0) {
|
||||
handState += FINGER_POINTING_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
MyAvatar.setHandState(handState);
|
||||
}
|
||||
|
||||
return {
|
||||
update: update
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
Script.update.connect(laserPointer.update);
|
||||
|
|
|
@ -1,25 +1,32 @@
|
|||
//
|
||||
// notifications.js
|
||||
// notifications.js
|
||||
// Version 0.801
|
||||
// Created by Adrian
|
||||
//
|
||||
// Adrian McCarlie 8-10-14
|
||||
// This script demonstrates on-screen overlay type notifications.
|
||||
// Copyright 2014 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
|
||||
|
||||
// This script demonstrates notifications created via a number of ways, such as:
|
||||
// Simple key press alerts, which only depend on a key being pressed,
|
||||
// dummy examples of this are "q", "w", "e", "r", and "SPACEBAR".
|
||||
// actual working examples are "a" for left turn, "d" for right turn and Ctrl/s for snapshot.
|
||||
|
||||
// System generated alerts such as users joining and leaving and chat messages which mention this user.
|
||||
// System generated alerts which originate with a user interface event such as Window Resize, and Mic Mute/Unmute.
|
||||
// Mic Mute/Unmute may appear to be a key press alert, but it actually gets the call from the system as mic is muted and unmuted,
|
||||
// so the mic mute/unmute will also trigger the notification by clicking the Mic Mute button at the top of the screen.
|
||||
// This script generates notifications created via a number of ways, such as:
|
||||
// keystroke:
|
||||
//
|
||||
// "q" returns number of users currently online (for debug purposes)
|
||||
|
||||
// CTRL/s for snapshot.
|
||||
// CTRL/m for mic mute and unmute.
|
||||
|
||||
// System generated notifications:
|
||||
// Displays users online at startup.
|
||||
// If Screen is resized.
|
||||
// Triggers notification if @MyUserName is mentioned in chat.
|
||||
// Announces existing user logging out.
|
||||
// Announces new user logging in.
|
||||
// If mic is muted for any reason.
|
||||
//
|
||||
// To add a new System notification type:
|
||||
//
|
||||
// 1. Set the Event Connector at the bottom of the script.
|
||||
|
@ -45,22 +52,23 @@
|
|||
// 2. Declare a text string.
|
||||
// 3. Call createNotifications(text) parsing the text.
|
||||
// example:
|
||||
// if (key.text == "a") {
|
||||
// var noteString = "Turning to the Left";
|
||||
// createNotification(noteString);
|
||||
// }
|
||||
// if (key.text == "q") { //queries number of users online
|
||||
// var numUsers = GlobalServices.onlineUsers.length;
|
||||
// var welcome = "There are " + numUsers + " users online now.";
|
||||
// createNotification(welcome);
|
||||
// }
|
||||
|
||||
|
||||
var width = 340.0; //width of notification overlay
|
||||
var height = 40.0; // height of a single line notification overlay
|
||||
var windowDimensions = Controller.getViewportDimensions(); // get the size of the interface window
|
||||
var overlayLocationX = (windowDimensions.x - (width + 60.0));// positions window 60px from the right of the interface window
|
||||
var overlayLocationX = (windowDimensions.x - (width + 20.0));// positions window 20px from the right of the interface window
|
||||
var buttonLocationX = overlayLocationX + (width - 28.0);
|
||||
var locationY = 20.0; // position down from top of interface window
|
||||
var topMargin = 13.0;
|
||||
var leftMargin = 10.0;
|
||||
var textColor = { red: 228, green: 228, blue: 228}; // text color
|
||||
var backColor = { red: 38, green: 38, blue: 38}; // background color
|
||||
var backColor = { red: 2, green: 2, blue: 2}; // background color was 38,38,38
|
||||
var backgroundAlpha = 0;
|
||||
var fontSize = 12.0;
|
||||
var persistTime = 10.0; // time in seconds before notification fades
|
||||
|
@ -115,7 +123,6 @@ function createNotification(text) {
|
|||
color: textColor,
|
||||
backgroundColor: backColor,
|
||||
alpha: backgroundAlpha,
|
||||
backgroundAlpha: backgroundAlpha,
|
||||
topMargin: topMargin,
|
||||
leftMargin: leftMargin,
|
||||
font: {size: fontSize},
|
||||
|
@ -125,8 +132,8 @@ function createNotification(text) {
|
|||
var buttonProperties = {
|
||||
x: buttonLocationX,
|
||||
y: bLevel,
|
||||
width: 15.0,
|
||||
height: 15.0,
|
||||
width: 10.0,
|
||||
height: 10.0,
|
||||
subImage: { x: 0, y: 0, width: 10, height: 10 },
|
||||
imageURL: "http://hifi-public.s3.amazonaws.com/images/close-small-light.svg",
|
||||
color: { red: 255, green: 255, blue: 255},
|
||||
|
@ -161,7 +168,7 @@ function fadeIn(noticeIn, buttonIn) {
|
|||
pauseTimer = Script.setInterval(function() {
|
||||
q++;
|
||||
qFade = q / 10.0;
|
||||
Overlays.editOverlay(noticeIn, {alpha: qFade, backgroundAlpha: qFade});
|
||||
Overlays.editOverlay(noticeIn, {alpha: qFade});
|
||||
Overlays.editOverlay(buttonIn, {alpha: qFade});
|
||||
if (q >= 9.0) {
|
||||
Script.clearInterval(pauseTimer);
|
||||
|
@ -203,41 +210,18 @@ function keyPressEvent(key) {
|
|||
if (key.key == 16777249) {
|
||||
ctrlIsPressed = true;
|
||||
}
|
||||
if (key.text == "a") {
|
||||
var noteString = "Turning to the Left";
|
||||
createNotification(noteString);
|
||||
}
|
||||
if (key.text == "d") {
|
||||
var noteString = "Turning to the Right";
|
||||
createNotification(noteString);
|
||||
}
|
||||
if (key.text == "q") { //queries number of users online
|
||||
var numUsers = GlobalServices.onlineUsers.length;
|
||||
var welcome = "There are " + numUsers + " users online now.";
|
||||
createNotification(welcome);
|
||||
}
|
||||
|
||||
if (key.text == "s") {
|
||||
if (ctrlIsPressed == true){
|
||||
var noteString = "You have taken a snapshot";
|
||||
var noteString = "Snapshot taken.";
|
||||
createNotification(noteString);
|
||||
}
|
||||
}
|
||||
if (key.text == "q") {
|
||||
var noteString = "Enable Scripted Motor control is now on.";
|
||||
wordWrap(noteString);
|
||||
}
|
||||
if (key.text == "w") {
|
||||
var noteString = "This notification spans 2 lines. The overlay will resize to fit new lines.";
|
||||
var noteString = "editVoxels.js stopped, editModels.js stopped, selectAudioDevice.js stopped.";
|
||||
wordWrap(noteString);
|
||||
}
|
||||
if (key.text == "e") {
|
||||
var noteString = "This is an example of a multiple line notification. This notification will span 3 lines."
|
||||
wordWrap(noteString);
|
||||
}
|
||||
if (key.text == "r") {
|
||||
var noteString = "This is a very long line of text that we are going to use in this example to divide it into rows of maximum 43 chars and see how many lines we use.";
|
||||
wordWrap(noteString);
|
||||
}
|
||||
if (key.text == "SPACE") {
|
||||
var noteString = "You have pressed the Spacebar, This is an example of a multiple line notification. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.";
|
||||
wordWrap(noteString);
|
||||
}
|
||||
}
|
||||
|
||||
// formats string to add newline every 43 chars
|
||||
|
@ -275,18 +259,14 @@ function checkSize(){
|
|||
|
||||
// Triggers notification if a user logs on or off
|
||||
function onOnlineUsersChanged(users) {
|
||||
var joiners = [];
|
||||
var leavers = [];
|
||||
for (user in users) {
|
||||
if (last_users.indexOf(users[user]) == -1.0) {
|
||||
joiners.push(users[user]);
|
||||
createNotification(users[user] + " Has joined");
|
||||
if (last_users.indexOf(users[user]) == -1.0) {
|
||||
createNotification(users[user] + " has joined");
|
||||
}
|
||||
}
|
||||
for (user in last_users) {
|
||||
if (users.indexOf(last_users[user]) == -1.0) {
|
||||
leavers.push(last_users[user]);
|
||||
createNotification(last_users[user] + " Has left");
|
||||
createNotification(last_users[user] + " has left");
|
||||
}
|
||||
}
|
||||
last_users = users;
|
||||
|
@ -303,8 +283,8 @@ function onIncomingMessage(user, message) {
|
|||
}
|
||||
// Triggers mic mute notification
|
||||
function onMuteStateChanged() {
|
||||
var muteState = AudioDevice.getMuted() ? "Muted" : "Unmuted";
|
||||
var muteString = "Microphone is set to " + muteState;
|
||||
var muteState = AudioDevice.getMuted() ? "muted" : "unmuted";
|
||||
var muteString = "Microphone is now " + muteState;
|
||||
createNotification(muteString);
|
||||
}
|
||||
|
||||
|
@ -345,7 +325,7 @@ function fadeOut(noticeOut, buttonOut, arraysOut) {
|
|||
pauseTimer = Script.setInterval(function() {
|
||||
r--;
|
||||
rFade = r / 10.0;
|
||||
Overlays.editOverlay(noticeOut, {alpha: rFade, backgroundAlpha: rFade});
|
||||
Overlays.editOverlay(noticeOut, {alpha: rFade});
|
||||
Overlays.editOverlay(buttonOut, {alpha: rFade});
|
||||
if (r < 0) {
|
||||
dismiss(noticeOut, buttonOut, arraysOut);
|
||||
|
@ -368,10 +348,17 @@ function dismiss(firstNoteOut, firstButOut, firstOut) {
|
|||
myAlpha.splice(firstOut,1);
|
||||
}
|
||||
|
||||
onMuteStateChanged();
|
||||
// This is meant to show users online at startup but currently shows 0 users.
|
||||
function onConnected() {
|
||||
var numUsers = GlobalServices.onlineUsers.length;
|
||||
var welcome = "Welcome! There are " + numUsers + " users online now.";
|
||||
createNotification(welcome);
|
||||
}
|
||||
|
||||
AudioDevice.muteToggled.connect(onMuteStateChanged);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
GlobalServices.connected.connect(onConnected);
|
||||
GlobalServices.onlineUsersChanged.connect(onOnlineUsersChanged);
|
||||
GlobalServices.incomingMessage.connect(onIncomingMessage);
|
||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||
|
|
|
@ -6,4 +6,4 @@ setup_hifi_project(Network)
|
|||
# link the shared hifi libraries
|
||||
link_hifi_libraries(networking shared)
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
|
@ -25,15 +25,15 @@ else ()
|
|||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
set(GL_HEADERS "#include <GLUT/glut.h>\n#include <OpenGL/glext.h>")
|
||||
set(GL_HEADERS "#include <OpenGL/glext.h>")
|
||||
elseif (UNIX)
|
||||
# include the right GL headers for UNIX
|
||||
set(GL_HEADERS "#include <GL/gl.h>\n#include <GL/glut.h>\n#include <GL/glext.h>")
|
||||
set(GL_HEADERS "#include <GL/gl.h>\n#include <GL/glext.h>")
|
||||
elseif (WIN32)
|
||||
add_definitions(-D_USE_MATH_DEFINES) # apparently needed to get M_PI and other defines from cmath/math.h
|
||||
add_definitions(-DWINDOWS_LEAN_AND_MEAN) # needed to make sure windows doesn't go to crazy with its defines
|
||||
|
||||
set(GL_HEADERS "#include <windowshacks.h>\n#include <GL/glew.h>\n#include <GL/glut.h>\n#include <GL/wglew.h>")
|
||||
set(GL_HEADERS "#include <windowshacks.h>\n#include <GL/glew.h>\n#include <GL/wglew.h>")
|
||||
endif ()
|
||||
|
||||
# set up the external glm library
|
||||
|
@ -194,11 +194,10 @@ if (APPLE)
|
|||
# link in required OS X frameworks and include the right GL headers
|
||||
find_library(CoreAudio CoreAudio)
|
||||
find_library(CoreFoundation CoreFoundation)
|
||||
find_library(GLUT GLUT)
|
||||
find_library(OpenGL OpenGL)
|
||||
find_library(AppKit AppKit)
|
||||
|
||||
target_link_libraries(${TARGET_NAME} ${CoreAudio} ${CoreFoundation} ${GLUT} ${OpenGL} ${AppKit})
|
||||
target_link_libraries(${TARGET_NAME} ${CoreAudio} ${CoreFoundation} ${OpenGL} ${AppKit})
|
||||
|
||||
# install command for OS X bundle
|
||||
INSTALL(TARGETS ${TARGET_NAME}
|
||||
|
@ -214,15 +213,12 @@ else (APPLE)
|
|||
)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLUT REQUIRED)
|
||||
|
||||
include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}")
|
||||
|
||||
if (${OPENGL_INCLUDE_DIR})
|
||||
include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}")
|
||||
endif ()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}" "${GLUT_LIBRARIES}")
|
||||
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}")
|
||||
|
||||
# link target to external libraries
|
||||
if (WIN32)
|
||||
|
@ -232,7 +228,7 @@ else (APPLE)
|
|||
# we're using static GLEW, so define GLEW_STATIC
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
|
||||
target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${NSIGHT_LIBRARIES}" wsock32.lib opengl32.lib)
|
||||
target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${NSIGHT_LIBRARIES}" wsock32.lib opengl32.lib Winmm.lib)
|
||||
|
||||
# try to find the Nsight package and add it to the build if we find it
|
||||
find_package(NSIGHT)
|
||||
|
@ -246,4 +242,4 @@ else (APPLE)
|
|||
endif (APPLE)
|
||||
|
||||
# link any dependencies bubbled up from our linked dependencies
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -130,7 +130,7 @@ static QTimer* idleTimer = NULL;
|
|||
const QString CHECK_VERSION_URL = "https://highfidelity.io/latestVersion.xml";
|
||||
const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion";
|
||||
|
||||
const QString DEFAULT_SCRIPTS_JS_URL = "http://public.highfidelity.io/scripts/defaultScripts.js";
|
||||
const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js";
|
||||
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||
QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
|
||||
|
@ -310,13 +310,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
// use our MyAvatar position and quat for address manager path
|
||||
addressManager.setPositionGetter(getPositionForPath);
|
||||
addressManager.setOrientationGetter(getOrientationForPath);
|
||||
|
||||
// handle domain change signals from AddressManager
|
||||
connect(&addressManager, &AddressManager::possibleDomainChangeRequiredToHostname,
|
||||
this, &Application::changeDomainHostname);
|
||||
|
||||
connect(&addressManager, &AddressManager::possibleDomainChangeRequiredViaICEForID,
|
||||
&domainHandler, &DomainHandler::setIceServerHostnameAndID);
|
||||
|
||||
_settings = new QSettings(this);
|
||||
_numChangedSettings = 0;
|
||||
|
@ -538,8 +531,6 @@ void Application::initializeGL() {
|
|||
} else {
|
||||
isInitialized = true;
|
||||
}
|
||||
int argc = 0;
|
||||
glutInit(&argc, 0);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -1436,7 +1427,7 @@ void Application::dropEvent(QDropEvent *event) {
|
|||
SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath);
|
||||
if (snapshotData) {
|
||||
if (!snapshotData->getDomain().isEmpty()) {
|
||||
changeDomainHostname(snapshotData->getDomain());
|
||||
DependencyManager::get<NodeList>()->getDomainHandler().setHostnameAndPort(snapshotData->getDomain());
|
||||
}
|
||||
|
||||
_myAvatar->setPosition(snapshotData->getLocation());
|
||||
|
@ -3577,7 +3568,7 @@ void Application::renderViewFrustum(ViewFrustum& viewFrustum) {
|
|||
glPushMatrix();
|
||||
glColor4f(1, 1, 0, 1);
|
||||
glTranslatef(position.x, position.y, position.z); // where we actually want it!
|
||||
glutWireSphere(keyholeRadius, 20, 20);
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(keyholeRadius, 20, 20, false);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
@ -3701,19 +3692,6 @@ void Application::updateLocationInServer() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::changeDomainHostname(const QString &newDomainHostname) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
if (!nodeList->getDomainHandler().isCurrentHostname(newDomainHostname)) {
|
||||
// tell the MyAvatar object to send a kill packet so that it dissapears from its old avatar mixer immediately
|
||||
_myAvatar->sendKillAvatar();
|
||||
|
||||
// call the domain hostname change as a queued connection on the nodelist
|
||||
QMetaObject::invokeMethod(&DependencyManager::get<NodeList>()->getDomainHandler(), "setHostname",
|
||||
Q_ARG(const QString&, newDomainHostname));
|
||||
}
|
||||
}
|
||||
|
||||
void Application::clearDomainOctreeDetails() {
|
||||
qDebug() << "Clearing domain octree details...";
|
||||
// reset the environment so that we don't erroneously end up with multiple
|
||||
|
|
|
@ -335,7 +335,6 @@ signals:
|
|||
void importDone();
|
||||
|
||||
public slots:
|
||||
void changeDomainHostname(const QString& newDomainHostname);
|
||||
void domainChanged(const QString& domainHostname);
|
||||
void updateWindowTitle();
|
||||
void updateLocationInServer();
|
||||
|
|
|
@ -10,11 +10,14 @@
|
|||
//
|
||||
// Creates single flexible verlet-integrated strands that can be used for hair/fur/grass
|
||||
|
||||
#include "Hair.h"
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include "Util.h"
|
||||
#include "world.h"
|
||||
|
||||
#include "Hair.h"
|
||||
|
||||
|
||||
const float HAIR_DAMPING = 0.99f;
|
||||
const float CONSTRAINT_RELAXATION = 10.0f;
|
||||
const float HAIR_ACCELERATION_COUPLING = 0.045f;
|
||||
|
|
|
@ -33,12 +33,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
// no clue which versions are affected...
|
||||
#define WORKAROUND_BROKEN_GLUT_STROKES
|
||||
// see http://www.opengl.org/resources/libraries/glut/spec3/node78.html
|
||||
|
||||
|
||||
|
||||
void renderWorldBox() {
|
||||
// Show edge of world
|
||||
float red[] = {1, 0, 0};
|
||||
|
|
|
@ -282,43 +282,64 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
|
|||
// render pointing lasers
|
||||
glm::vec3 laserColor = glm::vec3(1.0f, 0.0f, 1.0f);
|
||||
float laserLength = 50.0f;
|
||||
if (_handState == HAND_STATE_LEFT_POINTING ||
|
||||
_handState == HAND_STATE_BOTH_POINTING) {
|
||||
int leftIndex = _skeletonModel.getLeftHandJointIndex();
|
||||
glm::vec3 leftPosition;
|
||||
glm::quat leftRotation;
|
||||
_skeletonModel.getJointPositionInWorldFrame(leftIndex, leftPosition);
|
||||
_skeletonModel.getJointRotationInWorldFrame(leftIndex, leftRotation);
|
||||
glPushMatrix(); {
|
||||
glTranslatef(leftPosition.x, leftPosition.y, leftPosition.z);
|
||||
float angle = glm::degrees(glm::angle(leftRotation));
|
||||
glm::vec3 axis = glm::axis(leftRotation);
|
||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(laserColor.x, laserColor.y, laserColor.z);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, laserLength, 0.0f);
|
||||
glEnd();
|
||||
} glPopMatrix();
|
||||
glm::vec3 position;
|
||||
glm::quat rotation;
|
||||
bool havePosition, haveRotation;
|
||||
|
||||
if (_handState & LEFT_HAND_POINTING_FLAG) {
|
||||
|
||||
if (_handState & IS_FINGER_POINTING_FLAG) {
|
||||
int leftIndexTip = getJointIndex("LeftHandIndex4");
|
||||
int leftIndexTipJoint = getJointIndex("LeftHandIndex3");
|
||||
havePosition = _skeletonModel.getJointPositionInWorldFrame(leftIndexTip, position);
|
||||
haveRotation = _skeletonModel.getJointRotationInWorldFrame(leftIndexTipJoint, rotation);
|
||||
} else {
|
||||
int leftHand = _skeletonModel.getLeftHandJointIndex();
|
||||
havePosition = _skeletonModel.getJointPositionInWorldFrame(leftHand, position);
|
||||
haveRotation = _skeletonModel.getJointRotationInWorldFrame(leftHand, rotation);
|
||||
}
|
||||
|
||||
if (havePosition && haveRotation) {
|
||||
glPushMatrix(); {
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
float angle = glm::degrees(glm::angle(rotation));
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(laserColor.x, laserColor.y, laserColor.z);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, laserLength, 0.0f);
|
||||
glEnd();
|
||||
} glPopMatrix();
|
||||
}
|
||||
}
|
||||
if (_handState == HAND_STATE_RIGHT_POINTING ||
|
||||
_handState == HAND_STATE_BOTH_POINTING) {
|
||||
int rightIndex = _skeletonModel.getRightHandJointIndex();
|
||||
glm::vec3 rightPosition;
|
||||
glm::quat rightRotation;
|
||||
_skeletonModel.getJointPositionInWorldFrame(rightIndex, rightPosition);
|
||||
_skeletonModel.getJointRotationInWorldFrame(rightIndex, rightRotation);
|
||||
glPushMatrix(); {
|
||||
glTranslatef(rightPosition.x, rightPosition.y, rightPosition.z);
|
||||
float angle = glm::degrees(glm::angle(rightRotation));
|
||||
glm::vec3 axis = glm::axis(rightRotation);
|
||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(laserColor.x, laserColor.y, laserColor.z);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, laserLength, 0.0f);
|
||||
glEnd();
|
||||
} glPopMatrix();
|
||||
|
||||
if (_handState & RIGHT_HAND_POINTING_FLAG) {
|
||||
|
||||
if (_handState & IS_FINGER_POINTING_FLAG) {
|
||||
int rightIndexTip = getJointIndex("RightHandIndex4");
|
||||
int rightIndexTipJoint = getJointIndex("RightHandIndex3");
|
||||
havePosition = _skeletonModel.getJointPositionInWorldFrame(rightIndexTip, position);
|
||||
haveRotation = _skeletonModel.getJointRotationInWorldFrame(rightIndexTipJoint, rotation);
|
||||
} else {
|
||||
int rightHand = _skeletonModel.getRightHandJointIndex();
|
||||
havePosition = _skeletonModel.getJointPositionInWorldFrame(rightHand, position);
|
||||
haveRotation = _skeletonModel.getJointRotationInWorldFrame(rightHand, rotation);
|
||||
}
|
||||
|
||||
if (havePosition && haveRotation) {
|
||||
glPushMatrix(); {
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
float angle = glm::degrees(glm::angle(rotation));
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(laserColor.x, laserColor.y, laserColor.z);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, laserLength, 0.0f);
|
||||
glEnd();
|
||||
} glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,6 +669,49 @@ glm::vec3 Avatar::getDisplayNamePosition() {
|
|||
return namePosition;
|
||||
}
|
||||
|
||||
float Avatar::calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD) {
|
||||
|
||||
// We need to compute the scale factor such as the text remains with fixed size respect to window coordinates
|
||||
// We project a unit vector and check the difference in screen coordinates, to check which is the
|
||||
// correction scale needed
|
||||
// save the matrices for later scale correction factor
|
||||
// The up vector must be relative to the rotation current rotation matrix:
|
||||
// we set the identity
|
||||
glm::vec3 testPoint0 = textPosition;
|
||||
glm::vec3 testPoint1 = textPosition + (Application::getInstance()->getCamera()->getRotation() * IDENTITY_UP);
|
||||
|
||||
double textWindowHeight;
|
||||
|
||||
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
|
||||
float windowSizeX = glCanvas->getDeviceWidth();
|
||||
float windowSizeY = glCanvas->getDeviceHeight();
|
||||
|
||||
glm::dmat4 modelViewMatrix;
|
||||
glm::dmat4 projectionMatrix;
|
||||
Application::getInstance()->getModelViewMatrix(&modelViewMatrix);
|
||||
Application::getInstance()->getProjectionMatrix(&projectionMatrix);
|
||||
|
||||
glm::dvec4 p0 = modelViewMatrix * glm::dvec4(testPoint0, 1.0);
|
||||
p0 = projectionMatrix * p0;
|
||||
glm::dvec2 result0 = glm::vec2(windowSizeX * (p0.x / p0.w + 1.0f) * 0.5f, windowSizeY * (p0.y / p0.w + 1.0f) * 0.5f);
|
||||
|
||||
glm::dvec4 p1 = modelViewMatrix * glm::dvec4(testPoint1, 1.0);
|
||||
p1 = projectionMatrix * p1;
|
||||
glm::vec2 result1 = glm::vec2(windowSizeX * (p1.x / p1.w + 1.0f) * 0.5f, windowSizeY * (p1.y / p1.w + 1.0f) * 0.5f);
|
||||
textWindowHeight = abs(result1.y - result0.y);
|
||||
|
||||
// need to scale to compensate for the font resolution due to the device
|
||||
float scaleFactor = QApplication::desktop()->windowHandle()->devicePixelRatio() *
|
||||
((textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f);
|
||||
if (inHMD) {
|
||||
const float HMDMODE_NAME_SCALE = 0.65f;
|
||||
scaleFactor *= HMDMODE_NAME_SCALE;
|
||||
} else {
|
||||
scaleFactor *= Application::getInstance()->getRenderResolutionScale();
|
||||
}
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
void Avatar::renderDisplayName() {
|
||||
|
||||
if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) {
|
||||
|
@ -679,78 +743,39 @@ void Avatar::renderDisplayName() {
|
|||
frontAxis = glm::normalize(glm::vec3(frontAxis.z, 0.0f, -frontAxis.x));
|
||||
float angle = acos(frontAxis.x) * ((frontAxis.z < 0) ? 1.0f : -1.0f);
|
||||
glRotatef(glm::degrees(angle), 0.0f, 1.0f, 0.0f);
|
||||
|
||||
// We need to compute the scale factor such as the text remains with fixed size respect to window coordinates
|
||||
// We project a unit vector and check the difference in screen coordinates, to check which is the
|
||||
// correction scale needed
|
||||
// save the matrices for later scale correction factor
|
||||
glm::dmat4 modelViewMatrix;
|
||||
glm::dmat4 projectionMatrix;
|
||||
GLint viewportMatrix[4];
|
||||
Application::getInstance()->getModelViewMatrix(&modelViewMatrix);
|
||||
Application::getInstance()->getProjectionMatrix(&projectionMatrix);
|
||||
glGetIntegerv(GL_VIEWPORT, viewportMatrix);
|
||||
GLdouble result0[3], result1[3];
|
||||
|
||||
// The up vector must be relative to the rotation current rotation matrix:
|
||||
// we set the identity
|
||||
glm::dvec3 testPoint0 = glm::dvec3(textPosition);
|
||||
glm::dvec3 testPoint1 = glm::dvec3(textPosition) + glm::dvec3(Application::getInstance()->getCamera()->getRotation() * IDENTITY_UP);
|
||||
|
||||
bool success;
|
||||
success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z,
|
||||
(GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix,
|
||||
&result0[0], &result0[1], &result0[2]);
|
||||
success = success &&
|
||||
gluProject(testPoint1.x, testPoint1.y, testPoint1.z,
|
||||
(GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix,
|
||||
&result1[0], &result1[1], &result1[2]);
|
||||
float scaleFactor = calculateDisplayNameScaleFactor(textPosition, inHMD);
|
||||
glScalef(scaleFactor, scaleFactor, 1.0);
|
||||
|
||||
glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis
|
||||
|
||||
if (success) {
|
||||
double textWindowHeight = abs(result1[1] - result0[1]);
|
||||
// need to scale to compensate for the font resolution due to the device
|
||||
float scaleFactor = QApplication::desktop()->windowHandle()->devicePixelRatio() *
|
||||
((textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f);
|
||||
if (inHMD) {
|
||||
const float HMDMODE_NAME_SCALE = 0.65f;
|
||||
scaleFactor *= HMDMODE_NAME_SCALE;
|
||||
} else {
|
||||
scaleFactor *= Application::getInstance()->getRenderResolutionScale();
|
||||
}
|
||||
glScalef(scaleFactor, scaleFactor, 1.0);
|
||||
|
||||
glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis
|
||||
int text_x = -_displayNameBoundingRect.width() / 2;
|
||||
int text_y = -_displayNameBoundingRect.height() / 2;
|
||||
|
||||
int text_x = -_displayNameBoundingRect.width() / 2;
|
||||
int text_y = -_displayNameBoundingRect.height() / 2;
|
||||
// draw a gray background
|
||||
int left = text_x + _displayNameBoundingRect.x();
|
||||
int right = left + _displayNameBoundingRect.width();
|
||||
int bottom = text_y + _displayNameBoundingRect.y();
|
||||
int top = bottom + _displayNameBoundingRect.height();
|
||||
const int border = 8;
|
||||
bottom -= border;
|
||||
left -= border;
|
||||
top += border;
|
||||
right += border;
|
||||
|
||||
// draw a gray background
|
||||
int left = text_x + _displayNameBoundingRect.x();
|
||||
int right = left + _displayNameBoundingRect.width();
|
||||
int bottom = text_y + _displayNameBoundingRect.y();
|
||||
int top = bottom + _displayNameBoundingRect.height();
|
||||
const int border = 8;
|
||||
bottom -= border;
|
||||
left -= border;
|
||||
top += border;
|
||||
right += border;
|
||||
// We are drawing coplanar textures with depth: need the polygon offset
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.0f, 1.0f);
|
||||
|
||||
// We are drawing coplanar textures with depth: need the polygon offset
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.0f, 1.0f);
|
||||
|
||||
glColor4f(0.2f, 0.2f, 0.2f, _displayNameAlpha * DISPLAYNAME_BACKGROUND_ALPHA / DISPLAYNAME_ALPHA);
|
||||
renderBevelCornersRect(left, bottom, right - left, top - bottom, 3);
|
||||
|
||||
glColor4f(0.93f, 0.93f, 0.93f, _displayNameAlpha);
|
||||
QByteArray ba = _displayName.toLocal8Bit();
|
||||
const char* text = ba.data();
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
textRenderer(DISPLAYNAME)->draw(text_x, text_y, text);
|
||||
|
||||
|
||||
}
|
||||
glColor4f(0.2f, 0.2f, 0.2f, _displayNameAlpha * DISPLAYNAME_BACKGROUND_ALPHA / DISPLAYNAME_ALPHA);
|
||||
renderBevelCornersRect(left, bottom, right - left, top - bottom, 3);
|
||||
|
||||
glColor4f(0.93f, 0.93f, 0.93f, _displayNameAlpha);
|
||||
QByteArray ba = _displayName.toLocal8Bit();
|
||||
const char* text = ba.data();
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
textRenderer(DISPLAYNAME)->draw(text_x, text_y, text);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@ protected:
|
|||
float getPelvisFloatingHeight() const;
|
||||
glm::vec3 getDisplayNamePosition();
|
||||
|
||||
float calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD);
|
||||
void renderDisplayName();
|
||||
virtual void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
||||
virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
||||
|
|
|
@ -153,7 +153,7 @@ void Hand::renderHandTargets(bool isMine) {
|
|||
|
||||
const float collisionRadius = 0.05f;
|
||||
glColor4f(0.5f,0.5f,0.5f, alpha);
|
||||
glutWireSphere(collisionRadius, 10.0f, 10.0f);
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(collisionRadius, 10, 10, false);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,15 +21,6 @@
|
|||
|
||||
class ModelItemID;
|
||||
|
||||
enum AvatarHandState
|
||||
{
|
||||
HAND_STATE_NULL = 0,
|
||||
HAND_STATE_LEFT_POINTING,
|
||||
HAND_STATE_RIGHT_POINTING,
|
||||
HAND_STATE_BOTH_POINTING,
|
||||
NUM_HAND_STATES
|
||||
};
|
||||
|
||||
class MyAvatar : public Avatar {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool shouldRenderLocally READ getShouldRenderLocally WRITE setShouldRenderLocally)
|
||||
|
|
|
@ -582,7 +582,7 @@ void OculusManager::renderDistortionMesh(ovrPosef eyeRenderPose[ovrEye_Count]) {
|
|||
|
||||
glLoadIdentity();
|
||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||
gluOrtho2D(0, glCanvas->getDeviceWidth(), 0, glCanvas->getDeviceHeight());
|
||||
glOrtho(0, glCanvas->getDeviceWidth(), 0, glCanvas->getDeviceHeight(), -1.0, 1.0);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
|
|
|
@ -116,8 +116,9 @@ void AddressBarDialog::setupUI() {
|
|||
|
||||
void AddressBarDialog::showEvent(QShowEvent* event) {
|
||||
_goButton->setIcon(QIcon(PathUtils::resourcesPath() + ADDRESSBAR_GO_BUTTON_ICON));
|
||||
_addressLineEdit->setText(QString());
|
||||
_addressLineEdit->setText(AddressManager::getInstance().currentAddress().toString());
|
||||
_addressLineEdit->setFocus();
|
||||
_addressLineEdit->selectAll();
|
||||
FramelessDialog::showEvent(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
|
||||
glPushMatrix(); {
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, glCanvas->width(), glCanvas->height(), 0);
|
||||
glOrtho(0, glCanvas->width(), glCanvas->height(), 0, -1.0, 1.0);
|
||||
|
||||
renderAudioMeter();
|
||||
|
||||
|
@ -224,7 +224,7 @@ void ApplicationOverlay::displayOverlayTexture() {
|
|||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix(); {
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight(), 0);
|
||||
glOrtho(0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight(), 0, -1.0, 1.0);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <QVBoxLayout>
|
||||
|
||||
#include <AttributeRegistry.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <MetavoxelMessages.h>
|
||||
#include <MetavoxelUtil.h>
|
||||
#include <PathUtils.h>
|
||||
|
@ -492,12 +493,11 @@ void BoxTool::render() {
|
|||
glColor4f(GRID_BRIGHTNESS, GRID_BRIGHTNESS, GRID_BRIGHTNESS, BOX_ALPHA);
|
||||
}
|
||||
glEnable(GL_CULL_FACE);
|
||||
glutSolidCube(1.0);
|
||||
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f);
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
glColor3f(GRID_BRIGHTNESS, GRID_BRIGHTNESS, GRID_BRIGHTNESS);
|
||||
glutWireCube(1.0);
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderWireCube(1.0f);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <GeometryCache.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
@ -132,7 +134,7 @@ void NodeBounds::draw() {
|
|||
getColorForNodeType(selectedNode->getType(), red, green, blue);
|
||||
|
||||
glColor4f(red, green, blue, 0.2f);
|
||||
glutSolidCube(1.0);
|
||||
DependencyManager::get<GeometryCache>()->renderSolidCube(1.0f);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint texture
|
|||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
gluOrtho2D(bounds.left(), bounds.right(), bounds.bottom(), bounds.top());
|
||||
glOrtho(bounds.left(), bounds.right(), bounds.bottom(), bounds.top(), -1.0, 1.0);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
|
|
@ -100,26 +100,31 @@ void ImageOverlay::render(RenderArgs* args) {
|
|||
float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure
|
||||
float h = fromImage.height() / imageHeight;
|
||||
|
||||
int left = _bounds.left();
|
||||
int right = _bounds.right() + 1;
|
||||
int top = _bounds.top();
|
||||
int bottom = _bounds.bottom() + 1;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x, 1.0f - y);
|
||||
}
|
||||
glVertex2f(_bounds.left(), _bounds.top());
|
||||
glVertex2f(left, top);
|
||||
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x + w, 1.0f - y);
|
||||
}
|
||||
glVertex2f(_bounds.right(), _bounds.top());
|
||||
glVertex2f(right, top);
|
||||
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x + w, 1.0f - (y + h));
|
||||
}
|
||||
glVertex2f(_bounds.right(), _bounds.bottom());
|
||||
glVertex2f(right, bottom);
|
||||
|
||||
if (_renderImage) {
|
||||
glTexCoord2f(x, 1.0f - (y + h));
|
||||
}
|
||||
glVertex2f(_bounds.left(), _bounds.bottom());
|
||||
glVertex2f(left, bottom);
|
||||
glEnd();
|
||||
|
||||
if (_renderImage) {
|
||||
|
|
|
@ -62,11 +62,7 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
|||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
if (_isSolid) {
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(1.0f, SLICES, SLICES);
|
||||
} else {
|
||||
glutWireSphere(1.0f, SLICES, SLICES);
|
||||
}
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(1.0f, SLICES, SLICES, _isSolid);
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
|
||||
|
|
|
@ -70,11 +70,16 @@ void TextOverlay::render(RenderArgs* args) {
|
|||
glColor4f(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR,
|
||||
getBackgroundAlpha());
|
||||
|
||||
int left = _bounds.left();
|
||||
int right = _bounds.right() + 1;
|
||||
int top = _bounds.top();
|
||||
int bottom = _bounds.bottom() + 1;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(_bounds.left(), _bounds.top());
|
||||
glVertex2f(_bounds.right(), _bounds.top());
|
||||
glVertex2f(_bounds.right(), _bounds.bottom());
|
||||
glVertex2f(_bounds.left(), _bounds.bottom());
|
||||
glVertex2f(left, top);
|
||||
glVertex2f(right, top);
|
||||
glVertex2f(right, bottom);
|
||||
glVertex2f(left, bottom);
|
||||
glEnd();
|
||||
|
||||
// Same font properties as textSize()
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <GlowEffect.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <VoxelConstants.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -47,7 +48,7 @@ void VoxelFade::render() {
|
|||
voxelDetails.y + voxelDetails.s * 0.5f,
|
||||
voxelDetails.z + voxelDetails.s * 0.5f);
|
||||
glLineWidth(1.0f);
|
||||
glutSolidCube(voxelDetails.s);
|
||||
DependencyManager::get<GeometryCache>()->renderSolidCube(voxelDetails.s);
|
||||
glLineWidth(1.0f);
|
||||
glPopMatrix();
|
||||
glEnable(GL_LIGHTING);
|
||||
|
|
|
@ -5,5 +5,5 @@ setup_hifi_library(Network Script)
|
|||
|
||||
link_hifi_libraries(shared fbx)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -7,5 +7,5 @@ include_glm()
|
|||
|
||||
link_hifi_libraries(networking shared)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -5,8 +5,7 @@ setup_hifi_library(Network Script)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared octree voxels networking physics)
|
||||
include_hifi_library_headers(fbx)
|
||||
link_hifi_libraries(audio shared octree voxels networking physics fbx)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -188,7 +188,11 @@ QByteArray AvatarData::toByteArray() {
|
|||
// key state
|
||||
setSemiNibbleAt(bitItems,KEY_STATE_START_BIT,_keyState);
|
||||
// hand state
|
||||
setSemiNibbleAt(bitItems,HAND_STATE_START_BIT,_handState);
|
||||
bool isFingerPointing = _handState & IS_FINGER_POINTING_FLAG;
|
||||
setSemiNibbleAt(bitItems, HAND_STATE_START_BIT, _handState & ~IS_FINGER_POINTING_FLAG);
|
||||
if (isFingerPointing) {
|
||||
setAtBit(bitItems, HAND_STATE_FINGER_POINTING_BIT);
|
||||
}
|
||||
// faceshift state
|
||||
if (_headData->_isFaceshiftConnected) {
|
||||
setAtBit(bitItems, IS_FACESHIFT_CONNECTED);
|
||||
|
@ -439,8 +443,16 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
|
|||
|
||||
// key state, stored as a semi-nibble in the bitItems
|
||||
_keyState = (KeyState)getSemiNibbleAt(bitItems,KEY_STATE_START_BIT);
|
||||
// hand state, stored as a semi-nibble in the bitItems
|
||||
_handState = getSemiNibbleAt(bitItems,HAND_STATE_START_BIT);
|
||||
|
||||
// hand state, stored as a semi-nibble plus a bit in the bitItems
|
||||
// we store the hand state as well as other items in a shared bitset. The hand state is an octal, but is split
|
||||
// into two sections to maintain backward compatibility. The bits are ordered as such (0-7 left to right).
|
||||
// +---+-----+-----+--+
|
||||
// |x,x|H0,H1|x,x,x|H2|
|
||||
// +---+-----+-----+--+
|
||||
// Hand state - H0,H1,H2 is found in the 3rd, 4th, and 8th bits
|
||||
_handState = getSemiNibbleAt(bitItems, HAND_STATE_START_BIT)
|
||||
+ (oneAtBit(bitItems, HAND_STATE_FINGER_POINTING_BIT) ? IS_FINGER_POINTING_FLAG : 0);
|
||||
|
||||
_headData->_isFaceshiftConnected = oneAtBit(bitItems, IS_FACESHIFT_CONNECTED);
|
||||
_isChatCirclingEnabled = oneAtBit(bitItems, IS_CHAT_CIRCLING_ENABLED);
|
||||
|
|
|
@ -76,12 +76,28 @@ const quint32 AVATAR_MOTION_SCRIPTABLE_BITS =
|
|||
AVATAR_MOTION_STAND_ON_NEARBY_FLOORS;
|
||||
|
||||
|
||||
// First bitset
|
||||
// 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
|
||||
// backward compatibility. The bits are ordered as such (0-7 left to right).
|
||||
// +-----+-----+-+-+-+--+
|
||||
// |K0,K1|H0,H1|F|C|R|H2|
|
||||
// +-----+-----+-+-+-+--+
|
||||
// Key state - K0,K1 is found in the 1st and 2nd bits
|
||||
// Hand state - H0,H1,H2 is found in the 3rd, 4th, and 8th bits
|
||||
// Faceshift - F is found in the 5th bit
|
||||
// Chat Circling - C is found in the 6th bit
|
||||
// Referential Data - R is found in the 7th bit
|
||||
const int KEY_STATE_START_BIT = 0; // 1st and 2nd bits
|
||||
const int HAND_STATE_START_BIT = 2; // 3rd and 4th bits
|
||||
const int IS_FACESHIFT_CONNECTED = 4; // 5th bit
|
||||
const int IS_CHAT_CIRCLING_ENABLED = 5; // 6th bit
|
||||
const int HAS_REFERENTIAL = 6; // 7th bit
|
||||
const int HAND_STATE_FINGER_POINTING_BIT = 7; // 8th bit
|
||||
|
||||
const char HAND_STATE_NULL = 0;
|
||||
const char LEFT_HAND_POINTING_FLAG = 1;
|
||||
const char RIGHT_HAND_POINTING_FLAG = 2;
|
||||
const char IS_FINGER_POINTING_FLAG = 4;
|
||||
|
||||
static const float MAX_AVATAR_SCALE = 1000.0f;
|
||||
static const float MIN_AVATAR_SCALE = .005f;
|
||||
|
|
|
@ -3,5 +3,5 @@ set(TARGET_NAME embedded-webserver)
|
|||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Network)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -5,7 +5,7 @@ setup_hifi_library(Widgets OpenGL Network Script)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared gpu script-engine)
|
||||
link_hifi_libraries(shared gpu script-engine render-utils)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -62,6 +62,7 @@ EntityTreeRenderer::~EntityTreeRenderer() {
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::clear() {
|
||||
leaveAllEntities();
|
||||
foreach (const EntityItemID& entityID, _entityScripts.keys()) {
|
||||
checkAndCallUnload(entityID);
|
||||
}
|
||||
|
@ -82,8 +83,7 @@ void EntityTreeRenderer::init() {
|
|||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
glm::vec3 avatarPosition = _viewState->getAvatarPosition();
|
||||
_lastAvatarPosition = avatarPosition + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
|
||||
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::checkAndCallPreload);
|
||||
|
@ -97,13 +97,15 @@ QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItem
|
|||
}
|
||||
|
||||
|
||||
QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText) {
|
||||
QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL) {
|
||||
QUrl url(scriptMaybeURLorText);
|
||||
|
||||
// If the url is not valid, this must be script text...
|
||||
if (!url.isValid()) {
|
||||
isURL = false;
|
||||
return scriptMaybeURLorText;
|
||||
}
|
||||
isURL = true;
|
||||
|
||||
QString scriptContents; // assume empty
|
||||
|
||||
|
@ -173,7 +175,8 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
|
|||
return QScriptValue(); // no script
|
||||
}
|
||||
|
||||
QString scriptContents = loadScriptContents(entityScript);
|
||||
bool isURL = false; // loadScriptContents() will tell us if this is a URL or just text.
|
||||
QString scriptContents = loadScriptContents(entityScript, isURL);
|
||||
|
||||
QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(scriptContents);
|
||||
if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
|
||||
|
@ -184,6 +187,9 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
|
|||
return QScriptValue(); // invalid script
|
||||
}
|
||||
|
||||
if (isURL) {
|
||||
_entitiesScriptEngine->setParentURL(entity->getScript());
|
||||
}
|
||||
QScriptValue entityScriptConstructor = _entitiesScriptEngine->evaluate(scriptContents);
|
||||
|
||||
if (!entityScriptConstructor.isFunction()) {
|
||||
|
@ -197,6 +203,10 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
|
|||
EntityScriptDetails newDetails = { entityScript, entityScriptObject };
|
||||
_entityScripts[entityID] = newDetails;
|
||||
|
||||
if (isURL) {
|
||||
_entitiesScriptEngine->setParentURL("");
|
||||
}
|
||||
|
||||
return entityScriptObject; // newly constructed
|
||||
}
|
||||
|
||||
|
@ -287,6 +297,27 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::leaveAllEntities() {
|
||||
if (_tree) {
|
||||
_tree->lockForWrite(); // so that our scripts can do edits if they want
|
||||
|
||||
// for all of our previous containing entities, if they are no longer containing then send them a leave event
|
||||
foreach(const EntityItemID& entityID, _currentEntitiesInside) {
|
||||
emit leaveEntity(entityID);
|
||||
QScriptValueList entityArgs = createEntityArgs(entityID);
|
||||
QScriptValue entityScript = loadEntityScript(entityID);
|
||||
if (entityScript.property("leaveEntity").isValid()) {
|
||||
entityScript.property("leaveEntity").call(entityScript, entityArgs);
|
||||
}
|
||||
}
|
||||
_currentEntitiesInside.clear();
|
||||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
// first chance, we'll check for enter/leave entity events.
|
||||
_lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
_tree->unlock();
|
||||
}
|
||||
}
|
||||
void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) {
|
||||
if (_tree) {
|
||||
Model::startScene(renderSide);
|
||||
|
|
|
@ -129,6 +129,7 @@ private:
|
|||
|
||||
QScriptValueList createEntityArgs(const EntityItemID& entityID);
|
||||
void checkEnterLeaveEntities();
|
||||
void leaveAllEntities();
|
||||
glm::vec3 _lastAvatarPosition;
|
||||
QVector<EntityItemID> _currentEntitiesInside;
|
||||
|
||||
|
@ -138,7 +139,7 @@ private:
|
|||
QScriptValue loadEntityScript(EntityItem* entity);
|
||||
QScriptValue loadEntityScript(const EntityItemID& entityItemID);
|
||||
QScriptValue getPreviouslyLoadedEntityScript(const EntityItemID& entityItemID);
|
||||
QString loadScriptContents(const QString& scriptMaybeURLorText);
|
||||
QString loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL);
|
||||
QScriptValueList createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID);
|
||||
QScriptValueList createMouseEventArgs(const EntityItemID& entityID, const MouseEvent& mouseEvent);
|
||||
|
||||
|
|
|
@ -28,79 +28,23 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
|||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenter() * (float)TREE_SCALE;
|
||||
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::vec3 halfDimensions = dimensions / 2.0f;
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
const bool useGlutCube = true;
|
||||
const float MAX_COLOR = 255.0f;
|
||||
|
||||
if (useGlutCube) {
|
||||
glColor4f(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR,
|
||||
getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());
|
||||
glColor4f(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR,
|
||||
getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
glPushMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(1.0f);
|
||||
glPopMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(1.0f);
|
||||
glPopMatrix();
|
||||
} else {
|
||||
static GLfloat vertices[] = { 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)
|
||||
1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)
|
||||
1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0,v5,v6,v1 (top)
|
||||
-1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1,v6,v7,v2 (left)
|
||||
-1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, // v7,v4,v3,v2 (bottom)
|
||||
1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)
|
||||
glPopMatrix();
|
||||
|
||||
// normal array
|
||||
static GLfloat normals[] = { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
|
||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
|
||||
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)
|
||||
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left)
|
||||
0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7,v4,v3,v2 (bottom)
|
||||
0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 }; // v4,v7,v6,v5 (back)
|
||||
|
||||
// index array of vertex array for glDrawElements() & glDrawRangeElement()
|
||||
static GLubyte indices[] = { 0, 1, 2, 2, 3, 0, // front
|
||||
4, 5, 6, 6, 7, 4, // right
|
||||
8, 9,10, 10,11, 8, // top
|
||||
12,13,14, 14,15,12, // left
|
||||
16,17,18, 18,19,16, // bottom
|
||||
20,21,22, 22,23,20 }; // back
|
||||
|
||||
|
||||
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, 0, normals);
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertices);
|
||||
|
||||
glColor4f(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR,
|
||||
getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
glPushMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
// we need to do half the size because the geometry in the VBOs are from -1,-1,-1 to 1,1,1
|
||||
glScalef(halfDimensions.x, halfDimensions.y, halfDimensions.z);
|
||||
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
|
||||
DependencyManager::get<DeferredLightingEffect>()->releaseSimpleProgram();
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -34,9 +34,9 @@ RenderableModelEntityItem::~RenderableModelEntityItem() {
|
|||
}
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
bool RenderableModelEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
QString oldModelURL = getModelURL();
|
||||
bool somethingChanged = ModelEntityItem::setProperties(properties, forceCopy);
|
||||
bool somethingChanged = ModelEntityItem::setProperties(properties);
|
||||
if (somethingChanged && oldModelURL != getModelURL()) {
|
||||
_needsModelReload = true;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
virtual ~RenderableModelEntityItem();
|
||||
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy);
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
||||
|
|
|
@ -5,7 +5,7 @@ setup_hifi_library(Network Script)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared octree fbx networking animation physics)
|
||||
link_hifi_libraries(avatars shared octree fbx networking animation physics)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -29,7 +29,7 @@ BoxEntityItem::BoxEntityItem(const EntityItemID& entityItemID, const EntityItemP
|
|||
{
|
||||
_type = EntityTypes::Box;
|
||||
_created = properties.getCreated();
|
||||
setProperties(properties, true);
|
||||
setProperties(properties);
|
||||
}
|
||||
|
||||
EntityItemProperties BoxEntityItem::getProperties() const {
|
||||
|
@ -44,9 +44,9 @@ EntityItemProperties BoxEntityItem::getProperties() const {
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool BoxEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
bool BoxEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
|
||||
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
|
|
@ -53,14 +53,13 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
|
|||
_creatorTokenID = entityItemID.creatorTokenID;
|
||||
|
||||
// init values with defaults before calling setProperties
|
||||
//uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
_lastSimulated = now;
|
||||
_lastUpdated = now;
|
||||
_lastEdited = 0;
|
||||
_lastEditedFromRemote = 0;
|
||||
_lastEditedFromRemoteInRemoteTime = 0;
|
||||
|
||||
_lastSimulated = 0;
|
||||
_lastUpdated = 0;
|
||||
_created = 0; // TODO: when do we actually want to make this "now"
|
||||
_created = UNKNOWN_CREATED_TIME;
|
||||
_changedOnServer = 0;
|
||||
|
||||
_position = glm::vec3(0,0,0);
|
||||
|
@ -86,12 +85,13 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
|
|||
|
||||
EntityItem::EntityItem(const EntityItemID& entityItemID) {
|
||||
_type = EntityTypes::Unknown;
|
||||
quint64 now = usecTimestampNow();
|
||||
_lastSimulated = now;
|
||||
_lastUpdated = now;
|
||||
_lastEdited = 0;
|
||||
_lastEditedFromRemote = 0;
|
||||
_lastEditedFromRemoteInRemoteTime = 0;
|
||||
_lastSimulated = 0;
|
||||
_lastUpdated = 0;
|
||||
_created = 0;
|
||||
_created = UNKNOWN_CREATED_TIME;
|
||||
_dirtyFlags = 0;
|
||||
_changedOnServer = 0;
|
||||
initFromEntityItemID(entityItemID);
|
||||
|
@ -99,16 +99,17 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) {
|
|||
|
||||
EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) {
|
||||
_type = EntityTypes::Unknown;
|
||||
quint64 now = usecTimestampNow();
|
||||
_lastSimulated = now;
|
||||
_lastUpdated = now;
|
||||
_lastEdited = 0;
|
||||
_lastEditedFromRemote = 0;
|
||||
_lastEditedFromRemoteInRemoteTime = 0;
|
||||
_lastSimulated = 0;
|
||||
_lastUpdated = 0;
|
||||
_created = properties.getCreated();
|
||||
_created = UNKNOWN_CREATED_TIME;
|
||||
_dirtyFlags = 0;
|
||||
_changedOnServer = 0;
|
||||
initFromEntityItemID(entityItemID);
|
||||
setProperties(properties, true); // force copy
|
||||
setProperties(properties);
|
||||
}
|
||||
|
||||
EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
|
@ -365,9 +366,16 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
memcpy(&createdFromBuffer, dataAt, sizeof(createdFromBuffer));
|
||||
dataAt += sizeof(createdFromBuffer);
|
||||
bytesRead += sizeof(createdFromBuffer);
|
||||
createdFromBuffer -= clockSkew;
|
||||
|
||||
_created = createdFromBuffer; // TODO: do we ever want to discard this???
|
||||
|
||||
quint64 now = usecTimestampNow();
|
||||
if (_created == UNKNOWN_CREATED_TIME) {
|
||||
// we don't yet have a _created timestamp, so we accept this one
|
||||
createdFromBuffer -= clockSkew;
|
||||
if (createdFromBuffer > now || createdFromBuffer == UNKNOWN_CREATED_TIME) {
|
||||
createdFromBuffer = now;
|
||||
}
|
||||
_created = createdFromBuffer;
|
||||
}
|
||||
|
||||
if (wantDebug) {
|
||||
quint64 lastEdited = getLastEdited();
|
||||
|
@ -381,7 +389,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
qDebug() << " ago=" << editedAgo << "seconds - " << agoAsString;
|
||||
}
|
||||
|
||||
quint64 now = usecTimestampNow();
|
||||
quint64 lastEditedFromBuffer = 0;
|
||||
quint64 lastEditedFromBufferAdjusted = 0;
|
||||
|
||||
|
@ -391,6 +398,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
dataAt += sizeof(lastEditedFromBuffer);
|
||||
bytesRead += sizeof(lastEditedFromBuffer);
|
||||
lastEditedFromBufferAdjusted = lastEditedFromBuffer - clockSkew;
|
||||
if (lastEditedFromBufferAdjusted > now) {
|
||||
lastEditedFromBufferAdjusted = now;
|
||||
}
|
||||
|
||||
bool fromSameServerEdit = (lastEditedFromBuffer == _lastEditedFromRemoteInRemoteTime);
|
||||
|
||||
|
@ -439,10 +449,13 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
qDebug() << "USING NEW data from server!!! ****************";
|
||||
}
|
||||
|
||||
// don't allow _lastEdited to be in the future
|
||||
_lastEdited = lastEditedFromBufferAdjusted;
|
||||
_lastEditedFromRemote = now;
|
||||
_lastEditedFromRemoteInRemoteTime = lastEditedFromBuffer;
|
||||
|
||||
// TODO: only send this notification if something ACTUALLY changed (hint, we haven't yet parsed
|
||||
// the properties out of the bitstream (see below))
|
||||
somethingChangedNotification(); // notify derived classes that something has changed
|
||||
}
|
||||
|
||||
|
@ -451,7 +464,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
ByteCountCoded<quint64> updateDeltaCoder = encodedUpdateDelta;
|
||||
quint64 updateDelta = updateDeltaCoder;
|
||||
if (overwriteLocalData) {
|
||||
_lastSimulated = _lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that for _lastEdited
|
||||
_lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that
|
||||
if (wantDebug) {
|
||||
qDebug() << "_lastUpdated =" << _lastUpdated;
|
||||
qDebug() << "_lastEdited=" << _lastEdited;
|
||||
|
@ -523,6 +536,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData);
|
||||
|
||||
recalculateCollisionShape();
|
||||
if (overwriteLocalData && (getDirtyFlags() & EntityItem::DIRTY_POSITION)) {
|
||||
_lastSimulated = now;
|
||||
}
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
@ -576,7 +592,7 @@ void EntityItem::simulate(const quint64& now) {
|
|||
float timeElapsed = (float)(now - _lastSimulated) / (float)(USECS_PER_SECOND);
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << "********** EntityItem::update()";
|
||||
qDebug() << "********** EntityItem::simulate()";
|
||||
qDebug() << " entity ID=" << getEntityItemID();
|
||||
qDebug() << " now=" << now;
|
||||
qDebug() << " _lastSimulated=" << _lastSimulated;
|
||||
|
@ -612,10 +628,8 @@ void EntityItem::simulate(const quint64& now) {
|
|||
}
|
||||
}
|
||||
|
||||
_lastSimulated = now;
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << " ********** EntityItem::update() .... SETTING _lastSimulated=" << _lastSimulated;
|
||||
qDebug() << " ********** EntityItem::simulate() .... SETTING _lastSimulated=" << _lastSimulated;
|
||||
}
|
||||
|
||||
if (hasAngularVelocity()) {
|
||||
|
@ -651,7 +665,7 @@ void EntityItem::simulate(const quint64& now) {
|
|||
glm::vec3 newPosition = position + (velocity * timeElapsed);
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << " EntityItem::update()....";
|
||||
qDebug() << " EntityItem::simulate()....";
|
||||
qDebug() << " timeElapsed:" << timeElapsed;
|
||||
qDebug() << " old AACube:" << getMaximumAACube();
|
||||
qDebug() << " old position:" << position;
|
||||
|
@ -677,15 +691,15 @@ void EntityItem::simulate(const quint64& now) {
|
|||
}
|
||||
|
||||
// handle gravity....
|
||||
if (hasGravity() && !isRestingOnSurface()) {
|
||||
velocity += getGravity() * timeElapsed;
|
||||
}
|
||||
|
||||
// handle resting on surface case, this is definitely a bit of a hack, and it only works on the
|
||||
// "ground" plane of the domain, but for now it
|
||||
if (hasGravity() && isRestingOnSurface()) {
|
||||
velocity.y = 0.0f;
|
||||
position.y = getDistanceToBottomOfEntity();
|
||||
if (hasGravity()) {
|
||||
// handle resting on surface case, this is definitely a bit of a hack, and it only works on the
|
||||
// "ground" plane of the domain, but for now it what we've got
|
||||
if (isRestingOnSurface()) {
|
||||
velocity.y = 0.0f;
|
||||
position.y = getDistanceToBottomOfEntity();
|
||||
} else {
|
||||
velocity += getGravity() * timeElapsed;
|
||||
}
|
||||
}
|
||||
|
||||
// handle damping for velocity
|
||||
|
@ -721,6 +735,8 @@ void EntityItem::simulate(const quint64& now) {
|
|||
qDebug() << " old getAABox:" << getAABox();
|
||||
}
|
||||
}
|
||||
|
||||
_lastSimulated = now;
|
||||
}
|
||||
|
||||
bool EntityItem::isMoving() const {
|
||||
|
@ -768,18 +784,9 @@ EntityItemProperties EntityItem::getProperties() const {
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool EntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
// handle the setting of created timestamps for the basic new entity case
|
||||
if (forceCopy) {
|
||||
if (properties.getCreated() == UNKNOWN_CREATED_TIME) {
|
||||
_created = usecTimestampNow();
|
||||
} else if (properties.getCreated() != USE_EXISTING_CREATED_TIME) {
|
||||
_created = properties.getCreated();
|
||||
}
|
||||
}
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, updatePositionInMeters); // this will call recalculate collision shape if needed
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, updateDimensionsInMeters); // NOTE: radius is obsolete
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, updateRotation);
|
||||
|
@ -803,18 +810,49 @@ bool EntityItem::setProperties(const EntityItemProperties& properties, bool forc
|
|||
if (somethingChanged) {
|
||||
somethingChangedNotification(); // notify derived classes that something has changed
|
||||
bool wantDebug = false;
|
||||
uint64_t now = usecTimestampNow();
|
||||
if (wantDebug) {
|
||||
uint64_t now = usecTimestampNow();
|
||||
int elapsed = now - getLastEdited();
|
||||
qDebug() << "EntityItem::setProperties() AFTER update... edited AGO=" << elapsed <<
|
||||
"now=" << now << " getLastEdited()=" << getLastEdited();
|
||||
}
|
||||
setLastEdited(properties._lastEdited);
|
||||
if (_created != UNKNOWN_CREATED_TIME) {
|
||||
setLastEdited(now);
|
||||
}
|
||||
if (getDirtyFlags() & EntityItem::DIRTY_POSITION) {
|
||||
_lastSimulated = now;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// timestamps
|
||||
quint64 timestamp = properties.getCreated();
|
||||
if (_created == UNKNOWN_CREATED_TIME && timestamp != UNKNOWN_CREATED_TIME) {
|
||||
quint64 now = usecTimestampNow();
|
||||
if (timestamp > now) {
|
||||
timestamp = now;
|
||||
}
|
||||
_created = timestamp;
|
||||
|
||||
timestamp = properties.getLastEdited();
|
||||
if (timestamp > now) {
|
||||
timestamp = now;
|
||||
} else if (timestamp < _created) {
|
||||
timestamp = _created;
|
||||
}
|
||||
_lastEdited = timestamp;
|
||||
}
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
void EntityItem::recordCreationTime() {
|
||||
assert(_created == UNKNOWN_CREATED_TIME);
|
||||
_created = usecTimestampNow();
|
||||
_lastEdited = _created;
|
||||
_lastUpdated = _created;
|
||||
_lastSimulated = _created;
|
||||
}
|
||||
|
||||
|
||||
// TODO: is this really correct? how do we use size, does it need to handle rotation?
|
||||
float EntityItem::getSize() const {
|
||||
|
|
|
@ -74,18 +74,19 @@ public:
|
|||
virtual EntityItemProperties getProperties() const;
|
||||
|
||||
/// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
/// Override this in your derived class if you'd like to be informed when something about the state of the entity
|
||||
/// has changed. This will be called with properties change or when new data is loaded from a stream
|
||||
virtual void somethingChangedNotification() { }
|
||||
|
||||
void recordCreationTime(); // set _created to 'now'
|
||||
quint64 getLastSimulated() const { return _lastSimulated; } /// Last simulated time of this entity universal usecs
|
||||
|
||||
/// Last edited time of this entity universal usecs
|
||||
quint64 getLastEdited() const { return _lastEdited; }
|
||||
void setLastEdited(quint64 lastEdited)
|
||||
{ _lastEdited = _lastSimulated = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
|
||||
{ _lastEdited = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
|
||||
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
|
||||
{ return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; }
|
||||
|
||||
|
@ -120,9 +121,6 @@ public:
|
|||
|
||||
static int expectedBytes();
|
||||
|
||||
static bool encodeEntityEditMessageDetails(PacketType command, EntityItemID id, const EntityItemProperties& details,
|
||||
unsigned char* bufferOut, int sizeIn, int& sizeOut);
|
||||
|
||||
static void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, size_t length, int clockSkew);
|
||||
|
||||
// perform update
|
||||
|
|
|
@ -156,6 +156,17 @@ void EntityItemProperties::debugDump() const {
|
|||
props.debugDumpBits();
|
||||
}
|
||||
|
||||
void EntityItemProperties::setCreated(quint64 usecTime) {
|
||||
_created = usecTime;
|
||||
if (_lastEdited < _created) {
|
||||
_lastEdited = _created;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItemProperties::setLastEdited(quint64 usecTime) {
|
||||
_lastEdited = usecTime > _created ? usecTime : _created;
|
||||
}
|
||||
|
||||
EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
|
@ -652,9 +663,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
entityID.creatorTokenID = UNKNOWN_ENTITY_TOKEN;
|
||||
entityID.isKnownID = true;
|
||||
valid = true;
|
||||
|
||||
// created time is lastEdited time
|
||||
properties.setCreated(USE_EXISTING_CREATED_TIME);
|
||||
}
|
||||
|
||||
// Entity Type...
|
||||
|
|
|
@ -95,9 +95,7 @@ enum EntityPropertyList {
|
|||
|
||||
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
||||
|
||||
const quint64 UNKNOWN_CREATED_TIME = (quint64)(-1);
|
||||
const quint64 USE_EXISTING_CREATED_TIME = (quint64)(-2);
|
||||
|
||||
const quint64 UNKNOWN_CREATED_TIME = 0;
|
||||
|
||||
/// A collection of properties of an entity item used in the scripting API. Translates between the actual properties of an
|
||||
/// entity and a JavaScript style hash/QScriptValue storing a set of properties. Used in scripting to set/get the complete
|
||||
|
@ -134,7 +132,7 @@ public:
|
|||
AABox getAABoxInMeters() const;
|
||||
|
||||
void debugDump() const;
|
||||
void setLastEdited(quint64 usecTime) { _lastEdited = usecTime; }
|
||||
void setLastEdited(quint64 usecTime);
|
||||
|
||||
DEFINE_PROPERTY(PROP_VISIBLE, Visible, visible, bool);
|
||||
DEFINE_PROPERTY_REF_WITH_SETTER(PROP_POSITION, Position, position, glm::vec3);
|
||||
|
@ -180,7 +178,7 @@ public:
|
|||
|
||||
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
||||
quint64 getCreated() const { return _created; }
|
||||
void setCreated(quint64 usecTime) { _created = usecTime; }
|
||||
void setCreated(quint64 usecTime);
|
||||
bool hasCreatedTime() const { return (_created != UNKNOWN_CREATED_TIME); }
|
||||
|
||||
bool containsBoundsProperties() const { return (_positionChanged || _dimensionsChanged); }
|
||||
|
|
|
@ -137,13 +137,13 @@
|
|||
}
|
||||
|
||||
#define SET_ENTITY_PROPERTY_FROM_PROPERTIES(P,M) \
|
||||
if (properties._##P##Changed || forceCopy) { \
|
||||
if (properties._##P##Changed) { \
|
||||
M(properties._##P); \
|
||||
somethingChanged = true; \
|
||||
}
|
||||
|
||||
#define SET_ENTITY_PROPERTY_FROM_PROPERTIES_GETTER(C,G,S) \
|
||||
if (properties.C() || forceCopy) { \
|
||||
if (properties.C()) { \
|
||||
S(properties.G()); \
|
||||
somethingChanged = true; \
|
||||
}
|
||||
|
|
|
@ -164,9 +164,17 @@ EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItem
|
|||
|
||||
// NOTE: This method is used in the client and the server tree. In the client, it's possible to create EntityItems
|
||||
// that do not yet have known IDs. In the server tree however we don't want to have entities without known IDs.
|
||||
if (getIsServer() && !entityID.isKnownID) {
|
||||
qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... (getIsSever() && !entityID.isKnownID)";
|
||||
return result;
|
||||
bool recordCreationTime = false;
|
||||
if (!entityID.isKnownID) {
|
||||
if (getIsServer()) {
|
||||
qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... (getIsSever() && !entityID.isKnownID)";
|
||||
return result;
|
||||
}
|
||||
if (properties.getCreated() == UNKNOWN_CREATED_TIME) {
|
||||
// the entity's creation time was not specified in properties, which means this is a NEW entity
|
||||
// and we must record its creation time
|
||||
recordCreationTime = true;
|
||||
}
|
||||
}
|
||||
|
||||
// You should not call this on existing entities that are already part of the tree! Call updateEntity()
|
||||
|
@ -182,6 +190,9 @@ EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItem
|
|||
result = EntityTypes::constructEntityItem(type, entityID, properties);
|
||||
|
||||
if (result) {
|
||||
if (recordCreationTime) {
|
||||
result->recordCreationTime();
|
||||
}
|
||||
// Recurse the tree and store the entity in the correct tree element
|
||||
AddEntityOperator theOperator(this, result);
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
|
|
|
@ -71,22 +71,13 @@ bool EntityTypes::registerEntityType(EntityType entityType, const char* name, En
|
|||
|
||||
EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
|
||||
const EntityItemProperties& properties) {
|
||||
|
||||
EntityItem* newEntityItem = NULL;
|
||||
EntityTypeFactory factory = NULL;
|
||||
if (entityType >= 0 && entityType <= LAST) {
|
||||
factory = _factories[entityType];
|
||||
}
|
||||
if (factory) {
|
||||
// NOTE: if someone attempts to create an entity with properties that do not include a proper "created" time
|
||||
// then set the created time to now
|
||||
if (!properties.hasCreatedTime()) {
|
||||
EntityItemProperties mutableProperties = properties;
|
||||
mutableProperties.setCreated(usecTimestampNow());
|
||||
newEntityItem = factory(entityID, mutableProperties);
|
||||
} else {
|
||||
newEntityItem = factory(entityID, properties);
|
||||
}
|
||||
newEntityItem = factory(entityID, properties);
|
||||
}
|
||||
return newEntityItem;
|
||||
}
|
||||
|
@ -129,8 +120,6 @@ EntityItem* EntityTypes::constructEntityItem(const unsigned char* data, int byte
|
|||
|
||||
EntityItemID tempEntityID(actualID);
|
||||
EntityItemProperties tempProperties;
|
||||
tempProperties.setCreated(usecTimestampNow()); // this is temporary...
|
||||
|
||||
return constructEntityItem(entityType, tempEntityID, tempProperties);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID, const EntityI
|
|||
_exponent = 0.0f;
|
||||
_cutoff = PI;
|
||||
|
||||
setProperties(properties, true);
|
||||
setProperties(properties);
|
||||
|
||||
// a light is not collide-able so we make it's shape be a tiny sphere at origin
|
||||
_emptyShape.setTranslation(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
|
@ -71,8 +71,8 @@ EntityItemProperties LightEntityItem::getProperties() const {
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool LightEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
bool somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
|
||||
bool LightEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isSpotlight, setIsSpotlight);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(diffuseColor, setDiffuseColor);
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI
|
|||
EntityItem(entityItemID, properties)
|
||||
{
|
||||
_type = EntityTypes::Model;
|
||||
setProperties(properties, true);
|
||||
setProperties(properties);
|
||||
_lastAnimated = usecTimestampNow();
|
||||
_jointMappingCompleted = false;
|
||||
_color[0] = _color[1] = _color[2] = 0;
|
||||
|
@ -55,9 +55,9 @@ EntityItemProperties ModelEntityItem::getProperties() const {
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool ModelEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
bool ModelEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
|
||||
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(modelURL, setModelURL);
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
|
|
@ -31,7 +31,7 @@ SphereEntityItem::SphereEntityItem(const EntityItemID& entityItemID, const Entit
|
|||
EntityItem(entityItemID, properties)
|
||||
{
|
||||
_type = EntityTypes::Sphere;
|
||||
setProperties(properties, true);
|
||||
setProperties(properties);
|
||||
}
|
||||
|
||||
EntityItemProperties SphereEntityItem::getProperties() const {
|
||||
|
@ -40,8 +40,8 @@ EntityItemProperties SphereEntityItem::getProperties() const {
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool SphereEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
bool somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
|
||||
bool SphereEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityIte
|
|||
{
|
||||
_type = EntityTypes::Text;
|
||||
_created = properties.getCreated();
|
||||
setProperties(properties, true);
|
||||
setProperties(properties);
|
||||
}
|
||||
|
||||
void TextEntityItem::setDimensions(const glm::vec3& value) {
|
||||
|
@ -57,9 +57,9 @@ EntityItemProperties TextEntityItem::getProperties() const {
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool TextEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
bool TextEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
|
||||
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(text, setText);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineHeight, setLineHeight);
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
|
|
@ -11,5 +11,5 @@ find_package(ZLIB REQUIRED)
|
|||
include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
||||
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -19,7 +19,7 @@ elseif (WIN32)
|
|||
# we're using static GLEW, so define GLEW_STATIC
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
|
||||
target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" opengl32.lib)
|
||||
target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} opengl32.lib)
|
||||
|
||||
# need to bubble up the GLEW_INCLUDE_DIRS
|
||||
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${GLEW_INCLUDE_DIRS}")
|
||||
|
@ -44,5 +44,5 @@ else ()
|
|||
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${OPENGL_INCLUDE_DIR}")
|
||||
endif (APPLE)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -107,6 +107,19 @@ void Batch::setInputFormat(const Stream::FormatPointer& format) {
|
|||
_params.push_back(_streamFormats.cache(format));
|
||||
}
|
||||
|
||||
void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
ADD_COMMAND(setInputBuffer);
|
||||
|
||||
_params.push_back(stride);
|
||||
_params.push_back(offset);
|
||||
_params.push_back(_buffers.cache(buffer));
|
||||
_params.push_back(channel);
|
||||
}
|
||||
|
||||
void Batch::setInputBuffer(Slot channel, const BufferView& view) {
|
||||
setInputBuffer(channel, view._buffer, view._offset, Offset(view._stride));
|
||||
}
|
||||
|
||||
void Batch::setInputStream(Slot startChannel, const BufferStream& stream) {
|
||||
if (stream.getNumBuffers()) {
|
||||
const Buffers& buffers = stream.getBuffers();
|
||||
|
@ -118,15 +131,6 @@ void Batch::setInputStream(Slot startChannel, const BufferStream& stream) {
|
|||
}
|
||||
}
|
||||
|
||||
void Batch::setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
ADD_COMMAND(setInputBuffer);
|
||||
|
||||
_params.push_back(stride);
|
||||
_params.push_back(offset);
|
||||
_params.push_back(_buffers.cache(buffer));
|
||||
_params.push_back(channel);
|
||||
}
|
||||
|
||||
void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset) {
|
||||
ADD_COMMAND(setIndexBuffer);
|
||||
|
||||
|
@ -153,3 +157,17 @@ void Batch::setProjectionTransform(const Transform& proj) {
|
|||
_params.push_back(_transforms.cache(proj));
|
||||
}
|
||||
|
||||
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
||||
ADD_COMMAND(setUniformBuffer);
|
||||
|
||||
_params.push_back(size);
|
||||
_params.push_back(offset);
|
||||
_params.push_back(_buffers.cache(buffer));
|
||||
_params.push_back(slot);
|
||||
}
|
||||
|
||||
void Batch::setUniformBuffer(uint32 slot, const BufferView& view) {
|
||||
setUniformBuffer(slot, view._buffer, view._offset, view._size);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -72,8 +72,9 @@ public:
|
|||
// IndexBuffer
|
||||
void setInputFormat(const Stream::FormatPointer& format);
|
||||
|
||||
void setInputStream(Slot startChannel, const BufferStream& stream); // not a command, just unroll into a loop of setInputBuffer
|
||||
void setInputBuffer(Slot channel, const BufferPointer& buffer, Offset offset, Offset stride);
|
||||
void setInputBuffer(Slot channel, const BufferView& buffer); // not a command, just a shortcut from a BufferView
|
||||
void setInputStream(Slot startChannel, const BufferStream& stream); // not a command, just unroll into a loop of setInputBuffer
|
||||
|
||||
void setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset);
|
||||
|
||||
|
@ -87,6 +88,9 @@ public:
|
|||
void setViewTransform(const Transform& view);
|
||||
void setProjectionTransform(const Transform& proj);
|
||||
|
||||
// Shader Stage
|
||||
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
|
||||
void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
|
@ -117,6 +121,7 @@ public:
|
|||
void _glUseProgram(GLuint program);
|
||||
void _glUniform1f(GLint location, GLfloat v0);
|
||||
void _glUniform2f(GLint location, GLfloat v0, GLfloat v1);
|
||||
void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value);
|
||||
void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
|
||||
void _glMatrixMode(GLenum mode);
|
||||
|
@ -161,6 +166,8 @@ public:
|
|||
COMMAND_setViewTransform,
|
||||
COMMAND_setProjectionTransform,
|
||||
|
||||
COMMAND_setUniformBuffer,
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -187,6 +194,7 @@ public:
|
|||
COMMAND_glUseProgram,
|
||||
COMMAND_glUniform1f,
|
||||
COMMAND_glUniform2f,
|
||||
COMMAND_glUniform4fv,
|
||||
COMMAND_glUniformMatrix4fv,
|
||||
|
||||
COMMAND_glMatrixMode,
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#define hifi_gpu_Context_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
#include "Resource.h"
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#define hifi_gpu_Format_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
|
||||
namespace gpu {
|
||||
|
||||
|
@ -94,7 +92,8 @@ static const int DIMENSION_COUNT[NUM_DIMENSIONS] = {
|
|||
// Semantic of an Element
|
||||
// Provide information on how to use the element
|
||||
enum Semantic {
|
||||
RGB = 0,
|
||||
RAW = 0, // used as RAW memory
|
||||
RGB,
|
||||
RGBA,
|
||||
XYZ,
|
||||
XYZW,
|
||||
|
@ -104,6 +103,8 @@ enum Semantic {
|
|||
DIR_XYZ,
|
||||
UV,
|
||||
R8,
|
||||
INDEX, //used by index buffer of a mesh
|
||||
PART, // used by part buffer of a mesh
|
||||
|
||||
NUM_SEMANTICS,
|
||||
};
|
||||
|
@ -119,7 +120,7 @@ public:
|
|||
_type(type)
|
||||
{}
|
||||
Element() :
|
||||
_semantic(R8),
|
||||
_semantic(RAW),
|
||||
_dimension(SCALAR),
|
||||
_type(INT8)
|
||||
{}
|
||||
|
|
|
@ -31,6 +31,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_setViewTransform),
|
||||
(&::gpu::GLBackend::do_setProjectionTransform),
|
||||
|
||||
(&::gpu::GLBackend::do_setUniformBuffer),
|
||||
|
||||
(&::gpu::GLBackend::do_glEnable),
|
||||
(&::gpu::GLBackend::do_glDisable),
|
||||
|
||||
|
@ -54,6 +56,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_glUseProgram),
|
||||
(&::gpu::GLBackend::do_glUniform1f),
|
||||
(&::gpu::GLBackend::do_glUniform2f),
|
||||
(&::gpu::GLBackend::do_glUniform4fv),
|
||||
(&::gpu::GLBackend::do_glUniformMatrix4fv),
|
||||
|
||||
(&::gpu::GLBackend::do_glMatrixMode),
|
||||
|
@ -483,6 +486,25 @@ void GLBackend::updateTransform() {
|
|||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
||||
GLuint slot = batch._params[paramOffset + 3]._uint;
|
||||
BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint);
|
||||
GLintptr rangeStart = batch._params[paramOffset + 1]._uint;
|
||||
GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint;
|
||||
#if defined(Q_OS_MAC)
|
||||
GLfloat* data = (GLfloat*) (uniformBuffer->getData() + rangeStart);
|
||||
glUniform4fv(slot, rangeSize / sizeof(GLfloat[4]), data);
|
||||
#else
|
||||
GLuint bo = getBufferID(*uniformBuffer);
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize);
|
||||
|
||||
// glUniformBufferEXT(_shader._program, slot, bo);
|
||||
|
||||
//glBindBufferBase(GL_UNIFORM_BUFFER, slot, bo);
|
||||
#endif
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -672,7 +694,10 @@ void Batch::_glUseProgram(GLuint program) {
|
|||
DO_IT_NOW(_glUseProgram, 1);
|
||||
}
|
||||
void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) {
|
||||
glUseProgram(batch._params[paramOffset]._uint);
|
||||
|
||||
_shader._program = batch._params[paramOffset]._uint;
|
||||
glUseProgram(_shader._program);
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
|
@ -708,6 +733,25 @@ void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) {
|
|||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
|
||||
ADD_COMMAND_GL(glUniform4fv);
|
||||
|
||||
const int VEC4_SIZE = 4 * sizeof(float);
|
||||
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
||||
_params.push_back(count);
|
||||
_params.push_back(location);
|
||||
|
||||
DO_IT_NOW(_glUniform4fv, 3);
|
||||
}
|
||||
void GLBackend::do_glUniform4fv(Batch& batch, uint32 paramOffset) {
|
||||
glUniform4fv(
|
||||
batch._params[paramOffset + 2]._int,
|
||||
batch._params[paramOffset + 1]._uint,
|
||||
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
ADD_COMMAND_GL(glUniformMatrix4fv);
|
||||
|
||||
|
|
|
@ -122,6 +122,19 @@ protected:
|
|||
_lastMode(GL_TEXTURE) {}
|
||||
} _transform;
|
||||
|
||||
// Shader Stage
|
||||
void do_setUniformBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void updateShader();
|
||||
struct ShaderStageState {
|
||||
|
||||
GLuint _program;
|
||||
|
||||
ShaderStageState() :
|
||||
_program(0) {}
|
||||
} _shader;
|
||||
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
// code, we need to be able to record and batch these calls. THe long
|
||||
// term strategy is to get rid of any GL calls in favor of the HIFI GPU API
|
||||
|
@ -148,6 +161,7 @@ protected:
|
|||
void do_glUseProgram(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform1f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform2f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform4fv(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void do_glMatrixMode(Batch& batch, uint32 paramOffset);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
//
|
||||
// GPUConfig.h
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/17/14.
|
||||
// Copyright 2014 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 gpu__GLUTConfig__
|
||||
#define gpu__GLUTConfig__
|
||||
|
||||
// TODO: remove these once we migrate away from GLUT calls
|
||||
#if defined(__APPLE__)
|
||||
#include <GLUT/glut.h>
|
||||
#elif defined(WIN32)
|
||||
#include <GL/glut.h>
|
||||
#else
|
||||
#include <GL/glut.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif // gpu__GLUTConfig__
|
|
@ -67,6 +67,26 @@ Resource::Sysmem::Sysmem(Size size, const Byte* bytes) :
|
|||
}
|
||||
}
|
||||
|
||||
Resource::Sysmem::Sysmem(const Sysmem& sysmem) :
|
||||
_stamp(0),
|
||||
_size(0),
|
||||
_data(NULL)
|
||||
{
|
||||
if (sysmem.getSize() > 0) {
|
||||
_size = allocateMemory(&_data, sysmem.getSize());
|
||||
if (_size >= sysmem.getSize()) {
|
||||
if (sysmem.readData()) {
|
||||
memcpy(_data, sysmem.readData(), sysmem.getSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Resource::Sysmem& Resource::Sysmem::operator=(const Sysmem& sysmem) {
|
||||
setData(sysmem.getSize(), sysmem.readData());
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Resource::Sysmem::~Sysmem() {
|
||||
deallocateMemory( _data, _size );
|
||||
_data = NULL;
|
||||
|
@ -152,9 +172,25 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) {
|
|||
|
||||
Buffer::Buffer() :
|
||||
Resource(),
|
||||
_sysmem(NULL),
|
||||
_sysmem(new Sysmem()),
|
||||
_gpuObject(NULL) {
|
||||
_sysmem = new Sysmem();
|
||||
}
|
||||
|
||||
Buffer::Buffer(Size size, const Byte* bytes) :
|
||||
Resource(),
|
||||
_sysmem(new Sysmem(size, bytes)),
|
||||
_gpuObject(NULL) {
|
||||
}
|
||||
|
||||
Buffer::Buffer(const Buffer& buf) :
|
||||
Resource(),
|
||||
_sysmem(new Sysmem(buf.getSysmem())),
|
||||
_gpuObject(NULL) {
|
||||
}
|
||||
|
||||
Buffer& Buffer::operator=(const Buffer& buf) {
|
||||
(*_sysmem) = buf.getSysmem();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
|
|
|
@ -12,13 +12,15 @@
|
|||
#define hifi_gpu_Resource_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
#include "Format.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QSharedPointer>
|
||||
#ifdef _DEBUG
|
||||
#include <QDebug>
|
||||
#endif
|
||||
|
||||
namespace gpu {
|
||||
|
||||
|
@ -29,7 +31,7 @@ typedef int Stamp;
|
|||
class Resource {
|
||||
public:
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned int Size;
|
||||
typedef unsigned int Size;
|
||||
|
||||
static const Size NOT_ALLOCATED = -1;
|
||||
|
||||
|
@ -47,6 +49,8 @@ protected:
|
|||
|
||||
Sysmem();
|
||||
Sysmem(Size size, const Byte* bytes);
|
||||
Sysmem(const Sysmem& sysmem); // deep copy of the sysmem buffer
|
||||
Sysmem& operator=(const Sysmem& sysmem); // deep copy of the sysmem buffer
|
||||
~Sysmem();
|
||||
|
||||
Size getSize() const { return _size; }
|
||||
|
@ -90,9 +94,6 @@ protected:
|
|||
static void deallocateMemory(Byte* memDeallocated, Size size);
|
||||
|
||||
private:
|
||||
Sysmem(const Sysmem& sysmem) {}
|
||||
Sysmem &operator=(const Sysmem& other) {return *this;}
|
||||
|
||||
Stamp _stamp;
|
||||
Size _size;
|
||||
Byte* _data;
|
||||
|
@ -104,12 +105,15 @@ class Buffer : public Resource {
|
|||
public:
|
||||
|
||||
Buffer();
|
||||
Buffer(const Buffer& buf);
|
||||
Buffer(Size size, const Byte* bytes);
|
||||
Buffer(const Buffer& buf); // deep copy of the sysmem buffer
|
||||
Buffer& operator=(const Buffer& buf); // deep copy of the sysmem buffer
|
||||
~Buffer();
|
||||
|
||||
// The size in bytes of data stored in the buffer
|
||||
Size getSize() const { return getSysmem().getSize(); }
|
||||
const Byte* getData() const { return getSysmem().readData(); }
|
||||
Byte* editData() { return editSysmem().editData(); }
|
||||
|
||||
// Resize the buffer
|
||||
// Keep previous data [0 to min(pSize, mSize)]
|
||||
|
@ -130,7 +134,7 @@ public:
|
|||
|
||||
// Access the sysmem object.
|
||||
const Sysmem& getSysmem() const { assert(_sysmem); return (*_sysmem); }
|
||||
|
||||
Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -138,8 +142,6 @@ protected:
|
|||
|
||||
mutable GPUObject* _gpuObject;
|
||||
|
||||
Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); }
|
||||
|
||||
// This shouldn't be used by anything else than the Backend class with the proper casting.
|
||||
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
|
||||
GPUObject* getGPUObject() const { return _gpuObject; }
|
||||
|
@ -149,6 +151,281 @@ protected:
|
|||
|
||||
typedef QSharedPointer<Buffer> BufferPointer;
|
||||
typedef std::vector< BufferPointer > Buffers;
|
||||
|
||||
|
||||
class BufferView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
typedef int Index;
|
||||
|
||||
BufferPointer _buffer;
|
||||
Size _offset;
|
||||
Size _size;
|
||||
Element _element;
|
||||
uint16 _stride;
|
||||
|
||||
BufferView() :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(gpu::SCALAR, gpu::UINT8, gpu::RAW),
|
||||
_stride(1)
|
||||
{};
|
||||
|
||||
BufferView(const Element& element) :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
|
||||
// create the BufferView and own the Buffer
|
||||
BufferView(Buffer* newBuffer, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) :
|
||||
_buffer(newBuffer),
|
||||
_offset(0),
|
||||
_size(newBuffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
BufferView(const BufferPointer& buffer, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) :
|
||||
_buffer(buffer),
|
||||
_offset(0),
|
||||
_size(buffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
BufferView(const BufferPointer& buffer, Size offset, Size size, const Element& element = Element(gpu::SCALAR, gpu::UINT8, gpu::RAW)) :
|
||||
_buffer(buffer),
|
||||
_offset(offset),
|
||||
_size(size),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
~BufferView() {}
|
||||
BufferView(const BufferView& view) = default;
|
||||
BufferView& operator=(const BufferView& view) = default;
|
||||
|
||||
Size getNumElements() const { return _size / _element.getSize(); }
|
||||
|
||||
//Template iterator with random access on the buffer sysmem
|
||||
template<typename T>
|
||||
class Iterator : public std::iterator<std::random_access_iterator_tag,
|
||||
T,
|
||||
Index,
|
||||
T*,
|
||||
T&>
|
||||
{
|
||||
public:
|
||||
|
||||
Iterator(T* ptr = NULL) { _ptr = ptr; }
|
||||
Iterator(const Iterator<T>& iterator) = default;
|
||||
~Iterator() {}
|
||||
|
||||
Iterator<T>& operator=(const Iterator<T>& iterator) = default;
|
||||
Iterator<T>& operator=(T* ptr) {
|
||||
_ptr = ptr;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
if(_ptr)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const Iterator<T>& iterator) const { return (_ptr == iterator.getConstPtr()); }
|
||||
bool operator!=(const Iterator<T>& iterator) const { return (_ptr != iterator.getConstPtr()); }
|
||||
|
||||
Iterator<T>& operator+=(const Index& movement) {
|
||||
_ptr += movement;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T>& operator-=(const Index& movement) {
|
||||
_ptr -= movement;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T>& operator++() {
|
||||
++_ptr;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T>& operator--() {
|
||||
--_ptr;
|
||||
return (*this);
|
||||
}
|
||||
Iterator<T> operator++(Index) {
|
||||
auto temp(*this);
|
||||
++_ptr;
|
||||
return temp;
|
||||
}
|
||||
Iterator<T> operator--(Index) {
|
||||
auto temp(*this);
|
||||
--_ptr;
|
||||
return temp;
|
||||
}
|
||||
Iterator<T> operator+(const Index& movement) {
|
||||
auto oldPtr = _ptr;
|
||||
_ptr += movement;
|
||||
auto temp(*this);
|
||||
_ptr = oldPtr;
|
||||
return temp;
|
||||
}
|
||||
Iterator<T> operator-(const Index& movement) {
|
||||
auto oldPtr = _ptr;
|
||||
_ptr -= movement;
|
||||
auto temp(*this);
|
||||
_ptr = oldPtr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
Index operator-(const Iterator<T>& iterator) { return (iterator.getPtr() - this->getPtr())/sizeof(T); }
|
||||
|
||||
T& operator*(){return *_ptr;}
|
||||
const T& operator*()const{return *_ptr;}
|
||||
T* operator->(){return _ptr;}
|
||||
|
||||
T* getPtr()const{return _ptr;}
|
||||
const T* getConstPtr()const{return _ptr;}
|
||||
|
||||
protected:
|
||||
|
||||
T* _ptr;
|
||||
};
|
||||
|
||||
template <typename T> Iterator<T> begin() { return Iterator<T>(&edit<T>(0)); }
|
||||
template <typename T> Iterator<T> end() { return Iterator<T>(&edit<T>(getNum<T>())); }
|
||||
template <typename T> Iterator<const T> cbegin() const { return Iterator<const T>(&get<T>(0)); }
|
||||
template <typename T> Iterator<const T> cend() const { return Iterator<const T>(&get<T>(getNum<T>())); }
|
||||
|
||||
// the number of elements of the specified type fitting in the view size
|
||||
template <typename T> Index getNum() const {
|
||||
return Index(_size / sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T> const T& get() const {
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - _offset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - _offset);
|
||||
}
|
||||
if (sizeof(T) > _size) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size;
|
||||
}
|
||||
#endif
|
||||
const T* t = (reinterpret_cast<const T*> (_buffer->getData() + _offset));
|
||||
return *(t);
|
||||
}
|
||||
|
||||
template <typename T> T& edit() {
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - _offset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - _offset);
|
||||
}
|
||||
if (sizeof(T) > _size) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size;
|
||||
}
|
||||
#endif
|
||||
T* t = (reinterpret_cast<T*> (_buffer->editData() + _offset));
|
||||
return *(t);
|
||||
}
|
||||
|
||||
template <typename T> const T& get(const Index index) const {
|
||||
Resource::Size elementOffset = index * sizeof(T) + _offset;
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - elementOffset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, index = " << index << ", element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - elementOffset);
|
||||
}
|
||||
if (index > getNum<T>()) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
|
||||
}
|
||||
#endif
|
||||
return *(reinterpret_cast<const T*> (_buffer->getData() + elementOffset));
|
||||
}
|
||||
|
||||
template <typename T> T& edit(const Index index) const {
|
||||
Resource::Size elementOffset = index * sizeof(T) + _offset;
|
||||
#if _DEBUG
|
||||
if (_buffer.isNull()) {
|
||||
qDebug() << "Accessing null gpu::buffer!";
|
||||
}
|
||||
if (sizeof(T) > (_buffer->getSize() - elementOffset)) {
|
||||
qDebug() << "Accessing buffer in non allocated memory, index = " << index << ", element size = " << sizeof(T) << " available space in buffer at offset is = " << (_buffer->getSize() - elementOffset);
|
||||
}
|
||||
if (index > getNum<T>()) {
|
||||
qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum<T>();
|
||||
}
|
||||
#endif
|
||||
return *(reinterpret_cast<T*> (_buffer->editData() + elementOffset));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// TODO: For now TextureView works with Buffer as a place holder for the Texture.
|
||||
// The overall logic should be about the same except that the Texture will be a real GL Texture under the hood
|
||||
class TextureView {
|
||||
public:
|
||||
typedef Resource::Size Size;
|
||||
typedef int Index;
|
||||
|
||||
BufferPointer _buffer;
|
||||
Size _offset;
|
||||
Size _size;
|
||||
Element _element;
|
||||
uint16 _stride;
|
||||
|
||||
TextureView() :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(gpu::VEC3, gpu::UINT8, gpu::RGB),
|
||||
_stride(1)
|
||||
{};
|
||||
|
||||
TextureView(const Element& element) :
|
||||
_buffer(NULL),
|
||||
_offset(0),
|
||||
_size(0),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
|
||||
// create the BufferView and own the Buffer
|
||||
TextureView(Buffer* newBuffer, const Element& element) :
|
||||
_buffer(newBuffer),
|
||||
_offset(0),
|
||||
_size(newBuffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
TextureView(const BufferPointer& buffer, const Element& element) :
|
||||
_buffer(buffer),
|
||||
_offset(0),
|
||||
_size(buffer->getSize()),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
TextureView(const BufferPointer& buffer, Size offset, Size size, const Element& element) :
|
||||
_buffer(buffer),
|
||||
_offset(offset),
|
||||
_size(size),
|
||||
_element(element),
|
||||
_stride(uint16(element.getSize()))
|
||||
{};
|
||||
~TextureView() {}
|
||||
TextureView(const TextureView& view) = default;
|
||||
TextureView& operator=(const TextureView& view) = default;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ void Stream::Format::evaluateCache() {
|
|||
_elementTotalSize = 0;
|
||||
for(AttributeMap::iterator it = _attributes.begin(); it != _attributes.end(); it++) {
|
||||
Attribute& attrib = (*it).second;
|
||||
Channel& channel = _channels[attrib._channel];
|
||||
ChannelInfo& channel = _channels[attrib._channel];
|
||||
channel._slots.push_back(attrib._slot);
|
||||
channel._stride = std::max(channel._stride, attrib.getSize() + attrib._offset);
|
||||
channel._netSize += attrib.getSize();
|
||||
|
@ -41,7 +41,7 @@ BufferStream::BufferStream() :
|
|||
BufferStream::~BufferStream() {
|
||||
}
|
||||
|
||||
void BufferStream::addBuffer(BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
void BufferStream::addBuffer(const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||
_buffers.push_back(buffer);
|
||||
_offsets.push_back(offset);
|
||||
_strides.push_back(stride);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#define hifi_gpu_Stream_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "GPUConfig.h"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Format.h"
|
||||
|
@ -83,16 +82,16 @@ public:
|
|||
public:
|
||||
typedef std::map< Slot, Attribute > AttributeMap;
|
||||
|
||||
class Channel {
|
||||
class ChannelInfo {
|
||||
public:
|
||||
std::vector< Slot > _slots;
|
||||
std::vector< Offset > _offsets;
|
||||
Offset _stride;
|
||||
uint32 _netSize;
|
||||
|
||||
Channel() : _stride(0), _netSize(0) {}
|
||||
ChannelInfo() : _stride(0), _netSize(0) {}
|
||||
};
|
||||
typedef std::map< Slot, Channel > ChannelMap;
|
||||
typedef std::map< Slot, ChannelInfo > ChannelMap;
|
||||
|
||||
Format() :
|
||||
_attributes(),
|
||||
|
@ -104,6 +103,7 @@ public:
|
|||
|
||||
uint8 getNumChannels() const { return _channels.size(); }
|
||||
const ChannelMap& getChannels() const { return _channels; }
|
||||
const Offset getChannelStride(Slot channel) const { return _channels.at(channel)._stride; }
|
||||
|
||||
uint32 getElementTotalSize() const { return _elementTotalSize; }
|
||||
|
||||
|
@ -131,7 +131,7 @@ public:
|
|||
BufferStream();
|
||||
~BufferStream();
|
||||
|
||||
void addBuffer(BufferPointer& buffer, Offset offset, Offset stride);
|
||||
void addBuffer(const BufferPointer& buffer, Offset offset, Offset stride);
|
||||
|
||||
const Buffers& getBuffers() const { return _buffers; }
|
||||
const Offsets& getOffsets() const { return _offsets; }
|
||||
|
|
|
@ -10,5 +10,5 @@ link_hifi_libraries(shared networking)
|
|||
|
||||
include_glm()
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -28,5 +28,5 @@ target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES} ${TBB_LIBRARIES})
|
|||
# append libcuckoo includes to our list of includes to bubble
|
||||
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${TBB_INCLUDE_DIRS}")
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -107,7 +107,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl) {
|
|||
if (!handleUsername(lookupUrl.authority())) {
|
||||
// we're assuming this is either a network address or global place name
|
||||
// check if it is a network address first
|
||||
if (!handleNetworkAddress(lookupUrl.host())) {
|
||||
if (!handleNetworkAddress(lookupUrl.host()
|
||||
+ (lookupUrl.port() == -1 ? "" : ":" + QString::number(lookupUrl.port())))) {
|
||||
// wasn't an address - lookup the place name
|
||||
attemptPlaceNameLookup(lookupUrl.host());
|
||||
}
|
||||
|
@ -172,7 +173,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& addressMap) {
|
|||
if (domainObject.contains(DOMAIN_NETWORK_ADDRESS_KEY)) {
|
||||
QString domainHostname = domainObject[DOMAIN_NETWORK_ADDRESS_KEY].toString();
|
||||
|
||||
emit possibleDomainChangeRequiredToHostname(domainHostname);
|
||||
emit possibleDomainChangeRequired(domainHostname, DEFAULT_DOMAIN_SERVER_PORT);
|
||||
} else {
|
||||
QString iceServerAddress = domainObject[DOMAIN_ICE_SERVER_ADDRESS_KEY].toString();
|
||||
|
||||
|
@ -240,30 +241,40 @@ void AddressManager::attemptPlaceNameLookup(const QString& lookupString) {
|
|||
}
|
||||
|
||||
bool AddressManager::handleNetworkAddress(const QString& lookupString) {
|
||||
const QString IP_ADDRESS_REGEX_STRING = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}"
|
||||
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:\\d{1,5})?$";
|
||||
const QString IP_ADDRESS_REGEX_STRING = "^((?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}"
|
||||
"(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(?::(\\d{1,5}))?$";
|
||||
|
||||
const QString HOSTNAME_REGEX_STRING = "^((?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9])"
|
||||
"(?:\\.(?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9]))+|localhost)(:{1}\\d{1,5})?$";
|
||||
|
||||
QRegExp hostnameRegex(HOSTNAME_REGEX_STRING, Qt::CaseInsensitive);
|
||||
|
||||
if (hostnameRegex.indexIn(lookupString) != -1) {
|
||||
QString domainHostname = hostnameRegex.cap(0);
|
||||
|
||||
emit lookupResultsFinished();
|
||||
setDomainHostnameAndName(domainHostname);
|
||||
|
||||
return true;
|
||||
}
|
||||
"(?:\\.(?:[A-Z0-9]|[A-Z0-9][A-Z0-9\\-]{0,61}[A-Z0-9]))+|localhost)(?::(\\d{1,5}))?$";
|
||||
|
||||
QRegExp ipAddressRegex(IP_ADDRESS_REGEX_STRING);
|
||||
|
||||
if (ipAddressRegex.indexIn(lookupString) != -1) {
|
||||
QString domainIPString = ipAddressRegex.cap(0);
|
||||
QString domainIPString = ipAddressRegex.cap(1);
|
||||
|
||||
qint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
if (!ipAddressRegex.cap(2).isEmpty()) {
|
||||
domainPort = (qint16) ipAddressRegex.cap(2).toInt();
|
||||
}
|
||||
|
||||
emit lookupResultsFinished();
|
||||
setDomainHostnameAndName(domainIPString);
|
||||
setDomainInfo(domainIPString, domainPort);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QRegExp hostnameRegex(HOSTNAME_REGEX_STRING, Qt::CaseInsensitive);
|
||||
|
||||
if (hostnameRegex.indexIn(lookupString) != -1) {
|
||||
QString domainHostname = hostnameRegex.cap(1);
|
||||
|
||||
qint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
if (!hostnameRegex.cap(2).isEmpty()) {
|
||||
domainPort = (qint16) hostnameRegex.cap(2).toInt();
|
||||
}
|
||||
|
||||
emit lookupResultsFinished();
|
||||
setDomainInfo(domainHostname, domainPort);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -339,9 +350,9 @@ bool AddressManager::handleUsername(const QString& lookupString) {
|
|||
}
|
||||
|
||||
|
||||
void AddressManager::setDomainHostnameAndName(const QString& hostname, const QString& domainName) {
|
||||
void AddressManager::setDomainInfo(const QString& hostname, quint16 port, const QString& domainName) {
|
||||
_currentDomain = domainName.isEmpty() ? hostname : domainName;
|
||||
emit possibleDomainChangeRequiredToHostname(hostname);
|
||||
emit possibleDomainChangeRequired(hostname, port);
|
||||
}
|
||||
|
||||
void AddressManager::goToUser(const QString& username) {
|
||||
|
|
|
@ -59,7 +59,7 @@ signals:
|
|||
void lookupResultsFinished();
|
||||
void lookupResultIsOffline();
|
||||
void lookupResultIsNotFound();
|
||||
void possibleDomainChangeRequiredToHostname(const QString& newHostname);
|
||||
void possibleDomainChangeRequired(const QString& newHostname, quint16 newPort);
|
||||
void possibleDomainChangeRequiredViaICEForID(const QString& iceServerHostname, const QUuid& domainID);
|
||||
void locationChangeRequired(const glm::vec3& newPosition,
|
||||
bool hasOrientationChange, const glm::quat& newOrientation,
|
||||
|
@ -70,7 +70,7 @@ private slots:
|
|||
private:
|
||||
AddressManager();
|
||||
|
||||
void setDomainHostnameAndName(const QString& hostname, const QString& domainName = QString());
|
||||
void setDomainInfo(const QString& hostname, quint16 port, const QString& domainName = QString());
|
||||
|
||||
const JSONCallbackParameters& apiCallbackParameters();
|
||||
|
||||
|
|
|
@ -97,46 +97,32 @@ void DomainHandler::setUUID(const QUuid& uuid) {
|
|||
}
|
||||
}
|
||||
|
||||
QString DomainHandler::hostnameWithoutPort(const QString& hostname) {
|
||||
int colonIndex = hostname.indexOf(':');
|
||||
return colonIndex > 0 ? hostname.left(colonIndex) : hostname;
|
||||
}
|
||||
|
||||
bool DomainHandler::isCurrentHostname(const QString& hostname) {
|
||||
return hostnameWithoutPort(hostname) == _hostname;
|
||||
}
|
||||
|
||||
void DomainHandler::setHostname(const QString& hostname) {
|
||||
void DomainHandler::setHostnameAndPort(const QString& hostname, quint16 port) {
|
||||
|
||||
if (hostname != _hostname) {
|
||||
if (hostname != _hostname || _sockAddr.getPort() != port) {
|
||||
// re-set the domain info so that auth information is reloaded
|
||||
hardReset();
|
||||
|
||||
int colonIndex = hostname.indexOf(':');
|
||||
|
||||
if (colonIndex > 0) {
|
||||
// the user has included a custom DS port with the hostname
|
||||
|
||||
// the new hostname is everything up to the colon
|
||||
_hostname = hostname.left(colonIndex);
|
||||
|
||||
// grab the port by reading the string after the colon
|
||||
_sockAddr.setPort(atoi(hostname.mid(colonIndex + 1, hostname.size()).toLocal8Bit().constData()));
|
||||
|
||||
qDebug() << "Updated hostname to" << _hostname << "and port to" << _sockAddr.getPort();
|
||||
|
||||
} else {
|
||||
// no port included with the hostname, simply set the member variable and reset the domain server port to default
|
||||
if (hostname != _hostname) {
|
||||
// set the new hostname
|
||||
_hostname = hostname;
|
||||
_sockAddr.setPort(DEFAULT_DOMAIN_SERVER_PORT);
|
||||
|
||||
qDebug() << "Updated domain hostname to" << _hostname;
|
||||
|
||||
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
|
||||
qDebug("Looking up DS hostname %s.", _hostname.toLocal8Bit().constData());
|
||||
QHostInfo::lookupHost(_hostname, this, SLOT(completedHostnameLookup(const QHostInfo&)));
|
||||
|
||||
UserActivityLogger::getInstance().changedDomain(_hostname);
|
||||
emit hostnameChanged(_hostname);
|
||||
}
|
||||
|
||||
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
|
||||
qDebug("Looking up DS hostname %s.", _hostname.toLocal8Bit().constData());
|
||||
QHostInfo::lookupHost(_hostname, this, SLOT(completedHostnameLookup(const QHostInfo&)));
|
||||
if (_sockAddr.getPort() != port) {
|
||||
qDebug() << "Updated domain port to" << port;
|
||||
}
|
||||
|
||||
UserActivityLogger::getInstance().changedDomain(_hostname);
|
||||
emit hostnameChanged(_hostname);
|
||||
// grab the port by reading the string after the colon
|
||||
_sockAddr.setPort(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,9 +37,7 @@ public:
|
|||
|
||||
const QUuid& getUUID() const { return _uuid; }
|
||||
void setUUID(const QUuid& uuid);
|
||||
|
||||
static QString hostnameWithoutPort(const QString& hostname);
|
||||
bool isCurrentHostname(const QString& hostname);
|
||||
|
||||
const QString& getHostname() const { return _hostname; }
|
||||
|
||||
const QHostAddress& getIP() const { return _sockAddr.getAddress(); }
|
||||
|
@ -75,7 +73,7 @@ public:
|
|||
|
||||
void softReset();
|
||||
public slots:
|
||||
void setHostname(const QString& hostname);
|
||||
void setHostnameAndPort(const QString& hostname, quint16 port = DEFAULT_DOMAIN_SERVER_PORT);
|
||||
void setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id);
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <LogHandler.h>
|
||||
|
||||
#include "AccountManager.h"
|
||||
#include "AddressManager.h"
|
||||
#include "Assignment.h"
|
||||
#include "HifiSockAddr.h"
|
||||
#include "NodeList.h"
|
||||
|
@ -43,6 +44,15 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
|
|||
firstCall = false;
|
||||
}
|
||||
|
||||
AddressManager& addressManager = AddressManager::getInstance();
|
||||
|
||||
// handle domain change signals from AddressManager
|
||||
connect(&addressManager, &AddressManager::possibleDomainChangeRequired,
|
||||
&_domainHandler, &DomainHandler::setHostnameAndPort);
|
||||
|
||||
connect(&addressManager, &AddressManager::possibleDomainChangeRequiredViaICEForID,
|
||||
&_domainHandler, &DomainHandler::setIceServerHostnameAndID);
|
||||
|
||||
// clear our NodeList when the domain changes
|
||||
connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, this, &NodeList::reset);
|
||||
|
||||
|
|
|
@ -15,5 +15,5 @@ include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
|||
# append ZLIB and OpenSSL to our list of libraries to link
|
||||
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -15,5 +15,5 @@ link_hifi_libraries(shared)
|
|||
## append BULLET to our list of libraries to link
|
||||
#list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${BULLET_LIBRARIES}")
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -5,12 +5,7 @@ setup_hifi_library(Widgets OpenGL Network Script)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared gpu)
|
||||
link_hifi_libraries(animation fbx shared gpu)
|
||||
|
||||
if (WIN32)
|
||||
find_package(GLUT REQUIRED)
|
||||
include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}")
|
||||
endif ()
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <gpu/GLUTConfig.h> // TODO - we need to get rid of this ASAP
|
||||
|
||||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
@ -68,19 +66,19 @@ void DeferredLightingEffect::renderSolidSphere(float radius, int slices, int sta
|
|||
|
||||
void DeferredLightingEffect::renderWireSphere(float radius, int slices, int stacks) {
|
||||
bindSimpleProgram();
|
||||
glutWireSphere(radius, slices, stacks);
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(radius, slices, stacks, false);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderSolidCube(float size) {
|
||||
bindSimpleProgram();
|
||||
glutSolidCube(size);
|
||||
DependencyManager::get<GeometryCache>()->renderSolidCube(size);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderWireCube(float size) {
|
||||
bindSimpleProgram();
|
||||
glutWireCube(size);
|
||||
DependencyManager::get<GeometryCache>()->renderWireCube(size);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,7 @@ public:
|
|||
|
||||
void init(AbstractViewStateInterface* viewState);
|
||||
|
||||
/// Returns a reference to a simple program suitable for rendering static
|
||||
/// untextured geometry (such as that generated by glutSolidSphere, etc.)
|
||||
/// Returns a reference to a simple program suitable for rendering static untextured geometry
|
||||
ProgramObject& getSimpleProgram() { return _simpleProgram; }
|
||||
|
||||
/// Sets up the state necessary to render static untextured geometry with the simple program.
|
||||
|
|
|
@ -119,7 +119,7 @@ const int NUM_COORDS_PER_VERTEX = 3;
|
|||
const int NUM_BYTES_PER_VERTEX = NUM_COORDS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int NUM_BYTES_PER_INDEX = sizeof(GLushort);
|
||||
|
||||
void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
||||
void GeometryCache::renderSphere(float radius, int slices, int stacks, bool solid) {
|
||||
VerticesIndices& vbo = _sphereVBOs[IntPair(slices, stacks)];
|
||||
int vertices = slices * (stacks - 1) + 2;
|
||||
int indices = slices * stacks * NUM_VERTICES_PER_TRIANGULATED_QUAD;
|
||||
|
@ -211,7 +211,11 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) {
|
|||
|
||||
glPushMatrix();
|
||||
glScalef(radius, radius, radius);
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
if (solid) {
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
} else {
|
||||
glDrawRangeElementsEXT(GL_LINES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
@ -503,6 +507,161 @@ void GeometryCache::renderGrid(int xDivisions, int yDivisions) {
|
|||
buffer.release();
|
||||
}
|
||||
|
||||
void GeometryCache::renderSolidCube(float size) {
|
||||
VerticesIndices& vbo = _solidCubeVBOs[size];
|
||||
const int FLOATS_PER_VERTEX = 3;
|
||||
const int VERTICES_PER_FACE = 4;
|
||||
const int NUMBER_OF_FACES = 6;
|
||||
const int TRIANGLES_PER_FACE = 2;
|
||||
const int VERTICES_PER_TRIANGLE = 3;
|
||||
const int vertices = NUMBER_OF_FACES * VERTICES_PER_FACE * FLOATS_PER_VERTEX;
|
||||
const int indices = NUMBER_OF_FACES * TRIANGLES_PER_FACE * VERTICES_PER_TRIANGLE;
|
||||
const int vertexPoints = vertices * FLOATS_PER_VERTEX;
|
||||
if (vbo.first == 0) {
|
||||
GLfloat* vertexData = new GLfloat[vertexPoints * 2]; // vertices and normals
|
||||
GLfloat* vertex = vertexData;
|
||||
float halfSize = size / 2.0f;
|
||||
|
||||
static GLfloat cannonicalVertices[vertexPoints] =
|
||||
{ 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)
|
||||
1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)
|
||||
1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0,v5,v6,v1 (top)
|
||||
-1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1,v6,v7,v2 (left)
|
||||
-1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, // v7,v4,v3,v2 (bottom)
|
||||
1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)
|
||||
|
||||
// normal array
|
||||
static GLfloat cannonicalNormals[vertexPoints] =
|
||||
{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
|
||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
|
||||
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)
|
||||
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left)
|
||||
0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7,v4,v3,v2 (bottom)
|
||||
0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 }; // v4,v7,v6,v5 (back)
|
||||
|
||||
// index array of vertex array for glDrawElements() & glDrawRangeElement()
|
||||
static GLubyte cannonicalIndices[indices] =
|
||||
{ 0, 1, 2, 2, 3, 0, // front
|
||||
4, 5, 6, 6, 7, 4, // right
|
||||
8, 9,10, 10,11, 8, // top
|
||||
12,13,14, 14,15,12, // left
|
||||
16,17,18, 18,19,16, // bottom
|
||||
20,21,22, 22,23,20 }; // back
|
||||
|
||||
|
||||
|
||||
GLfloat* cannonicalVertex = &cannonicalVertices[0];
|
||||
GLfloat* cannonicalNormal = &cannonicalNormals[0];
|
||||
|
||||
for (int i = 0; i < vertices; i++) {
|
||||
//normals
|
||||
*(vertex++) = *cannonicalNormal++;
|
||||
*(vertex++) = *cannonicalNormal++;
|
||||
*(vertex++) = *cannonicalNormal++;
|
||||
|
||||
// vertices
|
||||
*(vertex++) = halfSize * *cannonicalVertex++;
|
||||
*(vertex++) = halfSize * *cannonicalVertex++;
|
||||
*(vertex++) = halfSize * *cannonicalVertex++;
|
||||
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < indices; i++) {
|
||||
index[i] = cannonicalIndices[i];
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glNormalPointer(GL_FLOAT, 6 * sizeof(float), 0);
|
||||
glVertexPointer(3, GL_FLOAT, (6 * sizeof(float)), (const void *)(3 * sizeof(float)));
|
||||
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireCube(float size) {
|
||||
VerticesIndices& vbo = _wireCubeVBOs[size];
|
||||
const int FLOATS_PER_VERTEX = 3;
|
||||
const int VERTICES_PER_EDGE = 2;
|
||||
const int TOP_EDGES = 4;
|
||||
const int BOTTOM_EDGES = 4;
|
||||
const int SIDE_EDGES = 4;
|
||||
const int vertices = 8;
|
||||
const int indices = (TOP_EDGES + BOTTOM_EDGES + SIDE_EDGES) * VERTICES_PER_EDGE;
|
||||
if (vbo.first == 0) {
|
||||
int vertexPoints = vertices * FLOATS_PER_VERTEX;
|
||||
GLfloat* vertexData = new GLfloat[vertexPoints]; // only vertices, no normals because we're a wire cube
|
||||
GLfloat* vertex = vertexData;
|
||||
float halfSize = size / 2.0f;
|
||||
|
||||
static GLfloat cannonicalVertices[] =
|
||||
{ 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0, v1, v2, v3 (top)
|
||||
1,-1, 1, 1,-1,-1, -1,-1,-1, -1,-1, 1 // v4, v5, v6, v7 (bottom)
|
||||
};
|
||||
|
||||
// index array of vertex array for glDrawRangeElement() as a GL_LINES for each edge
|
||||
static GLubyte cannonicalIndices[indices] = {
|
||||
0, 1, 1, 2, 2, 3, 3, 0, // (top)
|
||||
4, 5, 5, 6, 6, 7, 7, 4, // (bottom)
|
||||
0, 4, 1, 5, 2, 6, 3, 7, // (side edges)
|
||||
};
|
||||
|
||||
for (int i = 0; i < vertexPoints; i++) {
|
||||
vertex[i] = cannonicalVertices[i] * halfSize;
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.first);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices * NUM_BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW);
|
||||
delete[] vertexData;
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
for (int i = 0; i < indices; i++) {
|
||||
index[i] = cannonicalIndices[i];
|
||||
}
|
||||
|
||||
glGenBuffers(1, &vbo.second);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * NUM_BYTES_PER_INDEX, indexData, GL_STATIC_DRAW);
|
||||
delete[] indexData;
|
||||
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.first);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second);
|
||||
}
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(FLOATS_PER_VERTEX, GL_FLOAT, FLOATS_PER_VERTEX * sizeof(float), 0);
|
||||
glDrawRangeElementsEXT(GL_LINES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad) {
|
||||
return getResource(url, fallback, delayLoad).staticCast<NetworkGeometry>();
|
||||
}
|
||||
|
|
|
@ -38,11 +38,13 @@ class GeometryCache : public ResourceCache {
|
|||
|
||||
public:
|
||||
void renderHemisphere(int slices, int stacks);
|
||||
void renderSphere(float radius, int slices, int stacks);
|
||||
void renderSphere(float radius, int slices, int stacks, bool solid = true);
|
||||
void renderSquare(int xDivisions, int yDivisions);
|
||||
void renderHalfCylinder(int slices, int stacks);
|
||||
void renderCone(float base, float height, int slices, int stacks);
|
||||
void renderGrid(int xDivisions, int yDivisions);
|
||||
void renderSolidCube(float size);
|
||||
void renderWireCube(float size);
|
||||
|
||||
/// Loads geometry from the specified URL.
|
||||
/// \param fallback a fallback URL to load if the desired one is unavailable
|
||||
|
@ -66,6 +68,8 @@ private:
|
|||
QHash<IntPair, VerticesIndices> _squareVBOs;
|
||||
QHash<IntPair, VerticesIndices> _halfCylinderVBOs;
|
||||
QHash<IntPair, VerticesIndices> _coneVBOs;
|
||||
QHash<float, VerticesIndices> _wireCubeVBOs;
|
||||
QHash<float, VerticesIndices> _solidCubeVBOs;
|
||||
QHash<IntPair, QOpenGLBuffer> _gridBuffers;
|
||||
|
||||
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
||||
|
|
|
@ -5,7 +5,7 @@ setup_hifi_library(Gui Network Script Widgets)
|
|||
|
||||
include_glm()
|
||||
|
||||
link_hifi_libraries(shared octree voxels fbx entities animation audio physics)
|
||||
link_hifi_libraries(shared octree voxels fbx entities animation audio physics metavoxels)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
||||
|
|
|
@ -601,16 +601,20 @@ void ScriptEngine::stopTimer(QTimer *timer) {
|
|||
}
|
||||
|
||||
QUrl ScriptEngine::resolvePath(const QString& include) const {
|
||||
// first lets check to see if it's already a full URL
|
||||
QUrl url(include);
|
||||
// first lets check to see if it's already a full URL
|
||||
if (!url.scheme().isEmpty()) {
|
||||
return url;
|
||||
}
|
||||
|
||||
// we apparently weren't a fully qualified url, so, let's assume we're relative
|
||||
// to the original URL of our script
|
||||
QUrl parentURL(_fileNameString);
|
||||
|
||||
QUrl parentURL;
|
||||
if (_parentURL.isEmpty()) {
|
||||
parentURL = QUrl(_fileNameString);
|
||||
} else {
|
||||
parentURL = QUrl(_parentURL);
|
||||
}
|
||||
// if the parent URL's scheme is empty, then this is probably a local file...
|
||||
if (parentURL.scheme().isEmpty()) {
|
||||
parentURL = QUrl::fromLocalFile(_fileNameString);
|
||||
|
@ -643,6 +647,7 @@ void ScriptEngine::include(const QString& includeFile) {
|
|||
#else
|
||||
QString fileName = url.toLocalFile();
|
||||
#endif
|
||||
|
||||
QFile scriptFile(fileName);
|
||||
if (scriptFile.open(QFile::ReadOnly | QFile::Text)) {
|
||||
qDebug() << "Including file:" << fileName;
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; }
|
||||
bool isUserLoaded() const { return _isUserLoaded; }
|
||||
|
||||
void setParentURL(const QString& parentURL) { _parentURL = parentURL; }
|
||||
|
||||
public slots:
|
||||
void loadURL(const QUrl& scriptURL);
|
||||
void stop();
|
||||
|
@ -120,6 +122,7 @@ signals:
|
|||
|
||||
protected:
|
||||
QString _scriptContents;
|
||||
QString _parentURL;
|
||||
bool _isFinished;
|
||||
bool _isRunning;
|
||||
bool _isInitialized;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
set(TARGET_NAME shared)
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library(Network Widgets)
|
||||
# TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp)
|
||||
setup_hifi_library(Network Script Widgets)
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -98,6 +98,14 @@ std::ostream& operator<<(std::ostream& s, const CapsuleShape& capsule) {
|
|||
#ifndef QT_NO_DEBUG_STREAM
|
||||
#include <QDebug>
|
||||
|
||||
QDebug& operator<<(QDebug& dbg, const glm::vec2& v) {
|
||||
dbg.nospace() << "{type='glm::vec2'"
|
||||
", x=" << v.x <<
|
||||
", y=" << v.y <<
|
||||
"}";
|
||||
return dbg;
|
||||
}
|
||||
|
||||
QDebug& operator<<(QDebug& dbg, const glm::vec3& v) {
|
||||
dbg.nospace() << "{type='glm::vec3'"
|
||||
", x=" << v.x <<
|
||||
|
|
|
@ -49,6 +49,7 @@ std::ostream& operator<<(std::ostream& s, const CapsuleShape& capsule);
|
|||
#ifndef QT_NO_DEBUG_STREAM
|
||||
class QDebug;
|
||||
// Add support for writing these to qDebug().
|
||||
QDebug& operator<<(QDebug& s, const glm::vec2& v);
|
||||
QDebug& operator<<(QDebug& s, const glm::vec3& v);
|
||||
QDebug& operator<<(QDebug& s, const glm::quat& q);
|
||||
QDebug& operator<<(QDebug& s, const glm::mat4& m);
|
||||
|
|
|
@ -14,5 +14,5 @@ include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
|||
# add it to our list of libraries to link
|
||||
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
|
||||
|
||||
# call macro to link our dependencies and bubble them up via a property on our target
|
||||
link_shared_dependencies()
|
||||
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||
include_dependency_includes()
|
|
@ -7,4 +7,4 @@ include_glm()
|
|||
# link in the shared libraries
|
||||
link_hifi_libraries(shared audio networking)
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
|
@ -5,4 +5,4 @@ setup_hifi_project()
|
|||
# link in the shared libraries
|
||||
link_hifi_libraries(shared networking)
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
|
@ -9,4 +9,4 @@ setup_hifi_project(Network Script Widgets)
|
|||
# link in the shared libraries
|
||||
link_hifi_libraries(metavoxels networking shared)
|
||||
|
||||
link_shared_dependencies()
|
||||
include_dependency_includes()
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue