Merge branch 'master' of github.com:highfidelity/hifi into rig

This commit is contained in:
Seth Alves 2015-08-04 16:06:38 -07:00
commit 9171033f21
136 changed files with 2372 additions and 3217 deletions

View file

@ -70,7 +70,7 @@ void Agent::handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointe
// pull out the piggybacked packet and create a new QSharedPointer<NLPacket> for it
int piggyBackedSizeWithHeader = packet->getPayloadSize() - statsMessageLength;
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[piggyBackedSizeWithHeader]);
auto buffer = std::unique_ptr<char[]>(new char[piggyBackedSizeWithHeader]);
memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggyBackedSizeWithHeader);
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggyBackedSizeWithHeader, packet->getSenderSockAddr());
@ -107,6 +107,7 @@ void Agent::handleAudioPacket(QSharedPointer<NLPacket> packet) {
}
const QString AGENT_LOGGING_NAME = "agent";
const int PING_INTERVAL = 1000;
void Agent::run() {
ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);
@ -118,6 +119,10 @@ void Agent::run() {
<< NodeType::EntityServer
);
_pingTimer = new QTimer(this);
connect(_pingTimer, SIGNAL(timeout()), SLOT(sendPingRequests()));
_pingTimer->start(PING_INTERVAL);
// figure out the URL for the script for this agent assignment
QUrl scriptURL;
if (_payload.isEmpty()) {
@ -193,7 +198,27 @@ void Agent::run() {
void Agent::aboutToFinish() {
_scriptEngine.stop();
_pingTimer->stop();
delete _pingTimer;
// our entity tree is going to go away so tell that to the EntityScriptingInterface
DependencyManager::get<EntityScriptingInterface>()->setEntityTree(NULL);
}
void Agent::sendPingRequests() {
auto nodeList = DependencyManager::get<NodeList>();
nodeList->eachMatchingNode([](const SharedNodePointer& node)->bool {
switch (node->getType()) {
case NodeType::AvatarMixer:
case NodeType::AudioMixer:
case NodeType::EntityServer:
return true;
default:
return false;
}
}, [nodeList](const SharedNodePointer& node) {
nodeList->sendPacket(nodeList->constructPingPacket(), *node);
});
}

View file

@ -58,11 +58,13 @@ private slots:
void handleAudioPacket(QSharedPointer<NLPacket> packet);
void handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
void handleJurisdictionPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
void sendPingRequests();
private:
ScriptEngine _scriptEngine;
EntityEditPacketSender _entityEditSender;
EntityTreeHeadlessViewer _entityViewer;
QTimer* _pingTimer;
MixedAudioStream _receivedAudioStream;
float _lastReceivedAudioLoudness;

View file

@ -38,5 +38,19 @@ if (WIN32)
find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_INCLUDE_DIRS GLEW_LIBRARIES GLEW_DLL_PATH)
add_paths_to_fixup_libs(${GLEW_DLL_PATH})
elseif (APPLE)
else ()
find_path(GLEW_INCLUDE_DIR GL/glew.h)
find_library(GLEW_LIBRARY NAMES GLEW glew32 glew glew32s PATH_SUFFIXES lib64)
set(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR})
set(GLEW_LIBRARIES ${GLEW_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLEW
REQUIRED_VARS GLEW_INCLUDE_DIR GLEW_LIBRARY)
mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY)
endif ()

214
examples/controlPanel.js Normal file
View file

@ -0,0 +1,214 @@
//
// controlPanel.js
// examples
//
// Created by Zander Otavka on 7/15/15.
// Copyright 2015 High Fidelity, Inc.
//
// Shows a few common controls in a FloatingUIPanel on right click.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
Script.include([
"libraries/globals.js",
"libraries/overlayManager.js",
]);
var BG_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/card-bg.svg";
var CLOSE_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/tools/close.svg";
var MIC_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/tools/mic-toggle.svg";
var FACE_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/tools/face-toggle.svg";
var ADDRESS_BAR_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/tools/address-bar-toggle.svg";
var panel = new FloatingUIPanel({
anchorPosition: {
bind: "myAvatar"
},
offsetPosition: { x: 0, y: 0.4, z: 1 }
});
var background = new BillboardOverlay({
url: BG_IMAGE_URL,
dimensions: {
x: 0.5,
y: 0.5,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false
});
panel.addChild(background);
var closeButton = new BillboardOverlay({
url: CLOSE_IMAGE_URL,
dimensions: {
x: 0.15,
y: 0.15,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: -0.1,
y: 0.1,
z: -0.001
}
});
closeButton.onClick = function(event) {
panel.visible = false;
};
panel.addChild(closeButton);
var micMuteButton = new BillboardOverlay({
url: MIC_IMAGE_URL,
subImage: {
x: 0,
y: 0,
width: 45,
height: 45
},
dimensions: {
x: 0.15,
y: 0.15,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: 0.1,
y: 0.1,
z: -0.001
}
});
micMuteButton.onClick = function(event) {
AudioDevice.toggleMute();
};
panel.addChild(micMuteButton);
var faceMuteButton = new BillboardOverlay({
url: FACE_IMAGE_URL,
subImage: {
x: 0,
y: 0,
width: 45,
height: 45
},
dimensions: {
x: 0.15,
y: 0.15,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: 0.1,
y: -0.1,
z: -0.001
}
});
faceMuteButton.onClick = function(event) {
FaceTracker.toggleMute();
};
panel.addChild(faceMuteButton);
var addressBarButton = new BillboardOverlay({
url: ADDRESS_BAR_IMAGE_URL,
subImage: {
x: 0,
y: 0,
width: 45,
height: 45
},
dimensions: {
x: 0.15,
y: 0.15,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: -0.1,
y: -0.1,
z: -0.001
}
});
addressBarButton.onClick = function(event) {
DialogsManager.toggleAddressBar();
};
panel.addChild(addressBarButton);
function onMicMuteToggled() {
var offset;
if (AudioDevice.getMuted()) {
offset = 45;
} else {
offset = 0;
}
micMuteButton.subImage = {
x: offset,
y: 0,
width: 45,
height: 45
};
}
onMicMuteToggled();
function onFaceMuteToggled() {
var offset;
if (FaceTracker.getMuted()) {
offset = 45;
} else {
offset = 0;
}
faceMuteButton.subImage = {
x: offset,
y: 0,
width: 45,
height: 45
};
}
onFaceMuteToggled();
var mouseDown = {};
function onMouseDown(event) {
if (event.isLeftButton) {
mouseDown.overlay = OverlayManager.findAtPoint({ x: event.x, y: event.y });
}
if (event.isRightButton) {
mouseDown.pos = { x: event.x, y: event.y };
}
}
function onMouseUp(event) {
if (event.isLeftButton) {
var overlay = OverlayManager.findAtPoint({ x: event.x, y: event.y });
if (overlay && overlay === mouseDown.overlay && overlay.onClick) {
overlay.onClick(event);
}
}
if (event.isRightButton && Vec3.distance(mouseDown.pos, { x: event.x, y: event.y }) < 5) {
panel.setProperties({
visible: !panel.visible,
offsetRotation: {
bind: "quat",
value: Quat.multiply(MyAvatar.orientation, { x: 0, y: 1, z: 0, w: 0 })
}
});
}
mouseDown = {};
}
function onScriptEnd(event) {
panel.destroy();
}
Controller.mousePressEvent.connect(onMouseDown);
Controller.mouseReleaseEvent.connect(onMouseUp);
AudioDevice.muteToggled.connect(onMicMuteToggled);
FaceTracker.muteToggled.connect(onFaceMuteToggled);
Script.scriptEnding.connect(onScriptEnd);

View file

@ -0,0 +1,169 @@
//
// floatingUI.js
// examples/example/ui
//
// Created by Alexander Otavka
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
Script.include([
"../../libraries/globals.js",
"../../libraries/overlayManager.js",
]);
var BG_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/card-bg.svg";
var RED_DOT_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/red-dot.svg";
var BLUE_SQUARE_IMAGE_URL = HIFI_PUBLIC_BUCKET + "images/blue-square.svg";
var mainPanel = new FloatingUIPanel({
offsetRotation: {
bind: "quat",
value: { w: 1, x: 0, y: 0, z: 0 }
},
offsetPosition: { x: 0, y: 0.4, z: 1 }
});
var bluePanel = mainPanel.addChild(new FloatingUIPanel ({
offsetPosition: { x: 0.1, y: 0.1, z: -0.2 }
}));
var mainPanelBackground = new BillboardOverlay({
url: BG_IMAGE_URL,
dimensions: {
x: 0.5,
y: 0.5,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: 0,
y: 0,
z: 0.001
}
});
var bluePanelBackground = mainPanelBackground.clone();
bluePanelBackground.dimensions = {
x: 0.3,
y: 0.3
};
mainPanel.addChild(mainPanelBackground);
bluePanel.addChild(bluePanelBackground);
var redDot = mainPanel.addChild(new BillboardOverlay({
url: RED_DOT_IMAGE_URL,
dimensions: {
x: 0.1,
y: 0.1,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: -0.15,
y: -0.15,
z: 0
}
}));
var redDot2 = mainPanel.addChild(new BillboardOverlay({
url: RED_DOT_IMAGE_URL,
dimensions: {
x: 0.1,
y: 0.1,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: -0.155,
y: 0.005,
z: 0
}
}));
var blueSquare = bluePanel.addChild(new BillboardOverlay({
url: BLUE_SQUARE_IMAGE_URL,
dimensions: {
x: 0.1,
y: 0.1,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: 0.055,
y: -0.055,
z: 0
}
}));
var blueSquare2 = bluePanel.addChild(new BillboardOverlay({
url: BLUE_SQUARE_IMAGE_URL,
dimensions: {
x: 0.1,
y: 0.1,
},
isFacingAvatar: false,
alpha: 1.0,
ignoreRayIntersection: false,
offsetPosition: {
x: 0.055,
y: 0.055,
z: 0
}
}));
var blueSquare3 = blueSquare2.clone();
blueSquare3.offsetPosition = {
x: -0.055,
y: 0.055,
z: 0
};
var mouseDown = {};
function onMouseDown(event) {
if (event.isLeftButton) {
mouseDown.overlay = OverlayManager.findAtPoint({ x: event.x, y: event.y });
}
if (event.isRightButton) {
mouseDown.pos = { x: event.x, y: event.y };
}
}
function onMouseUp(event) {
if (event.isLeftButton) {
var overlay = OverlayManager.findAtPoint({ x: event.x, y: event.y });
if (overlay === mouseDown.overlay) {
if (overlay.attachedPanel === bluePanel) {
overlay.destroy();
} else if (overlay) {
var oldPos = overlay.offsetPosition;
var newPos = {
x: Number(oldPos.x),
y: Number(oldPos.y),
z: Number(oldPos.z) + 0.1
};
overlay.offsetPosition = newPos;
}
}
}
if (event.isRightButton && Vec3.distance(mouseDown.pos, { x: event.x, y: event.y }) < 5) {
mainPanel.visible = !mainPanel.visible;
}
}
function onScriptEnd() {
mainPanel.destroy();
}
Controller.mousePressEvent.connect(onMouseDown);
Controller.mouseReleaseEvent.connect(onMouseUp);
Script.scriptEnding.connect(onScriptEnd);

View file

@ -9,7 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var MOVE_DISTANCE = 10.0;
var MOVE_DISTANCE = 2.0;
var PITCH_INCREMENT = 0.5; // degrees
var pitchChange = 0; // degrees
var YAW_INCREMENT = 0.5; // degrees

View file

@ -23,7 +23,7 @@ var RAD_TO_DEG = 180.0 / PI;
var AZIMUTH_RATE = 90.0;
var ALTITUDE_RATE = 200.0;
var RADIUS_RATE = 1.0 / 100.0;
var PAN_RATE = 50.0;
var PAN_RATE = 250.0;
var Y_AXIS = {
x: 0,
@ -139,7 +139,7 @@ function handlePanMode(dx, dy) {
var right = Quat.getRight(Camera.getOrientation());
var distance = Vec3.length(vector);
var dv = Vec3.sum(Vec3.multiply(up, -distance * dy / PAN_RATE), Vec3.multiply(right, distance * dx / PAN_RATE));
var dv = Vec3.sum(Vec3.multiply(up, distance * dy / PAN_RATE), Vec3.multiply(right, -distance * dx / PAN_RATE));
center = Vec3.sum(center, dv);
position = Vec3.sum(position, dv);

View file

@ -0,0 +1,455 @@
//
// overlayManager.js
// examples/libraries
//
// Created by Zander Otavka on 7/24/15
// Copyright 2015 High Fidelity, Inc.
//
// Manage overlays with object oriented goodness, instead of ugly `Overlays.h` methods.
// Instead of:
//
// var billboard = Overlays.addOverlay("billboard", { visible: false });
// ...
// Overlays.editOverlay(billboard, { visible: true });
// ...
// Overlays.deleteOverlay(billboard);
//
// You can now do:
//
// var billboard = new BillboardOverlay({ visible: false });
// ...
// billboard.visible = true;
// ...
// billboard.destroy();
//
// See more on usage below.
//
// Note that including this file will delete Overlays from the global scope. All the
// functionality of Overlays is represented here, just better. If you try to use Overlays in
// tandem, there may be performance problems or nasty surprises.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
// Delete `Overlays` from the global scope.
var Overlays = this.Overlays;
delete this.Overlays;
var overlays = {};
var panels = {};
var overlayTypes;
var Overlay, Overlay2D, Base3DOverlay, Planar3DOverlay, Volume3DOverlay;
//
// Create a new JavaScript object for an overlay of given ID.
//
function makeOverlayFromId(id) {
var type = Overlays.getOverlayType(id);
if (!type) {
return null;
}
var overlay = new overlayTypes[type]();
overlay._id = id;
var panelID = Overlays.getAttachedPanel(id)
if (panelID && panelID in panels) {
panels[panelID].addChild(overlay);
}
overlays[id] = overlay;
return overlay;
}
//
// Get or create an overlay object from the id.
//
// @param knownOverlaysOnly (Optional: Boolean)
// If true, a new object will not be created.
// @param searchList (Optional: Object)
// Map of overlay id's and overlay objects. Can be generated with
// `OverlayManager.makeSearchList`.
//
function findOverlay(id, knownOverlaysOnly, searchList) {
if (id > 0) {
knownOverlaysOnly = Boolean(knownOverlaysOnly) || Boolean(searchList);
searchList = searchList || overlays;
var foundOverlay = searchList[id];
if (foundOverlay) {
return foundOverlay;
}
if (!knownOverlaysOnly) {
return makeOverlayFromId(id);
}
}
return null;
}
//
// Perform global scoped operations on overlays, such as finding by ray intersection.
//
OverlayManager = {
findOnRay: function(pickRay, knownOverlaysOnly, searchList) {
var rayPickResult = Overlays.findRayIntersection(pickRay);
print("raypick " + rayPickResult.overlayID);
if (rayPickResult.intersects) {
return findOverlay(rayPickResult.overlayID, knownOverlaysOnly, searchList);
}
return null;
},
findAtPoint: function(point, knownOverlaysOnly, searchList) {
var foundID = Overlays.getOverlayAtPoint(point);
print("at point " + foundID);
if (foundID) {
return findOverlay(foundID, knownOverlaysOnly, searchList);
} else {
var pickRay = Camera.computePickRay(point.x, point.y);
return OverlayManager.findOnRay(pickRay, knownOverlaysOnly, searchList);
}
},
makeSearchList: function(overlayArray) {
var searchList = {};
overlayArray.forEach(function(overlay){
searchList[overlay._id] = overlay;
});
return searchList;
}
};
//
// Object oriented abstraction layer for overlays.
//
// Usage:
// // Create an overlay
// var billboard = new BillboardOverlay({
// visible: true,
// isFacingAvatar: true,
// ignoreRayIntersections: false
// });
//
// // Get a property
// var isVisible = billboard.visible;
//
// // Set a single property
// billboard.position = { x: 1, y: 3, z: 2 };
//
// // Set multiple properties at the same time
// billboard.setProperties({
// url: "http://images.com/overlayImage.jpg",
// dimensions: { x: 2, y: 2 }
// });
//
// // Clone an overlay
// var clonedBillboard = billboard.clone();
//
// // Remove an overlay from the world
// billboard.destroy();
//
// // Remember, there is a poor orphaned JavaScript object left behind. You should
// // remove any references to it so you don't accidentally try to modify an overlay that
// // isn't there.
// billboard = undefined;
//
(function() {
var ABSTRACT = null;
overlayTypes = {};
function generateOverlayClass(superclass, type, properties) {
var that;
if (type == ABSTRACT) {
that = function(type, params) {
superclass.call(this, type, params);
};
} else {
that = function(params) {
superclass.call(this, type, params);
};
overlayTypes[type] = that;
}
that.prototype = new superclass();
that.prototype.constructor = that;
properties.forEach(function(prop) {
Object.defineProperty(that.prototype, prop, {
get: function() {
return Overlays.getProperty(this._id, prop);
},
set: function(newValue) {
var keyValuePair = {};
keyValuePair[prop] = newValue;
this.setProperties(keyValuePair);
},
configurable: false
});
});
return that;
}
// Supports multiple inheritance of properties. Just `concat` them onto the end of the
// properties list.
var PANEL_ATTACHABLE_FIELDS = ["offsetPosition", "facingRotation"];
Overlay = (function() {
var that = function(type, params) {
if (type && params) {
this._id = Overlays.addOverlay(type, params);
overlays[this._id] = this;
} else {
this._id = 0;
}
this._attachedPanelPointer = null;
};
that.prototype.constructor = that;
Object.defineProperty(that.prototype, "isLoaded", {
get: function() {
return Overlays.isLoaded(this._id);
}
});
Object.defineProperty(that.prototype, "attachedPanel", {
get: function() {
return this._attachedPanelPointer;
}
});
that.prototype.getTextSize = function(text) {
return Overlays.textSize(this._id, text);
};
that.prototype.setProperties = function(properties) {
Overlays.editOverlay(this._id, properties);
};
that.prototype.clone = function() {
return makeOverlayFromId(Overlays.cloneOverlay(this._id));
};
that.prototype.destroy = function() {
Overlays.deleteOverlay(this._id);
};
return generateOverlayClass(that, ABSTRACT, [
"alpha", "glowLevel", "pulseMax", "pulseMin", "pulsePeriod", "glowLevelPulse",
"alphaPulse", "colorPulse", "visible", "anchor"
]);
})();
Overlay2D = generateOverlayClass(Overlay, ABSTRACT, [
"bounds", "x", "y", "width", "height"
]);
Base3DOverlay = generateOverlayClass(Overlay, ABSTRACT, [
"position", "lineWidth", "rotation", "isSolid", "isFilled", "isWire", "isDashedLine",
"ignoreRayIntersection", "drawInFront", "drawOnHUD"
]);
Planar3DOverlay = generateOverlayClass(Base3DOverlay, ABSTRACT, [
"dimensions"
]);
Volume3DOverlay = generateOverlayClass(Base3DOverlay, ABSTRACT, [
"dimensions"
]);
generateOverlayClass(Overlay2D, "image", [
"subImage", "imageURL"
]);
generateOverlayClass(Overlay2D, "text", [
"font", "text", "backgroundColor", "backgroundAlpha", "leftMargin", "topMargin"
]);
generateOverlayClass(Planar3DOverlay, "text3d", [
"text", "backgroundColor", "backgroundAlpha", "lineHeight", "leftMargin", "topMargin",
"rightMargin", "bottomMargin", "isFacingAvatar"
]);
generateOverlayClass(Volume3DOverlay, "cube", [
"borderSize"
]);
generateOverlayClass(Volume3DOverlay, "sphere", [
]);
generateOverlayClass(Planar3DOverlay, "circle3d", [
"startAt", "endAt", "outerRadius", "innerRadius", "hasTickMarks",
"majorTickMarksAngle", "minorTickMarksAngle", "majorTickMarksLength",
"minorTickMarksLength", "majorTickMarksColor", "minorTickMarksColor"
]);
generateOverlayClass(Planar3DOverlay, "rectangle3d", [
]);
generateOverlayClass(Base3DOverlay, "line3d", [
"start", "end"
]);
generateOverlayClass(Planar3DOverlay, "grid", [
"minorGridWidth", "majorGridEvery"
]);
generateOverlayClass(Volume3DOverlay, "localmodels", [
]);
generateOverlayClass(Volume3DOverlay, "model", [
"url", "dimensions", "textures"
]);
generateOverlayClass(Planar3DOverlay, "billboard", [
"url", "subImage", "isFacingAvatar"
].concat(PANEL_ATTACHABLE_FIELDS));
})();
ImageOverlay = overlayTypes["image"];
TextOverlay = overlayTypes["text"];
Text3DOverlay = overlayTypes["text3d"];
Cube3DOverlay = overlayTypes["cube"];
Sphere3DOverlay = overlayTypes["sphere"];
Circle3DOverlay = overlayTypes["circle3d"];
Rectangle3DOverlay = overlayTypes["rectangle3d"];
Line3DOverlay = overlayTypes["line3d"];
Grid3DOverlay = overlayTypes["grid"];
LocalModelsOverlay = overlayTypes["localmodels"];
ModelOverlay = overlayTypes["model"];
BillboardOverlay = overlayTypes["billboard"];
//
// Object oriented abstraction layer for panels.
//
FloatingUIPanel = (function() {
var that = function(params) {
this._id = Overlays.addPanel(params);
this._children = [];
this._visible = Boolean(params.visible);
panels[this._id] = this;
this._attachedPanelPointer = null;
};
that.prototype.constructor = that;
var FIELDS = ["offsetPosition", "offsetRotation", "facingRotation"];
FIELDS.forEach(function(prop) {
Object.defineProperty(that.prototype, prop, {
get: function() {
return Overlays.getPanelProperty(this._id, prop);
},
set: function(newValue) {
var keyValuePair = {};
keyValuePair[prop] = newValue;
this.setProperties(keyValuePair);
},
configurable: false
});
});
var PSEUDO_FIELDS = [];
PSEUDO_FIELDS.push("children");
Object.defineProperty(that.prototype, "children", {
get: function() {
return this._children.slice();
}
});
PSEUDO_FIELDS.push("visible");
Object.defineProperty(that.prototype, "visible", {
get: function() {
return this._visible;
},
set: function(visible) {
this._visible = visible;
this._children.forEach(function(child) {
child.visible = visible;
});
}
});
that.prototype.addChild = function(child) {
if (child instanceof Overlay) {
Overlays.setAttachedPanel(child._id, this._id);
} else if (child instanceof FloatingUIPanel) {
child.setProperties({
anchorPosition: {
bind: "panel",
value: this._id
},
offsetRotation: {
bind: "panel",
value: this._id
}
});
}
child._attachedPanelPointer = this;
child.visible = this.visible;
this._children.push(child);
return child;
};
that.prototype.removeChild = function(child) {
var i = this._children.indexOf(child);
if (i >= 0) {
if (child instanceof Overlay) {
Overlays.setAttachedPanel(child._id, 0);
} else if (child instanceof FloatingUIPanel) {
child.setProperties({
anchorPosition: {
bind: "myAvatar"
},
offsetRotation: {
bind: "myAvatar"
}
});
}
child._attachedPanelPointer = null;
this._children.splice(i, 1);
}
};
that.prototype.setProperties = function(properties) {
for (var i in PSEUDO_FIELDS) {
if (properties[PSEUDO_FIELDS[i]] !== undefined) {
this[PSEUDO_FIELDS[i]] = properties[PSEUDO_FIELDS[i]];
}
}
Overlays.editPanel(this._id, properties);
};
that.prototype.destroy = function() {
Overlays.deletePanel(this._id);
};
return that;
})();
function onOverlayDeleted(id) {
if (id in overlays) {
if (overlays[id]._attachedPanelPointer) {
overlays[id]._attachedPanelPointer.removeChild(overlays[id]);
}
delete overlays[id];
}
}
function onPanelDeleted(id) {
if (id in panels) {
panels[id]._children.forEach(function(child) {
print(JSON.stringify(child.destroy));
child.destroy();
});
delete panels[id];
}
}
Overlays.overlayDeleted.connect(onOverlayDeleted);
Overlays.panelDeleted.connect(onPanelDeleted);
})();

View file

@ -1,7 +1,17 @@
/**
* OverlayGroup provides a way to create composite overlays and control their
* position relative to a settable rootPosition and rootRotation.
*/
//
// overlayUtils.js
// examples/libraries
//
// Copyright 2015 High Fidelity, Inc.
//
//
// DEPRECATION WARNING: Will be deprecated soon in favor of FloatingUIPanel.
//
// OverlayGroup provides a way to create composite overlays and control their
// position relative to a settable rootPosition and rootRotation.
//
OverlayGroup = function(opts) {
var that = {};
@ -59,6 +69,6 @@ OverlayGroup = function(opts) {
}
overlays = {};
}
return that;
};

View file

@ -50,7 +50,7 @@ void IceServer::processDatagrams() {
while (_serverSocket.hasPendingDatagrams()) {
// setup a buffer to read the packet into
int packetSizeWithHeader = _serverSocket.pendingDatagramSize();
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[packetSizeWithHeader]);
auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]);
_serverSocket.readDatagram(buffer.get(), packetSizeWithHeader,
sendingSockAddr.getAddressPointer(), sendingSockAddr.getPortPointer());

View file

@ -218,33 +218,13 @@ else (APPLE)
"${PROJECT_SOURCE_DIR}/resources"
$<TARGET_FILE_DIR:${TARGET_NAME}>/resources
)
find_package(OpenGL REQUIRED)
if (${OPENGL_INCLUDE_DIR})
include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}")
endif ()
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}")
# link target to external libraries
if (WIN32)
add_dependency_external_projects(glew)
find_package(GLEW REQUIRED)
target_include_directories(${TARGET_NAME} PRIVATE ${GLEW_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} wsock32.lib opengl32.lib Winmm.lib)
if (USE_NSIGHT)
# try to find the Nsight package and add it to the build if we find it
find_package(NSIGHT)
if (NSIGHT_FOUND)
include_directories(${NSIGHT_INCLUDE_DIRS})
add_definitions(-DNSIGHT_FOUND)
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
endif ()
endif()
# target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib)
target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib)
else (WIN32)
# Nothing else required on linux apparently
endif()
endif (APPLE)

View file

@ -772,8 +772,9 @@ void Application::initializeGL() {
}
#endif
// Where the gpuContext is created and where the TRUE Backend is created and assigned
_gpuContext = std::make_shared<gpu::Context>(new gpu::GLBackend());
// Where the gpuContext is initialized and where the TRUE Backend is created and assigned
gpu::Context::init<gpu::GLBackend>();
_gpuContext = std::make_shared<gpu::Context>();
initDisplay();
qCDebug(interfaceapp, "Initialized Display.");
@ -3757,10 +3758,13 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>().data());
scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("DialogsManager", _dialogsManagerScriptingInterface);
scriptEngine->registerGlobalObject("GlobalServices", GlobalServicesScriptingInterface::getInstance());
qScriptRegisterMetaType(scriptEngine, DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue);
scriptEngine->registerGlobalObject("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get<AvatarManager>().data());
qScriptRegisterMetaType(scriptEngine, joystickToScriptValue, joystickFromScriptValue);

View file

@ -49,6 +49,7 @@
#include "avatar/MyAvatar.h"
#include "devices/SixenseManager.h"
#include "scripting/ControllerScriptingInterface.h"
#include "scripting/DialogsManagerScriptingInterface.h"
#include "scripting/WebWindowClass.h"
#include "ui/AudioStatsDialog.h"
#include "ui/BandwidthDialog.h"
@ -69,6 +70,7 @@
#include "UndoStackScriptingInterface.h"
#include "gpu/Context.h"
#include "render/Engine.h"
class QGLWidget;
@ -643,6 +645,8 @@ private:
ApplicationOverlay _applicationOverlay;
ApplicationCompositor _compositor;
int _numFramesSinceLastResize = 0;
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
};
#endif // hifi_Application_h

View file

@ -13,7 +13,6 @@
#define hifi_GLCanvas_h
#include <QDebug>
#include <gpu/GPUConfig.h>
#include <QGLWidget>
#include <QTimer>

View file

@ -14,8 +14,6 @@
#include <mutex>
#include <QElapsedTimer>
#include <gpu/GPUConfig.h>
#include <gpu/Batch.h>
#include <gpu/Context.h>
#include <NumericalConstants.h>
#include <DependencyManager.h>
@ -208,8 +206,6 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
batch._glUniform1f(_timeSlot, secs);
geometryCache->renderUnitCube(batch);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
static const size_t VERTEX_STRIDE = sizeof(StarVertex);
size_t offset = offsetof(StarVertex, position);
gpu::BufferView posView(vertexBuffer, offset, vertexBuffer->getSize(), VERTEX_STRIDE, positionElement);
@ -218,10 +214,11 @@ void Stars::render(RenderArgs* renderArgs, float alpha) {
// Render the stars
batch.setPipeline(_starsPipeline);
batch.setInputFormat(streamFormat);
batch.setInputBuffer(VERTICES_SLOT, posView);
batch.setInputBuffer(COLOR_SLOT, colView);
batch.draw(gpu::Primitive::POINTS, STARFIELD_NUM_STARS);
renderArgs->_context->render(batch);
}

View file

@ -169,9 +169,6 @@ public:
void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; }
AvatarMotionState* getMotionState() { return _motionState; }
signals:
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
protected:
SkeletonModel _skeletonModel;
glm::vec3 _skeletonOffset;

View file

@ -29,7 +29,6 @@
#include <udt/PacketHeaders.h>
#include <PathUtils.h>
#include <PerfStat.h>
#include <ShapeCollider.h>
#include <SharedUtil.h>
#include <TextRenderer3D.h>
#include <UserActivityLogger.h>
@ -104,7 +103,6 @@ MyAvatar::MyAvatar(RigPointer rig) :
_rig(rig),
_prevShouldDrawHead(true)
{
ShapeCollider::initDispatchTable();
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
_driveKeys[i] = 0.0f;
}

View file

@ -47,7 +47,6 @@ public:
bool isMuted() const { return _isMuted; }
void setIsMuted(bool isMuted) { _isMuted = isMuted; }
void toggleMute();
static float getEyeDeflection() { return _eyeDeflection.get(); }
static void setEyeDeflection(float eyeDeflection);
@ -57,6 +56,8 @@ signals:
public slots:
virtual void setEnabled(bool enabled) = 0;
void toggleMute();
bool getMuted() { return _isMuted; }
protected:
virtual ~FaceTracker() {};

View file

@ -11,16 +11,16 @@
//
#include "OculusManager.h"
#include <gpu/GPUConfig.h>
#include <glm/glm.hpp>
#include <QDesktopWidget>
#include <QGuiApplication>
#include <gpu/GPUConfig.h>
#include <QScreen>
#include <CursorManager.h>
#include <QOpenGLTimerQuery>
#include <QGLWidget>
#include <CursorManager.h>
#include <glm/glm.hpp>
#include <avatar/AvatarManager.h>
#include <avatar/MyAvatar.h>

View file

@ -9,13 +9,14 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "TV3DManager.h"
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "gpu/GLBackend.h"
#include "Application.h"
#include <RenderArgs.h>
#include "TV3DManager.h"
#include "Application.h"
#include "Menu.h"
int TV3DManager::_screenWidth = 1;
@ -63,6 +64,7 @@ void TV3DManager::setFrustum(Camera& whichCamera) {
}
void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int screenHeight) {
#ifdef THIS_CURRENTLY_BROKEN_WAITING_FOR_DISPLAY_PLUGINS
if (screenHeight == 0) {
screenHeight = 1; // prevent divide by 0
}
@ -72,6 +74,7 @@ void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int scre
setFrustum(whichCamera);
glViewport (0, 0, _screenWidth, _screenHeight); // sets drawing viewport
#endif
}
void TV3DManager::display(RenderArgs* renderArgs, Camera& whichCamera) {

View file

@ -17,6 +17,7 @@
#include <glm/glm.hpp>
class Camera;
class RenderArgs;
struct eyeFrustum {
double left;

View file

@ -57,7 +57,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
if (piggybackBytes) {
// construct a new packet from the piggybacked one
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[piggybackBytes]);
auto buffer = std::unique_ptr<char[]>(new char[piggybackBytes]);
memcpy(buffer.get(), packet->getPayload() + statsMessageLength, piggybackBytes);
auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, packet->getSenderSockAddr());

View file

@ -0,0 +1,26 @@
//
// DialogsManagerScriptingInterface.cpp
// interface/src/scripting
//
// Created by Zander Otavka on 7/17/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "DialogsManagerScriptingInterface.h"
#include <DependencyManager.h>
#include "ui/DialogsManager.h"
DialogsManagerScriptingInterface::DialogsManagerScriptingInterface() {
connect(DependencyManager::get<DialogsManager>().data(), &DialogsManager::addressBarToggled,
this, &DialogsManagerScriptingInterface::addressBarToggled);
}
void DialogsManagerScriptingInterface::toggleAddressBar() {
QMetaObject::invokeMethod(DependencyManager::get<DialogsManager>().data(),
"toggleAddressBar", Qt::QueuedConnection);
}

View file

@ -0,0 +1,29 @@
//
// DialogsManagerScriptingInterface.h
// interface/src/scripting
//
// Created by Zander Otavka on 7/17/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_DialogsManagerScriptInterface_h
#define hifi_DialogsManagerScriptInterface_h
#include <QObject>
class DialogsManagerScriptingInterface : public QObject {
Q_OBJECT
public:
DialogsManagerScriptingInterface();
public slots:
void toggleAddressBar();
signals:
void addressBarToggled();
};
#endif

View file

@ -36,6 +36,7 @@
void DialogsManager::toggleAddressBar() {
AddressBarDialog::toggle();
emit addressBarToggled();
}
void DialogsManager::toggleDiskCacheEditor() {

View file

@ -72,6 +72,9 @@ public slots:
// Application Update
void showUpdateDialog();
signals:
void addressBarToggled();
private slots:
void toggleToolWindow();
void hmdToolsClosed();

View file

@ -13,19 +13,25 @@
#include <QScriptValue>
#include <DeferredLightingEffect.h>
#include <DependencyManager.h>
#include <GeometryCache.h>
#include <gpu/Batch.h>
#include <GLMHelpers.h>
#include "Application.h"
#include "GeometryUtil.h"
QString const BillboardOverlay::TYPE = "billboard";
BillboardOverlay::BillboardOverlay() {
_isLoaded = false;
}
BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) :
Planar3DOverlay(billboardOverlay),
PanelAttachable(billboardOverlay),
_url(billboardOverlay->_url),
_texture(billboardOverlay->_texture),
_fromImage(billboardOverlay->_fromImage),
@ -33,6 +39,19 @@ BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) :
{
}
void BillboardOverlay::setTransforms(Transform& transform) {
PanelAttachable::setTransforms(transform);
if (_isFacingAvatar) {
glm::quat rotation = Application::getInstance()->getCamera()->getOrientation();
rotation *= glm::angleAxis(glm::pi<float>(), IDENTITY_UP);
setRotation(rotation);
}
}
void BillboardOverlay::update(float deltatime) {
setTransforms(_transform);
}
void BillboardOverlay::render(RenderArgs* args) {
if (!_texture) {
_isLoaded = true;
@ -43,15 +62,8 @@ void BillboardOverlay::render(RenderArgs* args) {
return;
}
glm::quat rotation;
if (_isFacingAvatar) {
// rotate about vertical to face the camera
rotation = args->_viewFrustum->getOrientation();
rotation *= glm::angleAxis(glm::pi<float>(), IDENTITY_UP);
rotation *= getRotation();
} else {
rotation = getRotation();
}
Q_ASSERT(args->_batch);
auto batch = args->_batch;
float imageWidth = _texture->getWidth();
float imageHeight = _texture->getHeight();
@ -86,25 +98,25 @@ void BillboardOverlay::render(RenderArgs* args) {
xColor color = getColor();
float alpha = getAlpha();
auto batch = args->_batch;
setTransforms(_transform);
Transform transform = _transform;
transform.postScale(glm::vec3(getDimensions(), 1.0f));
if (batch) {
Transform transform = _transform;
transform.postScale(glm::vec3(getDimensions(), 1.0f));
transform.setRotation(rotation);
batch->setModelTransform(transform);
batch->setResourceTexture(0, _texture->getGPUTexture());
DependencyManager::get<GeometryCache>()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha));
batch->setModelTransform(transform);
batch->setResourceTexture(0, _texture->getGPUTexture());
batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me
}
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(*batch, true, true, false, true);
DependencyManager::get<GeometryCache>()->renderQuad(
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)
);
batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me
}
void BillboardOverlay::setProperties(const QScriptValue &properties) {
Planar3DOverlay::setProperties(properties);
PanelAttachable::setProperties(properties);
QScriptValue urlValue = properties.property("url");
if (urlValue.isValid()) {
@ -161,7 +173,14 @@ QScriptValue BillboardOverlay::getProperty(const QString& property) {
if (property == "isFacingAvatar") {
return _isFacingAvatar;
}
if (property == "offsetPosition") {
return vec3toScriptValue(_scriptEngine, getOffsetPosition());
}
QScriptValue value = PanelAttachable::getProperty(_scriptEngine, property);
if (value.isValid()) {
return value;
}
return Planar3DOverlay::getProperty(property);
}
@ -175,15 +194,10 @@ void BillboardOverlay::setBillboardURL(const QString& url) {
}
bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
float& distance, BoxFace& face) {
float& distance, BoxFace& face) {
if (_texture && _texture->isLoaded()) {
glm::quat rotation = getRotation();
if (_isFacingAvatar) {
// rotate about vertical to face the camera
rotation = Application::getInstance()->getCamera()->getRotation();
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
}
// Make sure position and rotation is updated.
setTransforms(_transform);
// Produce the dimensions of the billboard based on the image's aspect ratio and the overlay's scale.
bool isNull = _fromImage.isNull();
@ -192,7 +206,7 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v
float maxSize = glm::max(width, height);
glm::vec2 dimensions = _dimensions * glm::vec2(width / maxSize, height / maxSize);
return findRayRectangleIntersection(origin, direction, rotation, getPosition(), dimensions, distance);
return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), dimensions, distance);
}
return false;

View file

@ -15,15 +15,21 @@
#include <TextureCache.h>
#include "Planar3DOverlay.h"
#include "PanelAttachable.h"
class BillboardOverlay : public Planar3DOverlay {
class BillboardOverlay : public Planar3DOverlay, public PanelAttachable {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
BillboardOverlay();
BillboardOverlay(const BillboardOverlay* billboardOverlay);
virtual void render(RenderArgs* args);
virtual void update(float deltatime);
// setters
void setURL(const QString& url);
void setIsFacingAvatar(bool isFacingAvatar) { _isFacingAvatar = isFacingAvatar; }
@ -36,9 +42,12 @@ public:
virtual BillboardOverlay* createClone() const;
protected:
virtual void setTransforms(Transform& transform);
private:
void setBillboardURL(const QString& url);
QString _url;
NetworkTexturePointer _texture;

View file

@ -15,6 +15,8 @@
#include <RegisteredMetaTypes.h>
QString const Circle3DOverlay::TYPE = "circle3d";
Circle3DOverlay::Circle3DOverlay() :
_startAt(0.0f),
_endAt(360.0f),
@ -119,19 +121,21 @@ void Circle3DOverlay::render(RenderArgs* args) {
float angle = startAt;
float angleInRadians = glm::radians(angle);
glm::vec2 firstInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 firstOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
points << firstInnerPoint << firstOuterPoint;
glm::vec2 mostRecentInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 mostRecentOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
while (angle < endAt) {
angleInRadians = glm::radians(angle);
glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
points << thisOuterPoint << thisInnerPoint;
points << mostRecentInnerPoint << mostRecentOuterPoint << thisOuterPoint; // first triangle
points << mostRecentInnerPoint << thisInnerPoint << thisOuterPoint; // second triangle
angle += SLICE_ANGLE;
mostRecentInnerPoint = thisInnerPoint;
mostRecentOuterPoint = thisOuterPoint;
}
// get the last slice portion....
@ -139,13 +143,14 @@ void Circle3DOverlay::render(RenderArgs* args) {
angleInRadians = glm::radians(angle);
glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
points << lastOuterPoint << lastInnerPoint;
points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle
points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle
geometryCache->updateVertices(_quadVerticesID, points, color);
}
geometryCache->renderVertices(batch, gpu::QUAD_STRIP, _quadVerticesID);
geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID);
} else {
if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {

View file

@ -18,6 +18,9 @@ class Circle3DOverlay : public Planar3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
Circle3DOverlay();
Circle3DOverlay(const Circle3DOverlay* circle3DOverlay);

View file

@ -19,6 +19,8 @@
#include <GeometryCache.h>
#include <DependencyManager.h>
QString const Cube3DOverlay::TYPE = "cube";
Cube3DOverlay::Cube3DOverlay(const Cube3DOverlay* cube3DOverlay) :
Volume3DOverlay(cube3DOverlay)
{

View file

@ -17,6 +17,9 @@ class Cube3DOverlay : public Volume3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
Cube3DOverlay() {}
Cube3DOverlay(const Cube3DOverlay* cube3DOverlay);

View file

@ -0,0 +1,197 @@
//
// FloatingUIPanel.cpp
// interface/src/ui/overlays
//
// Created by Zander Otavka on 7/2/15.
// 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
//
#include "FloatingUIPanel.h"
#include <QVariant>
#include <RegisteredMetaTypes.h>
#include <DependencyManager.h>
#include "avatar/AvatarManager.h"
#include "avatar/MyAvatar.h"
#include "Application.h"
#include "Base3DOverlay.h"
std::function<glm::vec3()> const FloatingUIPanel::AVATAR_POSITION = []() -> glm::vec3 {
return DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition();
};
std::function<glm::quat()> const FloatingUIPanel::AVATAR_ORIENTATION = []() -> glm::quat {
return DependencyManager::get<AvatarManager>()->getMyAvatar()->getOrientation() *
glm::angleAxis(glm::pi<float>(), IDENTITY_UP);
};
glm::vec3 FloatingUIPanel::getPosition() const {
return getOffsetRotation() * getOffsetPosition() + getAnchorPosition();
}
glm::quat FloatingUIPanel::getRotation() const {
return getOffsetRotation() * getFacingRotation();
}
void FloatingUIPanel::setAnchorPosition(const glm::vec3& position) {
setAnchorPosition([position]() -> glm::vec3 {
return position;
});
}
void FloatingUIPanel::setOffsetRotation(const glm::quat& rotation) {
setOffsetRotation([rotation]() -> glm::quat {
return rotation;
});
}
void FloatingUIPanel::addChild(unsigned int childId) {
if (!_children.contains(childId)) {
_children.append(childId);
}
}
void FloatingUIPanel::removeChild(unsigned int childId) {
if (_children.contains(childId)) {
_children.removeOne(childId);
}
}
QScriptValue FloatingUIPanel::getProperty(const QString &property) {
if (property == "anchorPosition") {
return vec3toScriptValue(_scriptEngine, getAnchorPosition());
}
if (property == "offsetRotation") {
return quatToScriptValue(_scriptEngine, getOffsetRotation());
}
if (property == "offsetPosition") {
return vec3toScriptValue(_scriptEngine, getOffsetPosition());
}
if (property == "facingRotation") {
return quatToScriptValue(_scriptEngine, getFacingRotation());
}
return QScriptValue();
}
void FloatingUIPanel::setProperties(const QScriptValue &properties) {
QScriptValue anchor = properties.property("anchorPosition");
if (anchor.isValid()) {
QScriptValue bindType = anchor.property("bind");
QScriptValue value = anchor.property("value");
if (bindType.isValid()) {
QString bindTypeString = bindType.toVariant().toString();
if (bindTypeString == "myAvatar") {
setAnchorPosition(AVATAR_POSITION);
} else if (value.isValid()) {
if (bindTypeString == "overlay") {
Overlay::Pointer overlay = Application::getInstance()->getOverlays()
.getOverlay(value.toVariant().toUInt());
if (overlay->is3D()) {
auto overlay3D = std::static_pointer_cast<Base3DOverlay>(overlay);
setAnchorPosition([&overlay3D]() -> glm::vec3 {
return overlay3D->getPosition();
});
}
} else if (bindTypeString == "panel") {
FloatingUIPanel::Pointer panel = Application::getInstance()->getOverlays()
.getPanel(value.toVariant().toUInt());
setAnchorPosition([panel]() -> glm::vec3 {
return panel->getPosition();
});
} else if (bindTypeString == "vec3") {
QScriptValue x = value.property("x");
QScriptValue y = value.property("y");
QScriptValue z = value.property("z");
if (x.isValid() && y.isValid() && z.isValid()) {
glm::vec3 newPosition;
newPosition.x = x.toVariant().toFloat();
newPosition.y = y.toVariant().toFloat();
newPosition.z = z.toVariant().toFloat();
setAnchorPosition(newPosition);
}
}
}
}
}
QScriptValue offsetRotation = properties.property("offsetRotation");
if (offsetRotation.isValid()) {
QScriptValue bindType = offsetRotation.property("bind");
QScriptValue value = offsetRotation.property("value");
if (bindType.isValid()) {
QString bindTypeString = bindType.toVariant().toString();
if (bindTypeString == "myAvatar") {
setOffsetRotation(AVATAR_ORIENTATION);
} else if (value.isValid()) {
if (bindTypeString == "overlay") {
Overlay::Pointer overlay = Application::getInstance()->getOverlays()
.getOverlay(value.toVariant().toUInt());
if (overlay->is3D()) {
auto overlay3D = std::static_pointer_cast<Base3DOverlay>(overlay);
setOffsetRotation([&overlay3D]() -> glm::quat {
return overlay3D->getRotation();
});
}
} else if (bindTypeString == "panel") {
FloatingUIPanel::Pointer panel = Application::getInstance()->getOverlays()
.getPanel(value.toVariant().toUInt());
setOffsetRotation([panel]() -> glm::quat {
return panel->getRotation();
});
} else if (bindTypeString == "quat") {
QScriptValue x = value.property("x");
QScriptValue y = value.property("y");
QScriptValue z = value.property("z");
QScriptValue w = value.property("w");
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
glm::quat newRotation;
newRotation.x = x.toVariant().toFloat();
newRotation.y = y.toVariant().toFloat();
newRotation.z = z.toVariant().toFloat();
newRotation.w = w.toVariant().toFloat();
setOffsetRotation(newRotation);
}
}
}
}
}
QScriptValue offsetPosition = properties.property("offsetPosition");
if (offsetPosition.isValid()) {
QScriptValue x = offsetPosition.property("x");
QScriptValue y = offsetPosition.property("y");
QScriptValue z = offsetPosition.property("z");
if (x.isValid() && y.isValid() && z.isValid()) {
glm::vec3 newPosition;
newPosition.x = x.toVariant().toFloat();
newPosition.y = y.toVariant().toFloat();
newPosition.z = z.toVariant().toFloat();
setOffsetPosition(newPosition);
}
}
QScriptValue facingRotation = properties.property("facingRotation");
if (facingRotation.isValid()) {
QScriptValue x = facingRotation.property("x");
QScriptValue y = facingRotation.property("y");
QScriptValue z = facingRotation.property("z");
QScriptValue w = facingRotation.property("w");
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
glm::quat newRotation;
newRotation.x = x.toVariant().toFloat();
newRotation.y = y.toVariant().toFloat();
newRotation.z = z.toVariant().toFloat();
newRotation.w = w.toVariant().toFloat();
setFacingRotation(newRotation);
}
}
}

View file

@ -0,0 +1,63 @@
//
// FloatingUIPanel.h
// interface/src/ui/overlays
//
// Created by Zander Otavka on 7/2/15.
// 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 hifi_FloatingUIPanel_h
#define hifi_FloatingUIPanel_h
#include <functional>
#include <memory>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <QScriptValue>
class FloatingUIPanel : public QObject {
Q_OBJECT
public:
typedef std::shared_ptr<FloatingUIPanel> Pointer;
void init(QScriptEngine* scriptEngine) { _scriptEngine = scriptEngine; }
glm::vec3 getAnchorPosition() const { return _anchorPosition(); }
glm::quat getOffsetRotation() const { return _offsetRotation(); }
glm::vec3 getOffsetPosition() const { return _offsetPosition; }
glm::quat getFacingRotation() const { return _facingRotation; }
glm::vec3 getPosition() const;
glm::quat getRotation() const;
void setAnchorPosition(const std::function<glm::vec3()>& func) { _anchorPosition = func; }
void setAnchorPosition(const glm::vec3& position);
void setOffsetRotation(const std::function<glm::quat()>& func) { _offsetRotation = func; }
void setOffsetRotation(const glm::quat& rotation);
void setOffsetPosition(const glm::vec3& position) { _offsetPosition = position; }
void setFacingRotation(const glm::quat& rotation) { _facingRotation = rotation; }
const QList<unsigned int>& getChildren() { return _children; }
void addChild(unsigned int childId);
void removeChild(unsigned int childId);
unsigned int popLastChild() { return _children.takeLast(); }
QScriptValue getProperty(const QString& property);
void setProperties(const QScriptValue& properties);
private:
static std::function<glm::vec3()> const AVATAR_POSITION;
static std::function<glm::quat()> const AVATAR_ORIENTATION;
std::function<glm::vec3()> _anchorPosition{AVATAR_POSITION};
std::function<glm::quat()> _offsetRotation{AVATAR_ORIENTATION};
glm::vec3 _offsetPosition{0, 0, 0};
glm::quat _facingRotation{1, 0, 0, 0};
QScriptEngine* _scriptEngine;
QList<unsigned int> _children;
};
#endif // hifi_FloatingUIPanel_h

View file

@ -18,6 +18,9 @@
#include <PathUtils.h>
#include <ViewFrustum.h>
QString const Grid3DOverlay::TYPE = "grid";
Grid3DOverlay::Grid3DOverlay() :
_minorGridWidth(1.0),
_majorGridEvery(5) {

View file

@ -18,6 +18,9 @@ class Grid3DOverlay : public Planar3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
Grid3DOverlay();
Grid3DOverlay(const Grid3DOverlay* grid3DOverlay);

View file

@ -16,6 +16,9 @@
#include <gpu/StandardShaderLib.h>
#include <RegisteredMetaTypes.h>
QString const ImageOverlay::TYPE = "image";
ImageOverlay::ImageOverlay() :
_imageURL(),
_renderImage(false),

View file

@ -24,6 +24,9 @@ class ImageOverlay : public Overlay2D {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
ImageOverlay();
ImageOverlay(const ImageOverlay* imageOverlay);

View file

@ -13,6 +13,9 @@
#include <GeometryCache.h>
#include <RegisteredMetaTypes.h>
QString const Line3DOverlay::TYPE = "line3d";
Line3DOverlay::Line3DOverlay() :
_geometryCacheID(DependencyManager::get<GeometryCache>()->allocateID())
{

View file

@ -17,6 +17,9 @@ class Line3DOverlay : public Base3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
Line3DOverlay();
Line3DOverlay(const Line3DOverlay* line3DOverlay);
~Line3DOverlay();

View file

@ -14,6 +14,9 @@
#include <EntityTreeRenderer.h>
#include <gpu/Batch.h>
QString const LocalModelsOverlay::TYPE = "localmodels";
LocalModelsOverlay::LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer) :
Volume3DOverlay(),
_entityTreeRenderer(entityTreeRenderer) {

View file

@ -19,6 +19,9 @@ class EntityTreeRenderer;
class LocalModelsOverlay : public Volume3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer);
LocalModelsOverlay(const LocalModelsOverlay* localModelsOverlay);

View file

@ -10,11 +10,15 @@
//
#include "ModelOverlay.h"
#include "EntityRig.h"
#include "Application.h"
QString const ModelOverlay::TYPE = "model";
ModelOverlay::ModelOverlay()
: _model(nullptr),
: _model(std::make_shared<EntityRig>()),
_modelTextures(QVariantMap()),
_updateModel(false)
{
@ -24,7 +28,7 @@ ModelOverlay::ModelOverlay()
ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) :
Volume3DOverlay(modelOverlay),
_model(nullptr),
_model(std::make_shared<EntityRig>()),
_modelTextures(QVariantMap()),
_url(modelOverlay->_url),
_updateModel(false)

View file

@ -19,6 +19,9 @@
class ModelOverlay : public Volume3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
ModelOverlay();
ModelOverlay(const ModelOverlay* modelOverlay);

View file

@ -110,7 +110,8 @@ void Overlay::setProperties(const QScriptValue& properties) {
}
if (properties.property("visible").isValid()) {
setVisible(properties.property("visible").toVariant().toBool());
bool visible = properties.property("visible").toVariant().toBool();
setVisible(visible);
}
if (properties.property("anchor").isValid()) {

View file

@ -44,6 +44,7 @@ public:
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
// getters
virtual QString getType() const = 0;
virtual bool is3D() const = 0;
bool isLoaded() { return _isLoaded; }
bool getVisible() const { return _visible; }

View file

@ -48,6 +48,7 @@ Overlays::~Overlays() {
}
_overlaysHUD.clear();
_overlaysWorld.clear();
_panels.clear();
}
cleanupOverlaysToDelete();
@ -124,85 +125,84 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
}
}
unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) {
unsigned int thisID = 0;
Overlay* thisOverlay = NULL;
bool created = true;
if (type == "image") {
thisOverlay = new ImageOverlay();
} else if (type == "text") {
thisOverlay = new TextOverlay();
} else if (type == "text3d") {
thisOverlay = new Text3DOverlay();
} else if (type == "cube") {
thisOverlay = new Cube3DOverlay();
} else if (type == "sphere") {
thisOverlay = new Sphere3DOverlay();
} else if (type == "circle3d") {
thisOverlay = new Circle3DOverlay();
} else if (type == "rectangle3d") {
thisOverlay = new Rectangle3DOverlay();
} else if (type == "line3d") {
thisOverlay = new Line3DOverlay();
} else if (type == "grid") {
thisOverlay = new Grid3DOverlay();
} else if (type == "localmodels") {
thisOverlay = new LocalModelsOverlay(Application::getInstance()->getEntityClipboardRenderer());
} else if (type == "model") {
thisOverlay = new ModelOverlay();
} else if (type == "billboard") {
thisOverlay = new BillboardOverlay();
} else {
created = false;
Overlay::Pointer Overlays::getOverlay(unsigned int id) const {
if (_overlaysHUD.contains(id)) {
return _overlaysHUD[id];
}
if (created) {
thisOverlay->setProperties(properties);
thisID = addOverlay(thisOverlay);
if (_overlaysWorld.contains(id)) {
return _overlaysWorld[id];
}
return thisID;
return nullptr;
}
unsigned int Overlays::addOverlay(Overlay* overlay) {
Overlay::Pointer overlayPointer(overlay);
unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) {
Overlay::Pointer thisOverlay = nullptr;
if (type == ImageOverlay::TYPE) {
thisOverlay = std::make_shared<ImageOverlay>();
} else if (type == TextOverlay::TYPE) {
thisOverlay = std::make_shared<TextOverlay>();
} else if (type == Text3DOverlay::TYPE) {
thisOverlay = std::make_shared<Text3DOverlay>();
} else if (type == Cube3DOverlay::TYPE) {
thisOverlay = std::make_shared<Cube3DOverlay>();
} else if (type == Sphere3DOverlay::TYPE) {
thisOverlay = std::make_shared<Sphere3DOverlay>();
} else if (type == Circle3DOverlay::TYPE) {
thisOverlay = std::make_shared<Circle3DOverlay>();
} else if (type == Rectangle3DOverlay::TYPE) {
thisOverlay = std::make_shared<Rectangle3DOverlay>();
} else if (type == Line3DOverlay::TYPE) {
thisOverlay = std::make_shared<Line3DOverlay>();
} else if (type == Grid3DOverlay::TYPE) {
thisOverlay = std::make_shared<Grid3DOverlay>();
} else if (type == LocalModelsOverlay::TYPE) {
thisOverlay = std::make_shared<LocalModelsOverlay>(Application::getInstance()->getEntityClipboardRenderer());
} else if (type == ModelOverlay::TYPE) {
thisOverlay = std::make_shared<ModelOverlay>();
} else if (type == BillboardOverlay::TYPE) {
thisOverlay = std::make_shared<BillboardOverlay>();
}
if (thisOverlay) {
thisOverlay->setProperties(properties);
return addOverlay(thisOverlay);
}
return 0;
}
unsigned int Overlays::addOverlay(Overlay::Pointer overlay) {
overlay->init(_scriptEngine);
QWriteLocker lock(&_lock);
unsigned int thisID = _nextOverlayID;
_nextOverlayID++;
if (overlay->is3D()) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(overlay);
auto overlay3D = std::static_pointer_cast<Base3DOverlay>(overlay);
if (overlay3D->getDrawOnHUD()) {
_overlaysHUD[thisID] = overlayPointer;
_overlaysHUD[thisID] = overlay;
} else {
_overlaysWorld[thisID] = overlayPointer;
_overlaysWorld[thisID] = overlay;
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
render::PendingChanges pendingChanges;
overlayPointer->addToScene(overlayPointer, scene, pendingChanges);
overlay->addToScene(overlay, scene, pendingChanges);
scene->enqueuePendingChanges(pendingChanges);
}
} else {
_overlaysHUD[thisID] = overlayPointer;
_overlaysHUD[thisID] = overlay;
}
return thisID;
}
unsigned int Overlays::cloneOverlay(unsigned int id) {
Overlay::Pointer thisOverlay = NULL;
if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id];
} else if (_overlaysWorld.contains(id)) {
thisOverlay = _overlaysWorld[id];
}
Overlay::Pointer thisOverlay = getOverlay(id);
if (thisOverlay) {
return addOverlay(thisOverlay->createClone());
return addOverlay(Overlay::Pointer(thisOverlay->createClone()));
}
return 0; // Not found
@ -210,14 +210,8 @@ unsigned int Overlays::cloneOverlay(unsigned int id) {
bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
QWriteLocker lock(&_lock);
Overlay::Pointer thisOverlay;
if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id];
} else if (_overlaysWorld.contains(id)) {
thisOverlay = _overlaysWorld[id];
}
Overlay::Pointer thisOverlay = getOverlay(id);
if (thisOverlay) {
if (thisOverlay->is3D()) {
auto overlay3D = std::static_pointer_cast<Base3DOverlay>(thisOverlay);
@ -258,8 +252,51 @@ void Overlays::deleteOverlay(unsigned int id) {
}
}
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(overlayToDelete);
if (attachable && attachable->getAttachedPanel()) {
attachable->getAttachedPanel()->removeChild(id);
attachable->setAttachedPanel(nullptr);
}
QWriteLocker lock(&_deleteLock);
_overlaysToDelete.push_back(overlayToDelete);
emit overlayDeleted(id);
}
QString Overlays::getOverlayType(unsigned int overlayId) const {
Overlay::Pointer overlay = getOverlay(overlayId);
if (overlay) {
return overlay->getType();
}
return "";
}
unsigned int Overlays::getAttachedPanel(unsigned int childId) const {
Overlay::Pointer overlay = getOverlay(childId);
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(overlay);
if (attachable) {
return _panels.key(attachable->getAttachedPanel());
}
return 0;
}
void Overlays::setAttachedPanel(unsigned int childId, unsigned int panelId) {
Overlay::Pointer overlay = getOverlay(childId);
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(overlay);
if (attachable) {
if (_panels.contains(panelId)) {
auto panel = _panels[panelId];
panel->addChild(childId);
attachable->setAttachedPanel(panel);
} else {
auto panel = attachable->getAttachedPanel();
if (panel) {
panel->removeChild(childId);
attachable->setAttachedPanel(nullptr);
}
}
}
}
unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
@ -302,13 +339,8 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& property) {
OverlayPropertyResult result;
Overlay::Pointer thisOverlay;
Overlay::Pointer thisOverlay = getOverlay(id);
QReadLocker lock(&_lock);
if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id];
} else if (_overlaysWorld.contains(id)) {
thisOverlay = _overlaysWorld[id];
}
if (thisOverlay) {
result.value = thisOverlay->getProperty(property);
}
@ -456,12 +488,8 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R
bool Overlays::isLoaded(unsigned int id) {
QReadLocker lock(&_lock);
Overlay::Pointer thisOverlay = NULL;
if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id];
} else if (_overlaysWorld.contains(id)) {
thisOverlay = _overlaysWorld[id];
} else {
Overlay::Pointer thisOverlay = getOverlay(id);
if (!thisOverlay) {
return false; // not found
}
return thisOverlay->isLoaded();
@ -483,3 +511,56 @@ QSizeF Overlays::textSize(unsigned int id, const QString& text) const {
}
return QSizeF(0.0f, 0.0f);
}
unsigned int Overlays::addPanel(FloatingUIPanel::Pointer panel) {
QWriteLocker lock(&_lock);
unsigned int thisID = _nextOverlayID;
_nextOverlayID++;
_panels[thisID] = panel;
return thisID;
}
unsigned int Overlays::addPanel(const QScriptValue& properties) {
FloatingUIPanel::Pointer panel = std::make_shared<FloatingUIPanel>();
panel->init(_scriptEngine);
panel->setProperties(properties);
return addPanel(panel);
}
void Overlays::editPanel(unsigned int panelId, const QScriptValue& properties) {
if (_panels.contains(panelId)) {
_panels[panelId]->setProperties(properties);
}
}
OverlayPropertyResult Overlays::getPanelProperty(unsigned int panelId, const QString& property) {
OverlayPropertyResult result;
if (_panels.contains(panelId)) {
FloatingUIPanel::Pointer thisPanel = _panels[panelId];
QReadLocker lock(&_lock);
result.value = thisPanel->getProperty(property);
}
return result;
}
void Overlays::deletePanel(unsigned int panelId) {
FloatingUIPanel::Pointer panelToDelete;
{
QWriteLocker lock(&_lock);
if (_panels.contains(panelId)) {
panelToDelete = _panels.take(panelId);
} else {
return;
}
}
while (!panelToDelete->getChildren().isEmpty()) {
deleteOverlay(panelToDelete->popLastChild());
}
emit panelDeleted(panelId);
}

View file

@ -2,8 +2,14 @@
// Overlays.h
// interface/src/ui/overlays
//
// Modified by Zander Otavka on 7/15/15
// Copyright 2014 High Fidelity, Inc.
//
// Exposes methods for managing `Overlay`s and `FloatingUIPanel`s to scripts.
//
// YOU SHOULD NOT USE `Overlays` DIRECTLY, unless you like pain and deprecation. Instead, use the
// object oriented abstraction layer found in `examples/libraries/overlayUtils.js`.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
@ -16,6 +22,9 @@
#include "Overlay.h"
#include "FloatingUIPanel.h"
#include "PanelAttachable.h"
class PickRay;
class OverlayPropertyResult {
@ -57,12 +66,16 @@ public:
void update(float deltatime);
void renderHUD(RenderArgs* renderArgs);
Overlay::Pointer getOverlay(unsigned int id) const;
FloatingUIPanel::Pointer getPanel(unsigned int id) const { return _panels[id]; }
public slots:
/// adds an overlay with the specific properties
unsigned int addOverlay(const QString& type, const QScriptValue& properties);
/// adds an overlay that's already been created
unsigned int addOverlay(Overlay* overlay);
unsigned int addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); }
unsigned int addOverlay(Overlay::Pointer overlay);
/// clones an existing overlay
unsigned int cloneOverlay(unsigned int id);
@ -74,6 +87,12 @@ public slots:
/// deletes a particle
void deleteOverlay(unsigned int id);
/// get the string type of the overlay used in addOverlay
QString getOverlayType(unsigned int overlayId) const;
unsigned int getAttachedPanel(unsigned int childId) const;
void setAttachedPanel(unsigned int childId, unsigned int panelId);
/// returns the top most 2D overlay at the screen point, or 0 if not overlay at that point
unsigned int getOverlayAtPoint(const glm::vec2& point);
@ -90,12 +109,35 @@ public slots:
/// overlay; in meters if it is a 3D text overlay
QSizeF textSize(unsigned int id, const QString& text) const;
/// adds a panel that has already been created
unsigned int addPanel(FloatingUIPanel::Pointer panel);
/// creates and adds a panel based on a set of properties
unsigned int addPanel(const QScriptValue& properties);
/// edit the properties of a panel
void editPanel(unsigned int panelId, const QScriptValue& properties);
/// get a property of a panel
OverlayPropertyResult getPanelProperty(unsigned int panelId, const QString& property);
/// deletes a panel and all child overlays
void deletePanel(unsigned int panelId);
signals:
void overlayDeleted(unsigned int id);
void panelDeleted(unsigned int id);
private:
void cleanupOverlaysToDelete();
QMap<unsigned int, Overlay::Pointer> _overlaysHUD;
QMap<unsigned int, Overlay::Pointer> _overlaysWorld;
QMap<unsigned int, FloatingUIPanel::Pointer> _panels;
QList<Overlay::Pointer> _overlaysToDelete;
unsigned int _nextOverlayID;
QReadWriteLock _lock;
QReadWriteLock _deleteLock;
QScriptEngine* _scriptEngine;

View file

@ -0,0 +1,80 @@
//
// PanelAttachable.cpp
// hifi
//
// Created by Zander Otavka on 7/15/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "PanelAttachable.h"
#include <RegisteredMetaTypes.h>
PanelAttachable::PanelAttachable() :
_attachedPanel(nullptr),
_facingRotation(1, 0, 0, 0)
{
}
PanelAttachable::PanelAttachable(const PanelAttachable* panelAttachable) :
_attachedPanel(panelAttachable->_attachedPanel),
_offsetPosition(panelAttachable->_offsetPosition),
_facingRotation(panelAttachable->_facingRotation)
{
}
void PanelAttachable::setTransforms(Transform& transform) {
if (getAttachedPanel()) {
transform.setTranslation(getAttachedPanel()->getAnchorPosition());
transform.setRotation(getAttachedPanel()->getOffsetRotation());
transform.postTranslate(getOffsetPosition() + getAttachedPanel()->getOffsetPosition());
transform.postRotate(getFacingRotation() * getAttachedPanel()->getFacingRotation());
}
}
QScriptValue PanelAttachable::getProperty(QScriptEngine* scriptEngine, const QString &property) {
if (property == "offsetPosition") {
return vec3toScriptValue(scriptEngine, getOffsetPosition());
}
if (property == "facingRotation") {
return quatToScriptValue(scriptEngine, getFacingRotation());
}
return QScriptValue();
}
void PanelAttachable::setProperties(const QScriptValue &properties) {
QScriptValue offsetPosition = properties.property("offsetPosition");
if (offsetPosition.isValid()) {
QScriptValue x = offsetPosition.property("x");
QScriptValue y = offsetPosition.property("y");
QScriptValue z = offsetPosition.property("z");
if (x.isValid() && y.isValid() && z.isValid()) {
glm::vec3 newPosition;
newPosition.x = x.toVariant().toFloat();
newPosition.y = y.toVariant().toFloat();
newPosition.z = z.toVariant().toFloat();
setOffsetPosition(newPosition);
}
}
QScriptValue facingRotation = properties.property("facingRotation");
if (facingRotation.isValid()) {
QScriptValue x = facingRotation.property("x");
QScriptValue y = facingRotation.property("y");
QScriptValue z = facingRotation.property("z");
QScriptValue w = facingRotation.property("w");
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
glm::quat newRotation;
newRotation.x = x.toVariant().toFloat();
newRotation.y = y.toVariant().toFloat();
newRotation.z = z.toVariant().toFloat();
newRotation.w = w.toVariant().toFloat();
setFacingRotation(newRotation);
}
}
}

View file

@ -0,0 +1,45 @@
//
// PanelAttachable.h
// interface/src/ui/overlays
//
// Created by Zander Otavka on 7/1/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_PanelAttachable_h
#define hifi_PanelAttachable_h
#include "FloatingUIPanel.h"
#include <glm/glm.hpp>
#include <Transform.h>
class PanelAttachable {
public:
PanelAttachable();
PanelAttachable(const PanelAttachable* panelAttachable);
FloatingUIPanel::Pointer getAttachedPanel() const { return _attachedPanel; }
glm::vec3 getOffsetPosition() const { return _offsetPosition; }
glm::quat getFacingRotation() const { return _facingRotation; }
void setAttachedPanel(FloatingUIPanel::Pointer panel) { _attachedPanel = panel; }
void setOffsetPosition(const glm::vec3& position) { _offsetPosition = position; }
void setFacingRotation(const glm::quat& rotation) { _facingRotation = rotation; }
QScriptValue getProperty(QScriptEngine* scriptEngine, const QString& property);
void setProperties(const QScriptValue& properties);
protected:
virtual void setTransforms(Transform& transform);
private:
FloatingUIPanel::Pointer _attachedPanel;
glm::vec3 _offsetPosition;
glm::quat _facingRotation;
};
#endif // hifi_PanelAttachable_h

View file

@ -14,8 +14,15 @@
#include <GeometryUtil.h>
#include <RegisteredMetaTypes.h>
Planar3DOverlay::Planar3DOverlay() :
Base3DOverlay(),
_dimensions{1.0f, 1.0f}
{
}
Planar3DOverlay::Planar3DOverlay(const Planar3DOverlay* planar3DOverlay) :
Base3DOverlay(planar3DOverlay)
Base3DOverlay(planar3DOverlay),
_dimensions(planar3DOverlay->_dimensions)
{
}

View file

@ -17,7 +17,7 @@ class Planar3DOverlay : public Base3DOverlay {
Q_OBJECT
public:
Planar3DOverlay() {}
Planar3DOverlay();
Planar3DOverlay(const Planar3DOverlay* planar3DOverlay);
AABox getBounds() const;
@ -32,7 +32,7 @@ public:
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face);
protected:
glm::vec2 _dimensions{1.0f, 1.0f};
glm::vec2 _dimensions;
};

View file

@ -13,6 +13,9 @@
#include <GeometryCache.h>
#include <SharedUtil.h>
QString const Rectangle3DOverlay::TYPE = "rectangle3d";
Rectangle3DOverlay::Rectangle3DOverlay() :
_geometryCacheID(DependencyManager::get<GeometryCache>()->allocateID())
{

View file

@ -17,6 +17,9 @@ class Rectangle3DOverlay : public Planar3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
Rectangle3DOverlay();
Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay);
~Rectangle3DOverlay();

View file

@ -15,6 +15,8 @@
#include <gpu/Batch.h>
#include <SharedUtil.h>
QString const Sphere3DOverlay::TYPE = "sphere";
Sphere3DOverlay::Sphere3DOverlay(const Sphere3DOverlay* Sphere3DOverlay) :
Volume3DOverlay(Sphere3DOverlay)
{

View file

@ -17,6 +17,9 @@ class Sphere3DOverlay : public Volume3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
Sphere3DOverlay() {}
Sphere3DOverlay(const Sphere3DOverlay* Sphere3DOverlay);

View file

@ -23,6 +23,8 @@ const int FIXED_FONT_POINT_SIZE = 40;
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 80.0f; // this is a ratio determined through experimentation
const float LINE_SCALE_RATIO = 1.2f;
QString const Text3DOverlay::TYPE = "text3d";
Text3DOverlay::Text3DOverlay() :
_backgroundColor(DEFAULT_BACKGROUND_COLOR),
_backgroundAlpha(DEFAULT_BACKGROUND_ALPHA),

View file

@ -21,6 +21,9 @@ class Text3DOverlay : public Planar3DOverlay {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
Text3DOverlay();
Text3DOverlay(const Text3DOverlay* text3DOverlay);
~Text3DOverlay();

View file

@ -78,6 +78,8 @@ QString toQmlColor(const glm::vec4& v) {
arg((int)(v.b * 255), 2, 16, QChar('0'));
}
QString const TextOverlay::TYPE = "text";
TextOverlay::TextOverlay() :
_backgroundColor(DEFAULT_BACKGROUND_COLOR),
_backgroundAlpha(DEFAULT_BACKGROUND_ALPHA),

View file

@ -29,6 +29,9 @@ class TextOverlay : public Overlay2D {
Q_OBJECT
public:
static QString const TYPE;
virtual QString getType() const { return TYPE; }
TextOverlay();
TextOverlay(const TextOverlay* textOverlay);
~TextOverlay();

View file

@ -58,15 +58,18 @@ void Rig::removeAnimationHandle(const AnimationHandlePointer& handle) {
void Rig::startAnimation(const QString& url, float fps, float priority,
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) {
//qCDebug(animation) << "startAnimation" << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints;
// This is different than startAnimationByRole, in which we use the existing values if the animation already exists.
// Here we reuse the animation handle if possible, but in any case, we set the values to those given (or defaulted).
AnimationHandlePointer handle = nullptr;
foreach (const AnimationHandlePointer& candidate, _animationHandles) {
if (candidate->getURL() == url) {
candidate->start();
return;
handle = candidate;
}
}
AnimationHandlePointer handle = createAnimationHandle();
handle->setURL(url);
if (!handle) {
handle = createAnimationHandle();
handle->setURL(url);
}
handle->setFPS(fps);
handle->setPriority(priority);
handle->setLoop(loop);
@ -90,8 +93,34 @@ void Rig::addAnimationByRole(const QString& role, const QString& url, float fps,
}
}
AnimationHandlePointer handle = createAnimationHandle();
QString standard = "";
if (url.isEmpty()) { // Default animations for fight club
const QString& base = "https://hifi-public.s3.amazonaws.com/ozan/";
if (role == "walk") {
standard = base + "support/FightClubBotTest1/Animations/standard_walk.fbx";
lastFrame = 60;
} else if (role == "leftTurn") {
standard = base + "support/FightClubBotTest1/Animations/left_turn_noHipRotation.fbx";
lastFrame = 29;
} else if (role == "rightTurn") {
standard = base + "support/FightClubBotTest1/Animations/right_turn_noHipRotation.fbx";
lastFrame = 31;
} else if (role == "leftStrafe") {
standard = base + "animations/fightclub_bot_anims/side_step_left_inPlace.fbx";
lastFrame = 31;
} else if (role == "rightStrafe") {
standard = base + "animations/fightclub_bot_anims/side_step_right_inPlace.fbx";
lastFrame = 31;
} else if (role == "idle") {
standard = base + "support/FightClubBotTest1/Animations/standard_idle.fbx";
fps = 25.0f;
}
if (!standard.isEmpty()) {
loop = true;
}
}
handle->setRole(role);
handle->setURL(url);
handle->setURL(url.isEmpty() ? standard : url);
handle->setFPS(fps);
handle->setPriority(priority);
handle->setLoop(loop);
@ -135,6 +164,14 @@ void Rig::addRunningAnimation(AnimationHandlePointer animationHandle) {
bool Rig::isRunningAnimation(AnimationHandlePointer animationHandle) {
return _runningAnimations.contains(animationHandle);
}
bool Rig::isRunningRole(const QString& role) { //obviously, there are more efficient ways to do this
for (auto animation : _runningAnimations) {
if (animation->getRole() == role) {
return true;
}
}
return false;
}
void Rig::deleteAnimations() {
for (auto animation : _animationHandles) {
@ -372,37 +409,38 @@ glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const {
}
void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation) {
if (_enableRig) {
glm::vec3 front = worldRotation * IDENTITY_FRONT;
float forwardSpeed = glm::dot(worldVelocity, front);
float rotationalSpeed = glm::angle(front, _lastFront) / deltaTime;
bool isWalking = std::abs(forwardSpeed) > 0.01f;
bool isTurning = std::abs(rotationalSpeed) > 0.5f;
// Crude, until we have blending:
isTurning = isTurning && !isWalking; // Only one of walk/turn, walk wins.
isTurning = false; // FIXME
bool isIdle = !isWalking && !isTurning;
auto singleRole = [](bool walking, bool turning, bool idling) {
return walking ? "walk" : (turning ? "turn" : (idling ? "idle" : ""));
};
QString toStop = singleRole(_isWalking && !isWalking, _isTurning && !isTurning, _isIdle && !isIdle);
if (!toStop.isEmpty()) {
//qCDebug(animation) << "isTurning" << isTurning << "fronts" << front << _lastFront << glm::angle(front, _lastFront) << rotationalSpeed;
stopAnimationByRole(toStop);
}
QString newRole = singleRole(isWalking && !_isWalking, isTurning && !_isTurning, isIdle && !_isIdle);
if (!newRole.isEmpty()) {
startAnimationByRole(newRole);
qCDebug(animation) << deltaTime << ":" << worldVelocity << "." << front << "=> " << forwardSpeed << newRole;
}
_lastPosition = worldPosition;
_lastFront = front;
_isWalking = isWalking;
_isTurning = isTurning;
_isIdle = isIdle;
if (!_enableRig) {
return;
}
bool isMoving = false;
glm::vec3 front = worldRotation * IDENTITY_FRONT;
float forwardSpeed = glm::dot(worldVelocity, front);
float rightLateralSpeed = glm::dot(worldVelocity, worldRotation * IDENTITY_RIGHT);
float rightTurningSpeed = glm::orientedAngle(front, _lastFront, IDENTITY_UP) / deltaTime;
auto updateRole = [&](const QString& role, bool isOn) {
isMoving = isMoving || isOn;
if (isOn) {
if (!isRunningRole(role)) {
qCDebug(animation) << "Rig STARTING" << role;
startAnimationByRole(role);
}
} else {
if (isRunningRole(role)) {
qCDebug(animation) << "Rig stopping" << role;
stopAnimationByRole(role);
}
}
};
updateRole("walk", std::abs(forwardSpeed) > 0.01f);
bool isTurning = std::abs(rightTurningSpeed) > 0.5f;
updateRole("rightTurn", isTurning && (rightTurningSpeed > 0));
updateRole("leftTurn", isTurning && (rightTurningSpeed < 0));
bool isStrafing = std::abs(rightLateralSpeed) > 0.01f;
updateRole("rightStrafe", isStrafing && (rightLateralSpeed > 0.0f));
updateRole("leftStrafe", isStrafing && (rightLateralSpeed < 0.0f));
updateRole("idle", !isMoving); // Must be last, as it makes isMoving bogus.
_lastFront = front;
_lastPosition = worldPosition;
}
void Rig::updateAnimations(float deltaTime, glm::mat4 parentTransform) {

View file

@ -75,6 +75,7 @@ public:
bool removeRunningAnimation(AnimationHandlePointer animationHandle);
void addRunningAnimation(AnimationHandlePointer animationHandle);
bool isRunningAnimation(AnimationHandlePointer animationHandle);
bool isRunningRole(const QString& role); // There can be multiple animations per role, so this is more general than isRunningAnimation.
const QList<AnimationHandlePointer>& getRunningAnimations() const { return _runningAnimations; }
void deleteAnimations();
const QList<AnimationHandlePointer>& getAnimationHandles() const { return _animationHandles; }
@ -179,9 +180,6 @@ public:
QList<AnimationHandlePointer> _runningAnimations;
bool _enableRig;
bool _isWalking;
bool _isTurning;
bool _isIdle;
glm::vec3 _lastFront;
glm::vec3 _lastPosition;
};

View file

@ -1037,9 +1037,14 @@ bool AudioClient::outputLocalInjector(bool isStereo, AudioInjector* injector) {
localOutput->moveToThread(injector->getLocalBuffer()->thread());
// have it be stopped when that local buffer is about to close
connect(localOutput, &QAudioOutput::stateChanged, this, &AudioClient::audioStateChanged);
connect(this, &AudioClient::audioFinished, localOutput, &QAudioOutput::stop);
connect(this, &AudioClient::audioFinished, injector, &AudioInjector::stop);
// We don't want to stop this localOutput and injector whenever this AudioClient singleton goes idle,
// only when the localOutput does. But the connection is to localOutput, so that it happens on the right thread.
connect(localOutput, &QAudioOutput::stateChanged, localOutput, [=](QAudio::State state) {
if (state == QAudio::IdleState) {
localOutput->stop();
injector->stop();
}
});
connect(injector->getLocalBuffer(), &QIODevice::aboutToClose, localOutput, &QAudioOutput::stop);
@ -1358,9 +1363,3 @@ void AudioClient::saveSettings() {
windowSecondsForDesiredReduction.set(_receivedAudioStream.getWindowSecondsForDesiredReduction());
repetitionWithFade.set(_receivedAudioStream.getRepetitionWithFade());
}
void AudioClient::audioStateChanged(QAudio::State state) {
if (state == QAudio::IdleState) {
emit audioFinished();
}
}

View file

@ -209,9 +209,6 @@ protected:
deleteLater();
}
private slots:
void audioStateChanged(QAudio::State state);
private:
void outputFormatChanged();

View file

@ -46,7 +46,6 @@ typedef unsigned long long quint64;
#include <QtScript/QScriptable>
#include <QReadWriteLock>
#include <CollisionInfo.h>
#include <NLPacket.h>
#include <Node.h>
#include <RegisteredMetaTypes.h>
@ -257,10 +256,6 @@ public:
const HeadData* getHeadData() const { return _headData; }
const HandData* getHandData() const { return _handData; }
virtual bool findSphereCollisions(const glm::vec3& particleCenter, float particleRadius, CollisionList& collisions) {
return false;
}
bool hasIdentityChangedAfterParsing(NLPacket& packet);
QByteArray identityByteArray();

View file

@ -35,7 +35,7 @@
#include <PolyVoxCore/Material.h>
#include "model/Geometry.h"
#include "gpu/GLBackend.h"
#include "gpu/Context.h"
#include "EntityTreeRenderer.h"
#include "RenderablePolyVoxEntityItem.h"

View file

@ -8,7 +8,6 @@
#include "RenderableWebEntityItem.h"
#include <gpu/GPUConfig.h>
#include <QMouseEvent>
#include <QQuickItem>
#include <QQuickWindow>
@ -24,7 +23,7 @@
#include <GLMHelpers.h>
#include <PathUtils.h>
#include <TextureCache.h>
#include <gpu/GLBackend.h>
#include <gpu/Context.h>
#include "EntityTreeRenderer.h"

View file

@ -18,7 +18,6 @@
#include <glm/glm.hpp>
#include <AnimationCache.h> // for Animation, AnimationCache, and AnimationPointer classes
#include <CollisionInfo.h>
#include <Octree.h> // for EncodeBitstreamParams class
#include <OctreeElement.h> // for OctreeElement::AppendState
#include <OctreePacketData.h>

View file

@ -114,7 +114,8 @@ _glowLevelChanged(false),
_localRenderAlphaChanged(false),
_defaultSettings(true),
_naturalDimensions(1.0f, 1.0f, 1.0f)
_naturalDimensions(1.0f, 1.0f, 1.0f),
_naturalPosition(0.0f, 0.0f, 0.0f)
{
}
@ -128,6 +129,11 @@ void EntityItemProperties::setSittingPoints(const QVector<SittingPoint>& sitting
}
}
void EntityItemProperties::calculateNaturalPosition(const glm::vec3& min, const glm::vec3& max) {
glm::vec3 halfDimension = (max - min) / 2.0f;
_naturalPosition = max - halfDimension;
}
bool EntityItemProperties::animationSettingsChanged() const {
return _animationSettingsChanged;
}
@ -378,6 +384,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(dimensions);
if (!skipDefaults) {
COPY_PROPERTY_TO_QSCRIPTVALUE(naturalDimensions); // gettable, but not settable
COPY_PROPERTY_TO_QSCRIPTVALUE(naturalPosition);
}
COPY_PROPERTY_TO_QSCRIPTVALUE(rotation);
COPY_PROPERTY_TO_QSCRIPTVALUE(velocity);

View file

@ -192,7 +192,10 @@ public:
const glm::vec3& getNaturalDimensions() const { return _naturalDimensions; }
void setNaturalDimensions(const glm::vec3& value) { _naturalDimensions = value; }
const glm::vec3& getNaturalPosition() const { return _naturalPosition; }
void calculateNaturalPosition(const glm::vec3& min, const glm::vec3& max);
const QStringList& getTextureNames() const { return _textureNames; }
void setTextureNames(const QStringList& value) { _textureNames = value; }
@ -232,6 +235,7 @@ private:
QVector<SittingPoint> _sittingPoints;
QStringList _textureNames;
glm::vec3 _naturalDimensions;
glm::vec3 _naturalPosition;
};
Q_DECLARE_METATYPE(EntityItemProperties);

View file

@ -118,6 +118,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
results.setSittingPoints(geometry->sittingPoints);
Extents meshExtents = geometry->getUnscaledMeshExtents();
results.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum);
results.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum);
}
}

View file

@ -16,7 +16,6 @@
#include <QtCore/QObject>
#include <CollisionInfo.h>
#include <DependencyManager.h>
#include <Octree.h>
#include <OctreeScriptingInterface.h>

View file

@ -15,7 +15,7 @@
#include <QDebug>
#include <ByteCountCoding.h>
#include <PlaneShape.h>
#include <GeometryUtil.h>
#include "EntityTree.h"
#include "EntityTreeElement.h"
@ -128,46 +128,13 @@ void TextEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
}
bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
void** intersectedObject, bool precisionPicking) const {
RayIntersectionInfo rayInfo;
rayInfo._rayStart = origin;
rayInfo._rayDirection = direction;
rayInfo._rayLength = std::numeric_limits<float>::max();
PlaneShape plane;
const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f);
glm::vec3 normal = getRotation() * UNROTATED_NORMAL;
plane.setNormal(normal);
plane.setPoint(getPosition()); // the position is definitely a point on our plane
bool intersects = plane.findRayIntersection(rayInfo);
if (intersects) {
glm::vec3 hitAt = origin + (direction * rayInfo._hitDistance);
// now we know the point the ray hit our plane
glm::mat4 rotation = glm::mat4_cast(getRotation());
glm::mat4 translation = glm::translate(getPosition());
glm::mat4 entityToWorldMatrix = translation * rotation;
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
glm::vec3 dimensions = getDimensions();
glm::vec3 registrationPoint = getRegistrationPoint();
glm::vec3 corner = -(dimensions * registrationPoint);
AABox entityFrameBox(corner, dimensions);
glm::vec3 entityFrameHitAt = glm::vec3(worldToEntityMatrix * glm::vec4(hitAt, 1.0f));
intersects = entityFrameBox.contains(entityFrameHitAt);
}
if (intersects) {
distance = rayInfo._hitDistance;
}
return intersects;
glm::vec3 dimensions = getDimensions();
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
glm::quat rotation = getRotation();
glm::vec3 position = getPosition() + rotation *
(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
return findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance);
}

View file

@ -13,7 +13,7 @@
#include <QDebug>
#include <ByteCountCoding.h>
#include <PlaneShape.h>
#include <GeometryUtil.h>
#include "EntityTree.h"
#include "EntityTreeElement.h"
@ -98,50 +98,17 @@ void WebEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitst
APPEND_ENTITY_PROPERTY(PROP_SOURCE_URL, _sourceUrl);
}
bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
void** intersectedObject, bool precisionPicking) const {
RayIntersectionInfo rayInfo;
rayInfo._rayStart = origin;
rayInfo._rayDirection = direction;
rayInfo._rayLength = std::numeric_limits<float>::max();
PlaneShape plane;
const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f);
glm::vec3 normal = getRotation() * UNROTATED_NORMAL;
plane.setNormal(normal);
plane.setPoint(getPosition()); // the position is definitely a point on our plane
bool intersects = plane.findRayIntersection(rayInfo);
if (intersects) {
glm::vec3 hitAt = origin + (direction * rayInfo._hitDistance);
// now we know the point the ray hit our plane
glm::mat4 rotation = glm::mat4_cast(getRotation());
glm::mat4 translation = glm::translate(getPosition());
glm::mat4 entityToWorldMatrix = translation * rotation;
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
glm::vec3 dimensions = getDimensions();
glm::vec3 registrationPoint = getRegistrationPoint();
glm::vec3 corner = -(dimensions * registrationPoint);
AABox entityFrameBox(corner, dimensions);
glm::vec3 entityFrameHitAt = glm::vec3(worldToEntityMatrix * glm::vec4(hitAt, 1.0f));
intersects = entityFrameBox.contains(entityFrameHitAt);
}
if (intersects) {
distance = rayInfo._hitDistance;
}
return intersects;
glm::vec3 dimensions = getDimensions();
glm::vec2 xyDimensions(dimensions.x, dimensions.y);
glm::quat rotation = getRotation();
glm::vec3 position = getPosition() + rotation *
(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
return findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance);
}
void WebEntityItem::setSourceUrl(const QString& value) {
if (_sourceUrl != value) {
_sourceUrl = value;

View file

@ -28,7 +28,6 @@
#include <GLMHelpers.h>
#include <NumericalConstants.h>
#include <OctalCode.h>
#include <Shape.h>
#include <gpu/Format.h>
#include <LogHandler.h>
@ -830,6 +829,56 @@ public:
std::vector<AttributeData> attributes;
};
gpu::BufferPointer FBXMeshPart::getTrianglesForQuads() const {
// if we've been asked for our triangulation of the original quads, but we don't yet have them
// then create them now.
if (!trianglesForQuadsAvailable) {
trianglesForQuadsAvailable = true;
quadsAsTrianglesIndicesBuffer = std::make_shared<gpu::Buffer>();
// QVector<int> quadIndices; // original indices from the FBX mesh
QVector<quint32> quadsAsTrianglesIndices; // triangle versions of quads converted when first needed
const int INDICES_PER_ORIGINAL_QUAD = 4;
const int INDICES_PER_TRIANGULATED_QUAD = 6;
int numberOfQuads = quadIndices.size() / INDICES_PER_ORIGINAL_QUAD;
quadsAsTrianglesIndices.resize(numberOfQuads * INDICES_PER_TRIANGULATED_QUAD);
int originalIndex = 0;
int triangulatedIndex = 0;
for (int fromQuad = 0; fromQuad < numberOfQuads; fromQuad++) {
int i0 = quadIndices[originalIndex + 0];
int i1 = quadIndices[originalIndex + 1];
int i2 = quadIndices[originalIndex + 2];
int i3 = quadIndices[originalIndex + 3];
// Sam's recommended triangle slices
// Triangle tri1 = { v0, v1, v3 };
// Triangle tri2 = { v1, v2, v3 };
// NOTE: Random guy on the internet's recommended triangle slices
// Triangle tri1 = { v0, v1, v2 };
// Triangle tri2 = { v2, v3, v0 };
quadsAsTrianglesIndices[triangulatedIndex + 0] = i0;
quadsAsTrianglesIndices[triangulatedIndex + 1] = i1;
quadsAsTrianglesIndices[triangulatedIndex + 2] = i3;
quadsAsTrianglesIndices[triangulatedIndex + 3] = i1;
quadsAsTrianglesIndices[triangulatedIndex + 4] = i2;
quadsAsTrianglesIndices[triangulatedIndex + 5] = i3;
originalIndex += INDICES_PER_ORIGINAL_QUAD;
triangulatedIndex += INDICES_PER_TRIANGULATED_QUAD;
}
trianglesForQuadsIndicesCount = INDICES_PER_TRIANGULATED_QUAD * numberOfQuads;
quadsAsTrianglesIndicesBuffer->append(quadsAsTrianglesIndices.size() * sizeof(quint32), (gpu::Byte*)quadsAsTrianglesIndices.data());
}
return quadsAsTrianglesIndicesBuffer;
}
void appendIndex(MeshData& data, QVector<int>& indices, int index) {
if (index >= data.polygonIndices.size()) {
return;
@ -1089,7 +1138,6 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) {
appendIndex(data, part.quadIndices, beginIndex++);
appendIndex(data, part.quadIndices, beginIndex++);
appendIndex(data, part.quadIndices, beginIndex++);
} else {
for (int nextIndex = beginIndex + 1;; ) {
appendIndex(data, part.triangleIndices, beginIndex);

View file

@ -105,9 +105,10 @@ public:
class FBXMeshPart {
public:
QVector<int> quadIndices;
QVector<int> triangleIndices;
QVector<int> quadIndices; // original indices from the FBX mesh
QVector<int> triangleIndices; // original indices from the FBX mesh
mutable gpu::BufferPointer quadsAsTrianglesIndicesBuffer;
glm::vec3 diffuseColor;
glm::vec3 specularColor;
glm::vec3 emissiveColor;
@ -122,6 +123,10 @@ public:
QString materialID;
model::MaterialPointer _material;
mutable bool trianglesForQuadsAvailable = false;
mutable int trianglesForQuadsIndicesCount = 0;
gpu::BufferPointer getTrianglesForQuads() const;
};
/// A single mesh (with optional blendshapes) extracted from an FBX document.

View file

@ -23,7 +23,6 @@
#include <NetworkAccessManager.h>
#include "FBXReader.h"
#include "OBJReader.h"
#include "Shape.h"
#include "ModelFormatLogging.h"

View file

@ -21,23 +21,26 @@ elseif (WIN32)
if (USE_NSIGHT)
# try to find the Nsight package and add it to the build if we find it
# note that this will also enable NSIGHT profilers in all the projects linking gpu
find_package(NSIGHT)
if (NSIGHT_FOUND)
include_directories(${NSIGHT_INCLUDE_DIRS})
add_definitions(-DNSIGHT_FOUND)
target_include_directories(${TARGET_NAME} PUBLIC ${NSIGHT_INCLUDE_DIRS})
target_compile_definitions(${TARGET_NAME} PUBLIC NSIGHT_FOUND)
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
endif ()
endif()
elseif (ANDROID)
target_link_libraries(${TARGET_NAME} "-lGLESv3" "-lEGL")
else ()
find_package(GLEW REQUIRED)
target_include_directories(${TARGET_NAME} PUBLIC ${GLEW_INCLUDE_DIRS})
find_package(OpenGL REQUIRED)
if (${OPENGL_INCLUDE_DIR})
include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}")
endif ()
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}")
target_include_directories(${TARGET_NAME} PUBLIC ${OPENGL_INCLUDE_DIR})
target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${OPENGL_LIBRARY}")
endif (APPLE)

View file

@ -8,13 +8,9 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <string.h>
#include "Batch.h"
#include "GPUConfig.h"
#include <QDebug>
#include <GLMHelpers.h>
#if defined(NSIGHT_FOUND)
#include "nvToolsExt.h"
@ -292,15 +288,3 @@ void Batch::resetStages() {
ADD_COMMAND(resetStages);
}
void push_back(Batch::Params& params, const vec3& v) {
params.push_back(v.x);
params.push_back(v.y);
params.push_back(v.z);
}
void push_back(Batch::Params& params, const vec4& v) {
params.push_back(v.x);
params.push_back(v.y);
params.push_back(v.z);
params.push_back(v.a);
}

View file

@ -21,10 +21,9 @@
<@def VERSION_HEADER #version 120
#extension GL_EXT_gpu_shader4 : enable@>
<@else@>
<@def GPU_FEATURE_PROFILE GPU_LEGACY@>
<@def GPU_TRANSFORM_PROFILE GPU_LEGACY@>
<@def VERSION_HEADER #version 120
#extension GL_EXT_gpu_shader4 : enable@>
<@def GPU_FEATURE_PROFILE GPU_CORE@>
<@def GPU_TRANSFORM_PROFILE GPU_CORE@>
<@def VERSION_HEADER #version 430 compatibility@>
<@endif@>
<@endif@>

View file

@ -10,13 +10,16 @@
//
#include "Context.h"
// this include should disappear! as soon as the gpu::Context is in place
#include "GLBackend.h"
using namespace gpu;
Context::Context(Backend* backend) :
_backend(backend) {
Context::CreateBackend Context::_createBackendCallback = nullptr;
Context::MakeProgram Context::_makeProgramCallback = nullptr;
std::once_flag Context::_initialized;
Context::Context() {
if (_createBackendCallback) {
_backend.reset(_createBackendCallback());
}
}
Context::Context(const Context& context) {
@ -26,8 +29,8 @@ Context::~Context() {
}
bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) {
if (shader.isProgram()) {
return GLBackend::makeProgram(shader, bindings);
if (shader.isProgram() && _makeProgramCallback) {
return _makeProgramCallback(shader, bindings);
}
return false;
}

View file

@ -12,6 +12,7 @@
#define hifi_gpu_Context_h
#include <assert.h>
#include <mutex>
#include "Batch.h"
@ -26,13 +27,12 @@ namespace gpu {
class Backend {
public:
virtual~ Backend() {};
virtual void render(Batch& batch) = 0;
virtual void syncCache() = 0;
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
class TransformObject {
public:
Mat4 _model;
@ -118,7 +118,21 @@ protected:
class Context {
public:
Context(Backend* backend);
typedef Backend* (*CreateBackend)();
typedef bool (*MakeProgram)(Shader& shader, const Shader::BindingSet& bindings);
// This one call must happen before any context is created or used (Shader::MakeProgram) in order to setup the Backend and any singleton data needed
template <class T>
static void init() {
std::call_once(_initialized, [] {
_createBackendCallback = T::createBackend;
_makeProgramCallback = T::makeProgram;
T::init();
});
}
Context();
~Context();
void render(Batch& batch);
@ -132,13 +146,17 @@ public:
protected:
Context(const Context& context);
std::unique_ptr<Backend> _backend;
// This function can only be called by "static Shader::makeProgram()"
// makeProgramShader(...) make a program shader ready to be used in a Batch.
// It compiles the sub shaders, link them and defines the Slots and their bindings.
// If the shader passed is not a program, nothing happens.
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings = Shader::BindingSet());
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings);
std::unique_ptr<Backend> _backend;
static CreateBackend _createBackendCallback;
static MakeProgram _makeProgramCallback;
static std::once_flag _initialized;
friend class Shader;
};

View file

@ -213,9 +213,6 @@ enum Primitive {
TRIANGLES,
TRIANGLE_STRIP,
TRIANGLE_FAN,
QUADS,
QUAD_STRIP,
NUM_PRIMITIVES,
};

View file

@ -8,9 +8,9 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <mutex>
#include "GPULogging.h"
#include "GLBackendShared.h"
#include <mutex>
#include <glm/gtc/type_ptr.hpp>
using namespace gpu;
@ -63,12 +63,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_glLineWidth),
};
GLBackend::GLBackend() :
_input(),
_transform(),
_pipeline(),
_output()
{
void GLBackend::init() {
static std::once_flag once;
std::call_once(once, [] {
qCDebug(gpulogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
@ -94,6 +89,13 @@ GLBackend::GLBackend() :
#endif
#if defined(Q_OS_LINUX)
GLenum err = glewInit();
if (GLEW_OK != err) {
/* Problem: glewInit failed, something is seriously wrong. */
qCDebug(gpulogging, "Error: %s\n", glewGetErrorString(err));
}
qCDebug(gpulogging, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
// TODO: Write the correct code for Linux...
/* if (wglewGetExtension("WGL_EXT_swap_control")) {
int swapInterval = wglGetSwapIntervalEXT();
@ -101,7 +103,18 @@ GLBackend::GLBackend() :
}*/
#endif
});
}
Backend* GLBackend::createBackend() {
return new GLBackend();
}
GLBackend::GLBackend() :
_input(),
_transform(),
_pipeline(),
_output()
{
initInput();
initTransform();
}

View file

@ -18,16 +18,21 @@
#include "GPUConfig.h"
#include "Context.h"
#include "Batch.h"
namespace gpu {
class GLBackend : public Backend {
public:
// Context Backend static interface required
friend class Context;
static void init();
static Backend* createBackend();
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings);
explicit GLBackend(bool syncCache);
GLBackend();
public:
virtual ~GLBackend();
virtual void render(Batch& batch);
@ -49,7 +54,6 @@ public:
static void checkGLStackStable(std::function<void()> f);
static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings = Shader::BindingSet());
class GLBuffer : public GPUObject {
@ -91,9 +95,9 @@ public:
#if (GPU_TRANSFORM_PROFILE == GPU_CORE)
#else
GLuint _transformObject_model = -1;
GLuint _transformCamera_viewInverse = -1;
GLuint _transformCamera_viewport = -1;
GLint _transformObject_model = -1;
GLint _transformCamera_viewInverse = -1;
GLint _transformCamera_viewport = -1;
#endif
GLShader();

View file

@ -8,7 +8,6 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "GPULogging.h"
#include "GLBackendShared.h"

View file

@ -8,7 +8,6 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "GPULogging.h"
#include "GLBackendShared.h"
#include "Format.h"
@ -542,7 +541,12 @@ ElementResource getFormatFromGLUniform(GLenum gltype) {
};
int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers) {
int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,
Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers
#if (GPU_FEATURE_PROFILE == GPU_LEGACY)
, Shader::SlotSet& fakeBuffers
#endif
) {
GLint uniformsCount = 0;
#if (GPU_FEATURE_PROFILE == GPU_LEGACY)
@ -583,6 +587,15 @@ int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, S
}
if (elementResource._resource == Resource::BUFFER) {
#if (GPU_FEATURE_PROFILE == GPU_LEGACY)
// if in legacy profile, we fake the uniform buffer with an array
// this is where we detect it assuming it's explicitely assinged a binding
auto requestedBinding = slotBindings.find(std::string(sname));
if (requestedBinding != slotBindings.end()) {
// found one buffer!
fakeBuffers.insert(Shader::Slot(sname, location, elementResource._element, elementResource._resource));
}
#endif
uniforms.insert(Shader::Slot(sname, location, elementResource._element, elementResource._resource));
} else {
// For texture/Sampler, the location is the actual binding value
@ -640,14 +653,13 @@ int makeUniformBlockSlots(GLuint glprogram, const Shader::BindingSet& slotBindin
GLchar name[NAME_LENGTH];
GLint length = 0;
GLint size = 0;
GLenum type = 0;
GLint binding = -1;
glGetActiveUniformBlockiv(glprogram, i, GL_UNIFORM_BLOCK_NAME_LENGTH, &length);
glGetActiveUniformBlockName(glprogram, i, NAME_LENGTH, &length, name);
glGetActiveUniformBlockiv(glprogram, i, GL_UNIFORM_BLOCK_BINDING, &binding);
glGetActiveUniformBlockiv(glprogram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &size);
GLuint blockIndex = glGetUniformBlockIndex(glprogram, name);
// CHeck if there is a requested binding for this block
@ -738,8 +750,12 @@ bool GLBackend::makeProgram(Shader& shader, const Shader::BindingSet& slotBindin
Shader::SlotSet uniforms;
Shader::SlotSet textures;
Shader::SlotSet samplers;
#if (GPU_FEATURE_PROFILE == GPU_CORE)
makeUniformSlots(object->_program, slotBindings, uniforms, textures, samplers);
#else
makeUniformSlots(object->_program, slotBindings, uniforms, textures, samplers, buffers);
#endif
Shader::SlotSet inputs;
makeInputSlots(object->_program, slotBindings, inputs);

View file

@ -11,11 +11,10 @@
#ifndef hifi_gpu_GLBackend_Shared_h
#define hifi_gpu_GLBackend_Shared_h
#include "GLBackend.h"
#include <QDebug>
#include "Batch.h"
#include "GPULogging.h"
#include "GLBackend.h"
static const GLenum _primitiveToGLmode[gpu::NUM_PRIMITIVES] = {
GL_POINTS,
@ -24,8 +23,6 @@ static const GLenum _primitiveToGLmode[gpu::NUM_PRIMITIVES] = {
GL_TRIANGLES,
GL_TRIANGLE_STRIP,
GL_TRIANGLE_FAN,
GL_QUADS,
GL_QUAD_STRIP,
};
static const GLenum _elementTypeToGLType[gpu::NUM_TYPES] = {

View file

@ -484,6 +484,7 @@ void GLBackend::syncPipelineStateCache() {
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
// Point size is always on
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glEnable(GL_PROGRAM_POINT_SIZE_EXT);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

View file

@ -34,11 +34,11 @@
#elif defined(ANDROID)
#else
#include <GL/gl.h>
#include <GL/glext.h>
#define GPU_FEATURE_PROFILE GPU_LEGACY
#define GPU_TRANSFORM_PROFILE GPU_LEGACY
#include <GL/glew.h>
#define GPU_FEATURE_PROFILE GPU_CORE
#define GPU_TRANSFORM_PROFILE GPU_CORE
#endif

View file

@ -71,7 +71,7 @@ public:
LINE_STRIP,
TRIANGLES,
TRIANGLE_STRIP,
QUADS,
QUADS, // NOTE: These must be translated to triangles before rendering
QUAD_STRIP,
NUM_TOPOLOGIES,

View file

@ -13,13 +13,13 @@
#include <bitset>
#include <map>
#include <qurl.h>
#include <glm/glm.hpp>
#include "gpu/Resource.h"
#include "gpu/Texture.h"
#include <qurl.h>
namespace model {

View file

@ -46,7 +46,7 @@ std::unique_ptr<NLPacket> NLPacket::create(PacketType::Value type, qint64 size)
return packet;
}
std::unique_ptr<NLPacket> NLPacket::fromReceivedPacket(std::unique_ptr<char> data, qint64 size,
std::unique_ptr<NLPacket> NLPacket::fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
const HifiSockAddr& senderSockAddr) {
// Fail with null data
Q_ASSERT(data);
@ -85,7 +85,7 @@ NLPacket::NLPacket(const NLPacket& other) : Packet(other) {
}
NLPacket::NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) :
NLPacket::NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) :
Packet(std::move(data), size, senderSockAddr)
{
adjustPayloadStartAndCapacity();

View file

@ -20,7 +20,7 @@ class NLPacket : public Packet {
Q_OBJECT
public:
static std::unique_ptr<NLPacket> create(PacketType::Value type, qint64 size = -1);
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char> data, qint64 size,
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
const HifiSockAddr& senderSockAddr);
// Provided for convenience, try to limit use
static std::unique_ptr<NLPacket> createCopy(const NLPacket& other);
@ -45,7 +45,7 @@ protected:
NLPacket(PacketType::Value type);
NLPacket(PacketType::Value type, qint64 size);
NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
NLPacket(const NLPacket& other);
void readSourceID();

View file

@ -243,7 +243,7 @@ void PacketReceiver::processDatagrams() {
while (nodeList && nodeList->getNodeSocket().hasPendingDatagrams()) {
// setup a buffer to read the packet into
int packetSizeWithHeader = nodeList->getNodeSocket().pendingDatagramSize();
std::unique_ptr<char> buffer = std::unique_ptr<char>(new char[packetSizeWithHeader]);
auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]);
// if we're supposed to drop this packet then break out here
if (_shouldDropPackets) {

View file

@ -31,7 +31,7 @@ std::unique_ptr<Packet> Packet::create(PacketType::Value type, qint64 size) {
return packet;
}
std::unique_ptr<Packet> Packet::fromReceivedPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) {
std::unique_ptr<Packet> Packet::fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) {
// Fail with invalid size
Q_ASSERT(size >= 0);
@ -82,7 +82,7 @@ Packet::Packet(PacketType::Value type, qint64 size) :
}
}
Packet::Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) :
Packet::Packet(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr) :
_packetSize(size),
_packet(std::move(data)),
_senderSockAddr(senderSockAddr)
@ -110,7 +110,7 @@ Packet& Packet::operator=(const Packet& other) {
_type = other._type;
_packetSize = other._packetSize;
_packet = std::unique_ptr<char>(new char[_packetSize]);
_packet = std::unique_ptr<char[]>(new char[_packetSize]);
memcpy(_packet.get(), other._packet.get(), _packetSize);
_payloadStart = _packet.get() + (other._payloadStart - other._packet.get());

View file

@ -27,7 +27,7 @@ public:
static const qint64 PACKET_WRITE_ERROR;
static std::unique_ptr<Packet> create(PacketType::Value type, qint64 size = -1);
static std::unique_ptr<Packet> fromReceivedPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
static std::unique_ptr<Packet> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
// Provided for convenience, try to limit use
static std::unique_ptr<Packet> createCopy(const Packet& other);
@ -88,7 +88,7 @@ public:
protected:
Packet(PacketType::Value type, qint64 size);
Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
Packet(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
Packet(const Packet& other);
Packet& operator=(const Packet& other);
Packet(Packet&& other);
@ -109,7 +109,7 @@ protected:
PacketVersion _version; // Packet version
qint64 _packetSize = 0; // Total size of the allocated memory
std::unique_ptr<char> _packet; // Allocated memory
std::unique_ptr<char[]> _packet; // Allocated memory
char* _payloadStart = nullptr; // Start of the payload
qint64 _payloadCapacity = 0; // Total capacity of the payload

View file

@ -38,7 +38,6 @@
#include <OctalCode.h>
#include <udt/PacketHeaders.h>
#include <SharedUtil.h>
#include <Shape.h>
#include <PathUtils.h>
#include "CoverageMap.h"
@ -791,13 +790,6 @@ public:
bool found;
};
class ShapeArgs {
public:
const Shape* shape;
CollisionList& collisions;
bool found;
};
class ContentArgs {
public:
AACube cube;

View file

@ -19,7 +19,6 @@
#include <LogHandler.h>
#include <NodeList.h>
#include <PerfStat.h>
#include <AACubeShape.h>
#include "AACube.h"
#include "OctalCode.h"
@ -640,50 +639,7 @@ OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float
// otherwise, we need to find which of our children we should recurse
glm::vec3 ourCenter = _cube.calcCenter();
int childIndex = CHILD_UNKNOWN;
// left half
if (x > ourCenter.x) {
if (y > ourCenter.y) {
// top left
if (z > ourCenter.z) {
// top left far
childIndex = CHILD_TOP_LEFT_FAR;
} else {
// top left near
childIndex = CHILD_TOP_LEFT_NEAR;
}
} else {
// bottom left
if (z > ourCenter.z) {
// bottom left far
childIndex = CHILD_BOTTOM_LEFT_FAR;
} else {
// bottom left near
childIndex = CHILD_BOTTOM_LEFT_NEAR;
}
}
} else {
// right half
if (y > ourCenter.y) {
// top right
if (z > ourCenter.z) {
// top right far
childIndex = CHILD_TOP_RIGHT_FAR;
} else {
// top right near
childIndex = CHILD_TOP_RIGHT_NEAR;
}
} else {
// bottom right
if (z > ourCenter.z) {
// bottom right far
childIndex = CHILD_BOTTOM_RIGHT_FAR;
} else {
// bottom right near
childIndex = CHILD_BOTTOM_RIGHT_NEAR;
}
}
}
int childIndex = getMyChildContainingPoint(glm::vec3(x, y, z));
// Now, check if we have a child at that location
child = getChildAtIndex(childIndex);

View file

@ -24,7 +24,6 @@
#include "ViewFrustum.h"
#include "OctreeConstants.h"
class CollisionList;
class EncodeBitstreamParams;
class Octree;
class OctreeElement;

Some files were not shown because too many files have changed in this diff Show more