mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 13:18:38 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
e079ec4363
30 changed files with 2146 additions and 1721 deletions
|
@ -237,8 +237,9 @@ void MetavoxelSession::update() {
|
||||||
|
|
||||||
// go back to the beginning with the current packet and note that there's a delta pending
|
// go back to the beginning with the current packet and note that there's a delta pending
|
||||||
_sequencer.getOutputStream().getUnderlying().device()->seek(start);
|
_sequencer.getOutputStream().getUnderlying().device()->seek(start);
|
||||||
MetavoxelDeltaPendingMessage msg = { ++_reliableDeltaID };
|
MetavoxelDeltaPendingMessage msg = { ++_reliableDeltaID, sendRecord->getPacketNumber(),
|
||||||
out << QVariant::fromValue(msg);
|
_sequencer.getIncomingPacketNumber() };
|
||||||
|
out << (_reliableDeltaMessage = QVariant::fromValue(msg));
|
||||||
_sequencer.endPacket();
|
_sequencer.endPacket();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -254,8 +255,9 @@ void MetavoxelSession::handleMessage(const QVariant& message, Bitstream& in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketRecord* MetavoxelSession::maybeCreateSendRecord() const {
|
PacketRecord* MetavoxelSession::maybeCreateSendRecord() const {
|
||||||
return _reliableDeltaChannel ? new PacketRecord(_reliableDeltaLOD, _reliableDeltaData) :
|
return _reliableDeltaChannel ? new PacketRecord(_sequencer.getOutgoingPacketNumber(),
|
||||||
new PacketRecord(_lod, _sender->getData());
|
_reliableDeltaLOD, _reliableDeltaData) : new PacketRecord(_sequencer.getOutgoingPacketNumber(),
|
||||||
|
_lod, _sender->getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSession::handleMessage(const QVariant& message) {
|
void MetavoxelSession::handleMessage(const QVariant& message) {
|
||||||
|
@ -290,8 +292,7 @@ void MetavoxelSession::sendPacketGroup(int alreadySent) {
|
||||||
for (int i = 0; i < additionalPackets; i++) {
|
for (int i = 0; i < additionalPackets; i++) {
|
||||||
Bitstream& out = _sequencer.startPacket();
|
Bitstream& out = _sequencer.startPacket();
|
||||||
if (_reliableDeltaChannel) {
|
if (_reliableDeltaChannel) {
|
||||||
MetavoxelDeltaPendingMessage msg = { _reliableDeltaID };
|
out << _reliableDeltaMessage;
|
||||||
out << QVariant::fromValue(msg);
|
|
||||||
} else {
|
} else {
|
||||||
out << QVariant();
|
out << QVariant();
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,7 @@ private:
|
||||||
MetavoxelLOD _reliableDeltaLOD;
|
MetavoxelLOD _reliableDeltaLOD;
|
||||||
Bitstream::WriteMappings _reliableDeltaWriteMappings;
|
Bitstream::WriteMappings _reliableDeltaWriteMappings;
|
||||||
int _reliableDeltaID;
|
int _reliableDeltaID;
|
||||||
|
QVariant _reliableDeltaMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Handles persistence in a separate thread.
|
/// Handles persistence in a separate thread.
|
||||||
|
|
|
@ -5,174 +5,181 @@
|
||||||
// Created by Philip Rosedale on September 8, 2014
|
// Created by Philip Rosedale on September 8, 2014
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Press the spacebar and move/turn your head to move around.
|
// Press the spacebar and then use your head to move and turn. Pull back to see your body.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
var debug = false;
|
var debug = false;
|
||||||
|
var willMove = false;
|
||||||
|
|
||||||
|
var warpActive = false;
|
||||||
|
var warpPosition = { x: 0, y: 0, z: 0 };
|
||||||
|
|
||||||
|
// Overlays to show target location
|
||||||
|
|
||||||
|
var WARP_SPHERE_SIZE = 0.15;
|
||||||
|
var warpSphere = Overlays.addOverlay("sphere", {
|
||||||
|
position: { x: 0, y: 0, z: 0 },
|
||||||
|
size: WARP_SPHERE_SIZE,
|
||||||
|
color: { red: 200, green: 0, blue: 0 },
|
||||||
|
alpha: 0.5,
|
||||||
|
solid: true,
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
var WARP_LINE_HEIGHT = 5;
|
||||||
|
var warpLine = Overlays.addOverlay("line3d", {
|
||||||
|
position: { x: 0, y: 0, z:0 },
|
||||||
|
end: { x: 0, y: 0, z: 0 },
|
||||||
|
color: { red: 0, green: 255, blue: 255},
|
||||||
|
alpha: 1,
|
||||||
|
lineWidth: 5,
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
|
||||||
var movingWithHead = false;
|
var movingWithHead = false;
|
||||||
var headStartPosition, headStartDeltaPitch, headStartFinalPitch, headStartRoll, headStartYaw;
|
var headStartPosition, headStartDeltaPitch, headStartFinalPitch, headStartRoll, headStartYaw;
|
||||||
|
var deltaYaw = 0.0;
|
||||||
|
var keyDownTime = 0.0;
|
||||||
|
var watchAvatar = false;
|
||||||
|
var oldMode;
|
||||||
|
|
||||||
var HEAD_MOVE_DEAD_ZONE = 0.05;
|
function saveCameraState() {
|
||||||
var HEAD_STRAFE_DEAD_ZONE = 0.03;
|
oldMode = Camera.getMode();
|
||||||
var HEAD_ROTATE_DEAD_ZONE = 10.0;
|
Camera.setMode("independent");
|
||||||
var HEAD_YAW_RATE = 1.5;
|
}
|
||||||
var HEAD_PITCH_RATE = 1.0;
|
|
||||||
var WALL_BOUNCE = 10000.0;
|
|
||||||
var FIXED_WALK_VELOCITY = 1.5;
|
|
||||||
|
|
||||||
// Modify these values to tweak the strength of the motion.
|
function restoreCameraState() {
|
||||||
// A larger *FACTOR increases the speed.
|
Camera.setMode(oldMode);
|
||||||
// A lower SHORT_TIMESCALE makes the motor achieve full speed faster.
|
}
|
||||||
var HEAD_VELOCITY_FWD_FACTOR = 10.0;
|
|
||||||
var HEAD_VELOCITY_LEFT_FACTOR = 0.0;
|
|
||||||
var HEAD_VELOCITY_UP_FACTOR = 20.0;
|
|
||||||
var SHORT_TIMESCALE = 0.01;
|
|
||||||
var VERY_LARGE_TIMESCALE = 1000000.0;
|
|
||||||
|
|
||||||
var xAxis = {x:1.0, y:0.0, z:0.0 };
|
function activateWarp() {
|
||||||
var yAxis = {x:0.0, y:1.0, z:0.0 };
|
if (warpActive) return;
|
||||||
var zAxis = {x:0.0, y:0.0, z:1.0 };
|
warpActive = true;
|
||||||
|
|
||||||
// If these values are set to something
|
updateWarp();
|
||||||
var maxVelocity = 1.25;
|
}
|
||||||
var noFly = true;
|
|
||||||
var fixedWalkVelocity = true;
|
|
||||||
|
|
||||||
//var roomLimits = { xMin: 618, xMax: 635.5, zMin: 528, zMax: 552.5 };
|
var TRIGGER_PULLBACK_DISTANCE = 0.04;
|
||||||
var roomLimits = { xMin: -1.0, xMax: -1.0, zMin: -1.0, zMax: -1.0 };
|
var WATCH_AVATAR_DISTANCE = 1.5;
|
||||||
|
var MAX_WARP_YAW = 40.0;
|
||||||
|
var MAX_PULLBACK_YAW = 5.0;
|
||||||
|
|
||||||
function isInRoom(position) {
|
var sound = new Sound("http://public.highfidelity.io/sounds/Footsteps/FootstepW2Right-12db.wav");
|
||||||
var BUFFER = 2.0;
|
function playSound() {
|
||||||
if (roomLimits.xMin < 0) {
|
var options = new AudioInjectionOptions();
|
||||||
return false;
|
var position = MyAvatar.position;
|
||||||
|
options.position = position;
|
||||||
|
options.volume = 0.5;
|
||||||
|
Audio.playSound(sound, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
var WARP_SMOOTHING = 0.90;
|
||||||
|
var WARP_START_TIME = 0.50;
|
||||||
|
var WARP_START_DISTANCE = 1.0;
|
||||||
|
var WARP_SENSITIVITY = 0.15;
|
||||||
|
|
||||||
|
function updateWarp() {
|
||||||
|
if (!warpActive) return;
|
||||||
|
|
||||||
|
var look = Quat.getFront(Camera.getOrientation());
|
||||||
|
var deltaPosition = Vec3.subtract(MyAvatar.getTrackedHeadPosition(), headStartPosition);
|
||||||
|
var deltaPitch = MyAvatar.getHeadFinalPitch() - headStartFinalPitch;
|
||||||
|
deltaYaw = MyAvatar.getHeadFinalYaw() - headStartYaw;
|
||||||
|
|
||||||
|
willMove = (!watchAvatar && (Math.abs(deltaYaw) < MAX_WARP_YAW) && (keyDownTime > WARP_START_TIME));
|
||||||
|
|
||||||
|
if (willMove) {
|
||||||
|
//var distance = Math.pow((deltaPitch - WARP_PITCH_DEAD_ZONE) * WARP_SENSITIVITY, 2.0);
|
||||||
|
var distance = Math.exp(deltaPitch * WARP_SENSITIVITY) * WARP_START_DISTANCE;
|
||||||
|
var warpDirection = Vec3.normalize({ x: look.x, y: 0, z: look.z });
|
||||||
|
warpPosition = Vec3.mix(Vec3.sum(MyAvatar.position, Vec3.multiply(warpDirection, distance)), warpPosition, WARP_SMOOTHING);
|
||||||
}
|
}
|
||||||
if ((position.x > (roomLimits.xMin - BUFFER)) &&
|
|
||||||
(position.x < (roomLimits.xMax + BUFFER)) &&
|
var height = MyAvatar.getEyePosition().y - MyAvatar.position.y;
|
||||||
(position.z > (roomLimits.zMin - BUFFER)) &&
|
|
||||||
(position.z < (roomLimits.zMax + BUFFER)))
|
if (!watchAvatar && (Math.abs(deltaYaw) < MAX_PULLBACK_YAW) && (deltaPosition.z > TRIGGER_PULLBACK_DISTANCE)) {
|
||||||
{
|
saveCameraState();
|
||||||
return true;
|
var cameraPosition = Vec3.subtract(MyAvatar.position, Vec3.multiplyQbyV(Camera.getOrientation(), { x: 0, y: -height, z: -height * WATCH_AVATAR_DISTANCE }));
|
||||||
} else {
|
Camera.setPosition(cameraPosition);
|
||||||
return false;
|
watchAvatar = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust overlays to match warp position
|
||||||
|
Overlays.editOverlay(warpSphere, {
|
||||||
|
position: warpPosition,
|
||||||
|
visible: willMove,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(warpLine, {
|
||||||
|
position: Vec3.sum(warpPosition, { x: 0, y: -WARP_LINE_HEIGHT / 2.0, z: 0 }),
|
||||||
|
end: Vec3.sum(warpPosition, { x: 0, y: WARP_LINE_HEIGHT / 2.0, z: 0 }),
|
||||||
|
visible: willMove,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishWarp() {
|
||||||
|
if (!warpActive) return;
|
||||||
|
warpActive = false;
|
||||||
|
Overlays.editOverlay(warpSphere, {
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(warpLine, {
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
if (willMove) {
|
||||||
|
MyAvatar.position = warpPosition;
|
||||||
|
playSound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveWithHead(deltaTime) {
|
function update(deltaTime) {
|
||||||
var position = MyAvatar.position;
|
|
||||||
var motorTimescale = VERY_LARGE_TIMESCALE;
|
|
||||||
if (movingWithHead) {
|
if (movingWithHead) {
|
||||||
var deltaYaw = MyAvatar.getHeadFinalYaw() - headStartYaw;
|
keyDownTime += deltaTime;
|
||||||
var deltaPitch = MyAvatar.getHeadDeltaPitch() - headStartDeltaPitch;
|
updateWarp();
|
||||||
var deltaRoll = MyAvatar.getHeadFinalRoll() - headStartRoll;
|
|
||||||
var velocity = MyAvatar.getVelocity();
|
|
||||||
var position = MyAvatar.position;
|
|
||||||
var neckPosition = MyAvatar.getNeckPosition();
|
|
||||||
var bodyLocalCurrentHeadVector = Vec3.subtract(neckPosition, position);
|
|
||||||
bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), bodyLocalCurrentHeadVector);
|
|
||||||
var headDelta = Vec3.subtract(bodyLocalCurrentHeadVector, headStartPosition);
|
|
||||||
headDelta.y = 0.0; // Don't respond to any of the vertical component of head motion
|
|
||||||
headDelta = Vec3.multiplyQbyV(MyAvatar.orientation, headDelta);
|
|
||||||
headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta);
|
|
||||||
|
|
||||||
var length = Vec3.length(headDelta);
|
|
||||||
|
|
||||||
if (length > 1.0) {
|
|
||||||
// Needs fixed! Right now sometimes reported neck position jumps to a bad value
|
|
||||||
headDelta.x = headDelta.y = headDelta.z = 0.0;
|
|
||||||
length = 0.0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thrust based on leaning forward and side-to-side
|
|
||||||
var targetVelocity = {x:0.0, y:0.0, z:0.0};
|
|
||||||
if (length > HEAD_MOVE_DEAD_ZONE) {
|
|
||||||
//headDelta = Vec3.normalize(headDelta);
|
|
||||||
//targetVelocity = Vec3.multiply(headDelta, FIXED_WALK_VELOCITY);
|
|
||||||
targetVelocity = Vec3.multiply(headDelta, HEAD_VELOCITY_FWD_FACTOR);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (Math.abs(headDelta.z) > HEAD_MOVE_DEAD_ZONE) {
|
|
||||||
if (fixedWalkVelocity) {
|
|
||||||
targetVelocity = Vec3.multiply(zAxis, headDelta.z > 0 ? FIXED_WALK_VELOCITY : -FIXED_WALK_VELOCITY);
|
|
||||||
} else {
|
|
||||||
targetVelocity = Vec3.multiply(zAxis, headDelta.z * HEAD_VELOCITY_FWD_FACTOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Math.abs(headDelta.x) > HEAD_STRAFE_DEAD_ZONE) {
|
|
||||||
var deltaVelocity = Vec3.multiply(xAxis, headDelta.x * HEAD_VELOCITY_LEFT_FACTOR);
|
|
||||||
targetVelocity = Vec3.sum(targetVelocity, deltaVelocity);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (Math.abs(deltaYaw) > HEAD_ROTATE_DEAD_ZONE) {
|
|
||||||
var orientation = Quat.multiply(Quat.angleAxis((deltaYaw + deltaRoll) * HEAD_YAW_RATE * deltaTime, yAxis), MyAvatar.orientation);
|
|
||||||
MyAvatar.orientation = orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thrust Up/Down based on head pitch
|
|
||||||
if (!noFly) {
|
|
||||||
var deltaVelocity = Vec3.multiply(yAxis, headDelta.y * HEAD_VELOCITY_UP_FACTOR);
|
|
||||||
targetVelocity = Vec3.sum(targetVelocity, deltaVelocity);
|
|
||||||
}
|
|
||||||
// For head trackers, adjust pitch by head pitch
|
|
||||||
MyAvatar.headPitch += deltaPitch * HEAD_PITCH_RATE * deltaTime;
|
|
||||||
|
|
||||||
// apply the motor
|
|
||||||
MyAvatar.motorVelocity = targetVelocity;
|
|
||||||
motorTimescale = SHORT_TIMESCALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check against movement box limits
|
|
||||||
if (isInRoom(position)) {
|
|
||||||
var thrust = { x: 0, y: 0, z: 0 };
|
|
||||||
// use thrust to constrain the avatar to the space
|
|
||||||
if (position.x < roomLimits.xMin) {
|
|
||||||
thrust.x += (roomLimits.xMin - position.x) * WALL_BOUNCE * deltaTime;
|
|
||||||
} else if (position.x > roomLimits.xMax) {
|
|
||||||
thrust.x += (roomLimits.xMax - position.x) * WALL_BOUNCE * deltaTime;
|
|
||||||
}
|
|
||||||
if (position.z < roomLimits.zMin) {
|
|
||||||
thrust.z += (roomLimits.zMin - position.z) * WALL_BOUNCE * deltaTime;
|
|
||||||
} else if (position.z > roomLimits.zMax) {
|
|
||||||
thrust.z += (roomLimits.zMax - position.z) * WALL_BOUNCE * deltaTime;
|
|
||||||
}
|
|
||||||
MyAvatar.addThrust(thrust);
|
|
||||||
if (movingWithHead && Vec3.length(thrust) > 0.0) {
|
|
||||||
// reduce the timescale of the motor so that it won't defeat the thrust code
|
|
||||||
Vec3.print("adebug room containment thrust = ", thrust);
|
|
||||||
motorTimescale = 1000000.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MyAvatar.motorTimescale = motorTimescale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.keyPressEvent.connect(function(event) {
|
Controller.keyPressEvent.connect(function(event) {
|
||||||
if (event.text == "SPACE" && !movingWithHead) {
|
if (event.text == "SPACE" && !movingWithHead) {
|
||||||
|
keyDownTime = 0.0;
|
||||||
movingWithHead = true;
|
movingWithHead = true;
|
||||||
headStartPosition = Vec3.subtract(MyAvatar.getNeckPosition(), MyAvatar.position);
|
headStartPosition = MyAvatar.getTrackedHeadPosition();
|
||||||
headStartPosition = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), headStartPosition);
|
|
||||||
headStartDeltaPitch = MyAvatar.getHeadDeltaPitch();
|
headStartDeltaPitch = MyAvatar.getHeadDeltaPitch();
|
||||||
headStartFinalPitch = MyAvatar.getHeadFinalPitch();
|
headStartFinalPitch = MyAvatar.getHeadFinalPitch();
|
||||||
headStartRoll = MyAvatar.getHeadFinalRoll();
|
headStartRoll = MyAvatar.getHeadFinalRoll();
|
||||||
headStartYaw = MyAvatar.getHeadFinalYaw();
|
headStartYaw = MyAvatar.getHeadFinalYaw();
|
||||||
// start with disabled motor -- it will be updated shortly
|
deltaYaw = 0.0;
|
||||||
MyAvatar.motorTimescale = VERY_LARGE_TIMESCALE;
|
warpPosition = MyAvatar.position;
|
||||||
MyAvatar.motorVelocity = {x:0.0, y:0.0, z:0.0};
|
activateWarp();
|
||||||
MyAvatar.motorReferenceFrame = "camera"; // alternatives are: "avatar" and "world"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var TIME_FOR_TURN_AROUND = 0.50;
|
||||||
|
var TIME_FOR_TURN = 0.25;
|
||||||
|
var TURN_AROUND = 180.0;
|
||||||
|
|
||||||
Controller.keyReleaseEvent.connect(function(event) {
|
Controller.keyReleaseEvent.connect(function(event) {
|
||||||
if (event.text == "SPACE") {
|
if (event.text == "SPACE") {
|
||||||
movingWithHead = false;
|
movingWithHead = false;
|
||||||
// disable motor by giving it an obnoxiously large timescale
|
if (keyDownTime < TIME_FOR_TURN_AROUND) {
|
||||||
MyAvatar.motorTimescale = VERY_LARGE_TIMESCALE;
|
if (keyDownTime < TIME_FOR_TURN) {
|
||||||
MyAvatar.motorVelocity = {x:0.0, y:0.0, z:0.0};
|
var currentYaw = MyAvatar.getHeadFinalYaw();
|
||||||
|
MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, currentYaw, 0), MyAvatar.orientation);
|
||||||
|
} else {
|
||||||
|
MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, TURN_AROUND, 0), MyAvatar.orientation);
|
||||||
|
}
|
||||||
|
playSound();
|
||||||
|
}
|
||||||
|
finishWarp();
|
||||||
|
if (watchAvatar) {
|
||||||
|
restoreCameraState();
|
||||||
|
watchAvatar = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script.update.connect(moveWithHead);
|
Script.update.connect(update);
|
||||||
|
|
||||||
|
|
|
@ -97,11 +97,12 @@ EntityCameraTool = function() {
|
||||||
|
|
||||||
that.focus = function(entityProperties) {
|
that.focus = function(entityProperties) {
|
||||||
var dim = entityProperties.dimensions;
|
var dim = entityProperties.dimensions;
|
||||||
|
dim = SelectionManager.worldDimensions;
|
||||||
var size = Math.max(dim.x, Math.max(dim.y, dim.z));
|
var size = Math.max(dim.x, Math.max(dim.y, dim.z));
|
||||||
|
|
||||||
that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM);
|
that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM);
|
||||||
|
|
||||||
that.setFocalPoint(entityProperties.position);
|
that.setFocalPoint(SelectionManager.worldPosition);//entityProperties.position);
|
||||||
|
|
||||||
that.updateCamera();
|
that.updateCamera();
|
||||||
}
|
}
|
||||||
|
@ -184,7 +185,7 @@ EntityCameraTool = function() {
|
||||||
// Scale based on current zoom level
|
// Scale based on current zoom level
|
||||||
dZoom *= that.targetZoomDistance * ZOOM_SCALING;
|
dZoom *= that.targetZoomDistance * ZOOM_SCALING;
|
||||||
|
|
||||||
that.targetZoomDistance = Math.max(Math.min(that.targetZoomDistance + dZoom, MAX_ZOOM_DISTANCE), MIN_ZOOM_DISTANCE);
|
that.targetZoomDistance = Math.max(that.targetZoomDistance + dZoom, MIN_ZOOM_DISTANCE);
|
||||||
|
|
||||||
that.updateCamera();
|
that.updateCamera();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,6 +21,7 @@ Script.include("libraries/progressDialog.js");
|
||||||
|
|
||||||
Script.include("libraries/entitySelectionTool.js");
|
Script.include("libraries/entitySelectionTool.js");
|
||||||
var selectionDisplay = SelectionDisplay;
|
var selectionDisplay = SelectionDisplay;
|
||||||
|
var selectionManager = SelectionManager;
|
||||||
|
|
||||||
Script.include("libraries/ModelImporter.js");
|
Script.include("libraries/ModelImporter.js");
|
||||||
var modelImporter = new ModelImporter();
|
var modelImporter = new ModelImporter();
|
||||||
|
@ -34,6 +35,8 @@ var entityPropertyDialogBox = EntityPropertyDialogBox;
|
||||||
Script.include("libraries/entityCameraTool.js");
|
Script.include("libraries/entityCameraTool.js");
|
||||||
var entityCameraTool = new EntityCameraTool();
|
var entityCameraTool = new EntityCameraTool();
|
||||||
|
|
||||||
|
selectionManager.setEventListener(selectionDisplay.updateHandles());
|
||||||
|
|
||||||
var windowDimensions = Controller.getViewportDimensions();
|
var windowDimensions = Controller.getViewportDimensions();
|
||||||
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
||||||
var toolHeight = 50;
|
var toolHeight = 50;
|
||||||
|
@ -440,6 +443,11 @@ function mousePressEvent(event) {
|
||||||
orientation = MyAvatar.orientation;
|
orientation = MyAvatar.orientation;
|
||||||
intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation));
|
intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation));
|
||||||
|
|
||||||
|
if (!event.isShifted) {
|
||||||
|
selectionManager.clearSelections();
|
||||||
|
}
|
||||||
|
selectionManager.addEntity(foundEntity);
|
||||||
|
|
||||||
print("Model selected selectedEntityID:" + selectedEntityID.id);
|
print("Model selected selectedEntityID:" + selectedEntityID.id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -641,14 +649,21 @@ Menu.menuItemEvent.connect(handeMenuEvent);
|
||||||
|
|
||||||
Controller.keyReleaseEvent.connect(function (event) {
|
Controller.keyReleaseEvent.connect(function (event) {
|
||||||
// since sometimes our menu shortcut keys don't work, trap our menu items here also and fire the appropriate menu items
|
// since sometimes our menu shortcut keys don't work, trap our menu items here also and fire the appropriate menu items
|
||||||
|
print(event.text);
|
||||||
if (event.text == "`") {
|
if (event.text == "`") {
|
||||||
handeMenuEvent("Edit Properties...");
|
handeMenuEvent("Edit Properties...");
|
||||||
}
|
}
|
||||||
if (event.text == "BACKSPACE") {
|
if (event.text == "BACKSPACE") {
|
||||||
handeMenuEvent("Delete");
|
handeMenuEvent("Delete");
|
||||||
|
} else if (event.text == "TAB") {
|
||||||
|
selectionDisplay.toggleSpaceMode();
|
||||||
|
} else if (event.text == "ESC") {
|
||||||
|
selectionDisplay.cancelTool();
|
||||||
} else if (event.text == "f") {
|
} else if (event.text == "f") {
|
||||||
if (entitySelected) {
|
if (entitySelected) {
|
||||||
entityCameraTool.focus(selectedEntityProperties);
|
// Get latest properties
|
||||||
|
var properties = Entities.getEntityProperties(selectedEntityID);
|
||||||
|
entityCameraTool.focus(properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "ui/AttachmentsDialog.h"
|
#include "ui/AttachmentsDialog.h"
|
||||||
#include "ui/InfoView.h"
|
#include "ui/InfoView.h"
|
||||||
#include "ui/MetavoxelEditor.h"
|
#include "ui/MetavoxelEditor.h"
|
||||||
|
#include "ui/MetavoxelNetworkSimulator.h"
|
||||||
#include "ui/ModelsBrowser.h"
|
#include "ui/ModelsBrowser.h"
|
||||||
#include "ui/LoginDialog.h"
|
#include "ui/LoginDialog.h"
|
||||||
#include "ui/NodeBounds.h"
|
#include "ui/NodeBounds.h"
|
||||||
|
@ -431,6 +432,8 @@ Menu::Menu() :
|
||||||
QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");
|
QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");
|
||||||
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,
|
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,
|
||||||
Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));
|
Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));
|
||||||
|
addActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::NetworkSimulator, 0, this,
|
||||||
|
SLOT(showMetavoxelNetworkSimulator()));
|
||||||
|
|
||||||
QMenu* handOptionsMenu = developerMenu->addMenu("Hands");
|
QMenu* handOptionsMenu = developerMenu->addMenu("Hands");
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);
|
||||||
|
@ -1378,6 +1381,13 @@ void Menu::showMetavoxelEditor() {
|
||||||
_MetavoxelEditor->raise();
|
_MetavoxelEditor->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::showMetavoxelNetworkSimulator() {
|
||||||
|
if (!_metavoxelNetworkSimulator) {
|
||||||
|
_metavoxelNetworkSimulator = new MetavoxelNetworkSimulator();
|
||||||
|
}
|
||||||
|
_metavoxelNetworkSimulator->raise();
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::showScriptEditor() {
|
void Menu::showScriptEditor() {
|
||||||
if(!_ScriptEditor || !_ScriptEditor->isVisible()) {
|
if(!_ScriptEditor || !_ScriptEditor->isVisible()) {
|
||||||
_ScriptEditor = new ScriptEditorWindow();
|
_ScriptEditor = new ScriptEditorWindow();
|
||||||
|
|
|
@ -78,6 +78,7 @@ class AttachmentsDialog;
|
||||||
class BandwidthDialog;
|
class BandwidthDialog;
|
||||||
class LodToolsDialog;
|
class LodToolsDialog;
|
||||||
class MetavoxelEditor;
|
class MetavoxelEditor;
|
||||||
|
class MetavoxelNetworkSimulator;
|
||||||
class ChatWindow;
|
class ChatWindow;
|
||||||
class OctreeStatsDialog;
|
class OctreeStatsDialog;
|
||||||
class MenuItemProperties;
|
class MenuItemProperties;
|
||||||
|
@ -218,6 +219,7 @@ private slots:
|
||||||
void cycleFrustumRenderMode();
|
void cycleFrustumRenderMode();
|
||||||
void runTests();
|
void runTests();
|
||||||
void showMetavoxelEditor();
|
void showMetavoxelEditor();
|
||||||
|
void showMetavoxelNetworkSimulator();
|
||||||
void showScriptEditor();
|
void showScriptEditor();
|
||||||
void showChat();
|
void showChat();
|
||||||
void toggleConsole();
|
void toggleConsole();
|
||||||
|
@ -274,6 +276,7 @@ private:
|
||||||
FrustumDrawMode _frustumDrawMode;
|
FrustumDrawMode _frustumDrawMode;
|
||||||
ViewFrustumOffset _viewFrustumOffset;
|
ViewFrustumOffset _viewFrustumOffset;
|
||||||
QPointer<MetavoxelEditor> _MetavoxelEditor;
|
QPointer<MetavoxelEditor> _MetavoxelEditor;
|
||||||
|
QPointer<MetavoxelNetworkSimulator> _metavoxelNetworkSimulator;
|
||||||
QPointer<ScriptEditorWindow> _ScriptEditor;
|
QPointer<ScriptEditorWindow> _ScriptEditor;
|
||||||
QPointer<ChatWindow> _chatWindow;
|
QPointer<ChatWindow> _chatWindow;
|
||||||
QDialog* _jsConsole;
|
QDialog* _jsConsole;
|
||||||
|
@ -430,6 +433,7 @@ namespace MenuOption {
|
||||||
const QString MuteEnvironment = "Mute Environment";
|
const QString MuteEnvironment = "Mute Environment";
|
||||||
const QString MyLocations = "My Locations...";
|
const QString MyLocations = "My Locations...";
|
||||||
const QString NameLocation = "Name this location";
|
const QString NameLocation = "Name this location";
|
||||||
|
const QString NetworkSimulator = "Network Simulator...";
|
||||||
const QString NewVoxelCullingMode = "New Voxel Culling Mode";
|
const QString NewVoxelCullingMode = "New Voxel Culling Mode";
|
||||||
const QString ObeyEnvironmentalGravity = "Obey Environmental Gravity";
|
const QString ObeyEnvironmentalGravity = "Obey Environmental Gravity";
|
||||||
const QString OctreeStats = "Voxel and Entity Statistics";
|
const QString OctreeStats = "Voxel and Entity Statistics";
|
||||||
|
|
|
@ -39,6 +39,15 @@ REGISTER_META_OBJECT(StaticModelRenderer)
|
||||||
|
|
||||||
static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
|
static int bufferPointVectorMetaTypeId = qRegisterMetaType<BufferPointVector>();
|
||||||
|
|
||||||
|
MetavoxelSystem::NetworkSimulation::NetworkSimulation(float dropRate, float repeatRate,
|
||||||
|
int minimumDelay, int maximumDelay, int bandwidthLimit) :
|
||||||
|
dropRate(dropRate),
|
||||||
|
repeatRate(repeatRate),
|
||||||
|
minimumDelay(minimumDelay),
|
||||||
|
maximumDelay(maximumDelay),
|
||||||
|
bandwidthLimit(bandwidthLimit) {
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelSystem::init() {
|
void MetavoxelSystem::init() {
|
||||||
MetavoxelClientManager::init();
|
MetavoxelClientManager::init();
|
||||||
DefaultMetavoxelRendererImplementation::init();
|
DefaultMetavoxelRendererImplementation::init();
|
||||||
|
@ -61,6 +70,16 @@ MetavoxelLOD MetavoxelSystem::getLOD() {
|
||||||
return _lod;
|
return _lod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelSystem::setNetworkSimulation(const NetworkSimulation& simulation) {
|
||||||
|
QWriteLocker locker(&_networkSimulationLock);
|
||||||
|
_networkSimulation = simulation;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetavoxelSystem::NetworkSimulation MetavoxelSystem::getNetworkSimulation() {
|
||||||
|
QReadLocker locker(&_networkSimulationLock);
|
||||||
|
return _networkSimulation;
|
||||||
|
}
|
||||||
|
|
||||||
class SimulateVisitor : public MetavoxelVisitor {
|
class SimulateVisitor : public MetavoxelVisitor {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -678,6 +697,28 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Throttle::Throttle() :
|
||||||
|
_limit(INT_MAX),
|
||||||
|
_total(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Throttle::shouldThrottle(int bytes) {
|
||||||
|
// clear expired buckets
|
||||||
|
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
while (!_buckets.isEmpty() && now >= _buckets.first().first) {
|
||||||
|
_total -= _buckets.takeFirst().second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if possible, add the new bucket
|
||||||
|
if (_total + bytes > _limit) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const int BUCKET_DURATION = 1000;
|
||||||
|
_buckets.append(Bucket(now + BUCKET_DURATION, bytes));
|
||||||
|
_total += bytes;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) :
|
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) :
|
||||||
MetavoxelClient(node, updater) {
|
MetavoxelClient(node, updater) {
|
||||||
}
|
}
|
||||||
|
@ -692,10 +733,59 @@ MetavoxelData MetavoxelSystemClient::getAugmentedData() {
|
||||||
return _augmentedData;
|
return _augmentedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ReceiveDelayer : public QObject {
|
||||||
|
public:
|
||||||
|
|
||||||
|
ReceiveDelayer(const SharedNodePointer& node, const QByteArray& packet);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void timerEvent(QTimerEvent* event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SharedNodePointer _node;
|
||||||
|
QByteArray _packet;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReceiveDelayer::ReceiveDelayer(const SharedNodePointer& node, const QByteArray& packet) :
|
||||||
|
_node(node),
|
||||||
|
_packet(packet) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveDelayer::timerEvent(QTimerEvent* event) {
|
||||||
|
QMutexLocker locker(&_node->getMutex());
|
||||||
|
MetavoxelClient* client = static_cast<MetavoxelClient*>(_node->getLinkedData());
|
||||||
|
if (client) {
|
||||||
|
QMetaObject::invokeMethod(&client->getSequencer(), "receivedDatagram", Q_ARG(const QByteArray&, _packet));
|
||||||
|
}
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
int MetavoxelSystemClient::parseData(const QByteArray& packet) {
|
int MetavoxelSystemClient::parseData(const QByteArray& packet) {
|
||||||
// process through sequencer
|
// process through sequencer
|
||||||
|
MetavoxelSystem::NetworkSimulation simulation = Application::getInstance()->getMetavoxels()->getNetworkSimulation();
|
||||||
|
if (randFloat() < simulation.dropRate) {
|
||||||
|
return packet.size();
|
||||||
|
}
|
||||||
|
int count = (randFloat() < simulation.repeatRate) ? 2 : 1;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (simulation.bandwidthLimit > 0) {
|
||||||
|
_receiveThrottle.setLimit(simulation.bandwidthLimit);
|
||||||
|
if (_receiveThrottle.shouldThrottle(packet.size())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int delay = randIntInRange(simulation.minimumDelay, simulation.maximumDelay);
|
||||||
|
if (delay > 0) {
|
||||||
|
ReceiveDelayer* delayer = new ReceiveDelayer(_node, packet);
|
||||||
|
delayer->startTimer(delay);
|
||||||
|
|
||||||
|
} else {
|
||||||
QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet));
|
QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet));
|
||||||
|
}
|
||||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::METAVOXELS).updateValue(packet.size());
|
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::METAVOXELS).updateValue(packet.size());
|
||||||
|
}
|
||||||
return packet.size();
|
return packet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,9 +864,52 @@ void MetavoxelSystemClient::dataChanged(const MetavoxelData& oldData) {
|
||||||
QThreadPool::globalInstance()->start(new Augmenter(_node, _data, getAugmentedData(), _remoteDataLOD));
|
QThreadPool::globalInstance()->start(new Augmenter(_node, _data, getAugmentedData(), _remoteDataLOD));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SendDelayer : public QObject {
|
||||||
|
public:
|
||||||
|
|
||||||
|
SendDelayer(const SharedNodePointer& node, const QByteArray& data);
|
||||||
|
|
||||||
|
virtual void timerEvent(QTimerEvent* event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SharedNodePointer _node;
|
||||||
|
QByteArray _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
SendDelayer::SendDelayer(const SharedNodePointer& node, const QByteArray& data) :
|
||||||
|
_node(node),
|
||||||
|
_data(data.constData(), data.size()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendDelayer::timerEvent(QTimerEvent* event) {
|
||||||
|
NodeList::getInstance()->writeDatagram(_data, _node);
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
|
void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
|
||||||
|
MetavoxelSystem::NetworkSimulation simulation = Application::getInstance()->getMetavoxels()->getNetworkSimulation();
|
||||||
|
if (randFloat() < simulation.dropRate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count = (randFloat() < simulation.repeatRate) ? 2 : 1;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (simulation.bandwidthLimit > 0) {
|
||||||
|
_sendThrottle.setLimit(simulation.bandwidthLimit);
|
||||||
|
if (_sendThrottle.shouldThrottle(data.size())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int delay = randIntInRange(simulation.minimumDelay, simulation.maximumDelay);
|
||||||
|
if (delay > 0) {
|
||||||
|
SendDelayer* delayer = new SendDelayer(_node, data);
|
||||||
|
delayer->startTimer(delay);
|
||||||
|
|
||||||
|
} else {
|
||||||
NodeList::getInstance()->writeDatagram(data, _node);
|
NodeList::getInstance()->writeDatagram(data, _node);
|
||||||
|
}
|
||||||
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size());
|
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferData::~BufferData() {
|
BufferData::~BufferData() {
|
||||||
|
|
|
@ -31,12 +31,27 @@ class MetavoxelSystem : public MetavoxelClientManager {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
class NetworkSimulation {
|
||||||
|
public:
|
||||||
|
float dropRate;
|
||||||
|
float repeatRate;
|
||||||
|
int minimumDelay;
|
||||||
|
int maximumDelay;
|
||||||
|
int bandwidthLimit;
|
||||||
|
|
||||||
|
NetworkSimulation(float dropRate = 0.0f, float repeatRate = 0.0f, int minimumDelay = 0,
|
||||||
|
int maximumDelay = 0, int bandwidthLimit = 0);
|
||||||
|
};
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
virtual MetavoxelLOD getLOD();
|
virtual MetavoxelLOD getLOD();
|
||||||
|
|
||||||
const Frustum& getFrustum() const { return _frustum; }
|
const Frustum& getFrustum() const { return _frustum; }
|
||||||
|
|
||||||
|
void setNetworkSimulation(const NetworkSimulation& simulation);
|
||||||
|
NetworkSimulation getNetworkSimulation();
|
||||||
|
|
||||||
const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; }
|
const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; }
|
||||||
const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; }
|
const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; }
|
||||||
const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; }
|
const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; }
|
||||||
|
@ -93,6 +108,9 @@ private:
|
||||||
MetavoxelLOD _lod;
|
MetavoxelLOD _lod;
|
||||||
QReadWriteLock _lodLock;
|
QReadWriteLock _lodLock;
|
||||||
Frustum _frustum;
|
Frustum _frustum;
|
||||||
|
|
||||||
|
NetworkSimulation _networkSimulation;
|
||||||
|
QReadWriteLock _networkSimulationLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Generic abstract base class for objects that handle a signal.
|
/// Generic abstract base class for objects that handle a signal.
|
||||||
|
@ -116,6 +134,28 @@ typedef QVector<BufferPoint> BufferPointVector;
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(BufferPointVector)
|
Q_DECLARE_METATYPE(BufferPointVector)
|
||||||
|
|
||||||
|
/// Simple throttle for limiting bandwidth on a per-second basis.
|
||||||
|
class Throttle {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Throttle();
|
||||||
|
|
||||||
|
/// Sets the per-second limit.
|
||||||
|
void setLimit(int limit) { _limit = limit; }
|
||||||
|
|
||||||
|
/// Determines whether the message with the given size should be throttled (discarded). If not, registers the message
|
||||||
|
/// as having been processed (i.e., contributing to later throttling).
|
||||||
|
bool shouldThrottle(int bytes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int _limit;
|
||||||
|
int _total;
|
||||||
|
|
||||||
|
typedef QPair<qint64, int> Bucket;
|
||||||
|
QList<Bucket> _buckets;
|
||||||
|
};
|
||||||
|
|
||||||
/// A client session associated with a single server.
|
/// A client session associated with a single server.
|
||||||
class MetavoxelSystemClient : public MetavoxelClient {
|
class MetavoxelSystemClient : public MetavoxelClient {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -145,6 +185,9 @@ private:
|
||||||
MetavoxelData _augmentedData;
|
MetavoxelData _augmentedData;
|
||||||
MetavoxelData _renderedAugmentedData;
|
MetavoxelData _renderedAugmentedData;
|
||||||
QReadWriteLock _augmentedDataLock;
|
QReadWriteLock _augmentedDataLock;
|
||||||
|
|
||||||
|
Throttle _sendThrottle;
|
||||||
|
Throttle _receiveThrottle;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for cached static buffers.
|
/// Base class for cached static buffers.
|
||||||
|
|
|
@ -296,6 +296,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
||||||
} else if (OculusManager::isConnected()) {
|
} else if (OculusManager::isConnected()) {
|
||||||
estimatedPosition = OculusManager::getRelativePosition();
|
estimatedPosition = OculusManager::getRelativePosition();
|
||||||
estimatedPosition.x *= -1.0f;
|
estimatedPosition.x *= -1.0f;
|
||||||
|
_trackedHeadPosition = estimatedPosition;
|
||||||
|
|
||||||
const float OCULUS_LEAN_SCALE = 0.05f;
|
const float OCULUS_LEAN_SCALE = 0.05f;
|
||||||
estimatedPosition /= OCULUS_LEAN_SCALE;
|
estimatedPosition /= OCULUS_LEAN_SCALE;
|
||||||
|
@ -303,6 +304,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
||||||
FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker();
|
FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker();
|
||||||
if (tracker) {
|
if (tracker) {
|
||||||
estimatedPosition = tracker->getHeadTranslation();
|
estimatedPosition = tracker->getHeadTranslation();
|
||||||
|
_trackedHeadPosition = estimatedPosition;
|
||||||
estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation()));
|
estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,7 @@ public:
|
||||||
|
|
||||||
static void sendKillAvatar();
|
static void sendKillAvatar();
|
||||||
|
|
||||||
|
Q_INVOKABLE glm::vec3 getTrackedHeadPosition() const { return _trackedHeadPosition; }
|
||||||
Q_INVOKABLE glm::vec3 getHeadPosition() const { return getHead()->getPosition(); }
|
Q_INVOKABLE glm::vec3 getHeadPosition() const { return getHead()->getPosition(); }
|
||||||
Q_INVOKABLE float getHeadFinalYaw() const { return getHead()->getFinalYaw(); }
|
Q_INVOKABLE float getHeadFinalYaw() const { return getHead()->getFinalYaw(); }
|
||||||
Q_INVOKABLE float getHeadFinalRoll() const { return getHead()->getFinalRoll(); }
|
Q_INVOKABLE float getHeadFinalRoll() const { return getHead()->getFinalRoll(); }
|
||||||
|
@ -237,6 +238,8 @@ private:
|
||||||
|
|
||||||
RecorderPointer _recorder;
|
RecorderPointer _recorder;
|
||||||
|
|
||||||
|
glm::vec3 _trackedHeadPosition;
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
void updateOrientation(float deltaTime);
|
void updateOrientation(float deltaTime);
|
||||||
glm::vec3 applyKeyboardMotor(float deltaTime, const glm::vec3& velocity, bool walkingOnFloor);
|
glm::vec3 applyKeyboardMotor(float deltaTime, const glm::vec3& velocity, bool walkingOnFloor);
|
||||||
|
|
87
interface/src/ui/MetavoxelNetworkSimulator.cpp
Normal file
87
interface/src/ui/MetavoxelNetworkSimulator.cpp
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
//
|
||||||
|
// MetavoxelNetworkSimulator.cpp
|
||||||
|
// interface/src/ui
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 10/20/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "MetavoxelNetworkSimulator.h"
|
||||||
|
|
||||||
|
const int BYTES_PER_KILOBYTE = 1024;
|
||||||
|
|
||||||
|
MetavoxelNetworkSimulator::MetavoxelNetworkSimulator() :
|
||||||
|
QWidget(Application::getInstance()->getGLWidget(), Qt::Dialog) {
|
||||||
|
|
||||||
|
setWindowTitle("Metavoxel Network Simulator");
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
QVBoxLayout* topLayout = new QVBoxLayout();
|
||||||
|
setLayout(topLayout);
|
||||||
|
|
||||||
|
QFormLayout* form = new QFormLayout();
|
||||||
|
topLayout->addLayout(form);
|
||||||
|
|
||||||
|
MetavoxelSystem::NetworkSimulation simulation = Application::getInstance()->getMetavoxels()->getNetworkSimulation();
|
||||||
|
|
||||||
|
form->addRow("Drop Rate:", _dropRate = new QDoubleSpinBox());
|
||||||
|
_dropRate->setSuffix("%");
|
||||||
|
_dropRate->setValue(simulation.dropRate * 100.0);
|
||||||
|
connect(_dropRate, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this,
|
||||||
|
&MetavoxelNetworkSimulator::updateMetavoxelSystem);
|
||||||
|
|
||||||
|
form->addRow("Repeat Rate:", _repeatRate = new QDoubleSpinBox());
|
||||||
|
_repeatRate->setSuffix("%");
|
||||||
|
_repeatRate->setValue(simulation.repeatRate * 100.0);
|
||||||
|
connect(_repeatRate, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this,
|
||||||
|
&MetavoxelNetworkSimulator::updateMetavoxelSystem);
|
||||||
|
|
||||||
|
form->addRow("Minimum Delay:", _minimumDelay = new QSpinBox());
|
||||||
|
_minimumDelay->setMaximum(1000);
|
||||||
|
_minimumDelay->setSuffix("ms");
|
||||||
|
_minimumDelay->setValue(simulation.minimumDelay);
|
||||||
|
connect(_minimumDelay, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||||
|
&MetavoxelNetworkSimulator::updateMetavoxelSystem);
|
||||||
|
|
||||||
|
form->addRow("Maximum Delay:", _maximumDelay = new QSpinBox());
|
||||||
|
_maximumDelay->setMaximum(1000);
|
||||||
|
_maximumDelay->setSuffix("ms");
|
||||||
|
_maximumDelay->setValue(simulation.maximumDelay);
|
||||||
|
connect(_maximumDelay, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||||
|
&MetavoxelNetworkSimulator::updateMetavoxelSystem);
|
||||||
|
|
||||||
|
form->addRow("Bandwidth Limit:", _bandwidthLimit = new QSpinBox());
|
||||||
|
_bandwidthLimit->setMaximum(1024 * 1024);
|
||||||
|
_bandwidthLimit->setSuffix("KB/s");
|
||||||
|
_bandwidthLimit->setValue(simulation.bandwidthLimit / BYTES_PER_KILOBYTE);
|
||||||
|
connect(_bandwidthLimit, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||||
|
&MetavoxelNetworkSimulator::updateMetavoxelSystem);
|
||||||
|
|
||||||
|
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok, this);
|
||||||
|
topLayout->addWidget(buttons);
|
||||||
|
connect(buttons, &QDialogButtonBox::accepted, this, &QWidget::close);
|
||||||
|
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetavoxelNetworkSimulator::updateMetavoxelSystem() {
|
||||||
|
int bandwidthLimit = _bandwidthLimit->value() * BYTES_PER_KILOBYTE;
|
||||||
|
if (bandwidthLimit > 0) {
|
||||||
|
// make sure the limit is enough to let at least one packet through
|
||||||
|
const int MINIMUM_BANDWIDTH_LIMIT = 2048;
|
||||||
|
bandwidthLimit = qMax(bandwidthLimit, MINIMUM_BANDWIDTH_LIMIT);
|
||||||
|
}
|
||||||
|
Application::getInstance()->getMetavoxels()->setNetworkSimulation(MetavoxelSystem::NetworkSimulation(
|
||||||
|
_dropRate->value() / 100.0, _repeatRate->value() / 100.0, qMin(_minimumDelay->value(), _maximumDelay->value()),
|
||||||
|
qMax(_minimumDelay->value(), _maximumDelay->value()), bandwidthLimit));
|
||||||
|
}
|
41
interface/src/ui/MetavoxelNetworkSimulator.h
Normal file
41
interface/src/ui/MetavoxelNetworkSimulator.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// MetavoxelNetworkSimulator.h
|
||||||
|
// interface/src/ui
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 10/20/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_MetavoxelNetworkSimulator_h
|
||||||
|
#define hifi_MetavoxelNetworkSimulator_h
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QDoubleSpinBox;
|
||||||
|
class QSpinBox;
|
||||||
|
|
||||||
|
/// Allows tweaking network simulation (packet drop percentage, etc.) settings for metavoxels.
|
||||||
|
class MetavoxelNetworkSimulator : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MetavoxelNetworkSimulator();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void updateMetavoxelSystem();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QDoubleSpinBox* _dropRate;
|
||||||
|
QDoubleSpinBox* _repeatRate;
|
||||||
|
QSpinBox* _minimumDelay;
|
||||||
|
QSpinBox* _maximumDelay;
|
||||||
|
QSpinBox* _bandwidthLimit;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_MetavoxelNetworkSimulator_h
|
|
@ -26,6 +26,7 @@ public:
|
||||||
~Base3DOverlay();
|
~Base3DOverlay();
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
|
virtual bool is3D() const { return true; }
|
||||||
const glm::vec3& getPosition() const { return _position; }
|
const glm::vec3& getPosition() const { return _position; }
|
||||||
const glm::vec3& getCenter() const { return _position; } // TODO: consider implementing registration points in this class
|
const glm::vec3& getCenter() const { return _position; } // TODO: consider implementing registration points in this class
|
||||||
float getLineWidth() const { return _lineWidth; }
|
float getLineWidth() const { return _lineWidth; }
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
virtual void render() = 0;
|
virtual void render() = 0;
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
|
virtual bool is3D() const = 0;
|
||||||
bool isLoaded() { return _isLoaded; }
|
bool isLoaded() { return _isLoaded; }
|
||||||
bool getVisible() const { return _visible; }
|
bool getVisible() const { return _visible; }
|
||||||
xColor getColor();
|
xColor getColor();
|
||||||
|
|
|
@ -30,6 +30,8 @@ public:
|
||||||
Overlay2D();
|
Overlay2D();
|
||||||
~Overlay2D();
|
~Overlay2D();
|
||||||
|
|
||||||
|
virtual bool is3D() const { return false; }
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
int getX() const { return _bounds.x(); }
|
int getX() const { return _bounds.x(); }
|
||||||
int getY() const { return _bounds.y(); }
|
int getY() const { return _bounds.y(); }
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "Rectangle3DOverlay.h"
|
#include "Rectangle3DOverlay.h"
|
||||||
#include "Sphere3DOverlay.h"
|
#include "Sphere3DOverlay.h"
|
||||||
#include "TextOverlay.h"
|
#include "TextOverlay.h"
|
||||||
|
#include "Text3DOverlay.h"
|
||||||
|
|
||||||
Overlays::Overlays() : _nextOverlayID(1) {
|
Overlays::Overlays() : _nextOverlayID(1) {
|
||||||
}
|
}
|
||||||
|
@ -131,6 +132,8 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
|
||||||
thisOverlay = new ImageOverlay();
|
thisOverlay = new ImageOverlay();
|
||||||
} else if (type == "text") {
|
} else if (type == "text") {
|
||||||
thisOverlay = new TextOverlay();
|
thisOverlay = new TextOverlay();
|
||||||
|
} else if (type == "text3d") {
|
||||||
|
thisOverlay = new Text3DOverlay();
|
||||||
} else if (type == "cube") {
|
} else if (type == "cube") {
|
||||||
thisOverlay = new Cube3DOverlay();
|
thisOverlay = new Cube3DOverlay();
|
||||||
} else if (type == "sphere") {
|
} else if (type == "sphere") {
|
||||||
|
@ -167,8 +170,7 @@ unsigned int Overlays::addOverlay(Overlay* overlay) {
|
||||||
QWriteLocker lock(&_lock);
|
QWriteLocker lock(&_lock);
|
||||||
unsigned int thisID = _nextOverlayID;
|
unsigned int thisID = _nextOverlayID;
|
||||||
_nextOverlayID++;
|
_nextOverlayID++;
|
||||||
bool is3D = typeid(*overlay) != typeid(ImageOverlay) && typeid(*overlay) != typeid(TextOverlay);
|
if (overlay->is3D()) {
|
||||||
if (is3D) {
|
|
||||||
_overlays3D[thisID] = overlay;
|
_overlays3D[thisID] = overlay;
|
||||||
} else {
|
} else {
|
||||||
_overlays2D[thisID] = overlay;
|
_overlays2D[thisID] = overlay;
|
||||||
|
|
182
interface/src/ui/overlays/Text3DOverlay.cpp
Normal file
182
interface/src/ui/overlays/Text3DOverlay.cpp
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
//
|
||||||
|
// Text3DOverlay.cpp
|
||||||
|
// interface/src/ui/overlays
|
||||||
|
//
|
||||||
|
// 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 this before QGLWidget, which includes an earlier version of OpenGL
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "Text3DOverlay.h"
|
||||||
|
#include "ui/TextRenderer.h"
|
||||||
|
|
||||||
|
const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 };
|
||||||
|
const float DEFAULT_MARGIN = 0.1f;
|
||||||
|
|
||||||
|
Text3DOverlay::Text3DOverlay() :
|
||||||
|
_backgroundColor(DEFAULT_BACKGROUND_COLOR),
|
||||||
|
_lineHeight(0.1f),
|
||||||
|
_leftMargin(DEFAULT_MARGIN),
|
||||||
|
_topMargin(DEFAULT_MARGIN),
|
||||||
|
_rightMargin(DEFAULT_MARGIN),
|
||||||
|
_bottomMargin(DEFAULT_MARGIN),
|
||||||
|
_isFacingAvatar(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Text3DOverlay::~Text3DOverlay() {
|
||||||
|
}
|
||||||
|
|
||||||
|
xColor Text3DOverlay::getBackgroundColor() {
|
||||||
|
if (_colorPulse == 0.0f) {
|
||||||
|
return _backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
float pulseLevel = updatePulse();
|
||||||
|
xColor result = _backgroundColor;
|
||||||
|
if (_colorPulse < 0.0f) {
|
||||||
|
result.red *= (1.0f - pulseLevel);
|
||||||
|
result.green *= (1.0f - pulseLevel);
|
||||||
|
result.blue *= (1.0f - pulseLevel);
|
||||||
|
} else {
|
||||||
|
result.red *= pulseLevel;
|
||||||
|
result.green *= pulseLevel;
|
||||||
|
result.blue *= pulseLevel;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Text3DOverlay::render() {
|
||||||
|
if (!_visible) {
|
||||||
|
return; // do nothing if we're not visible
|
||||||
|
}
|
||||||
|
|
||||||
|
glPushMatrix(); {
|
||||||
|
glTranslatef(_position.x, _position.y, _position.z);
|
||||||
|
glm::quat rotation;
|
||||||
|
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));
|
||||||
|
} else {
|
||||||
|
rotation = getRotation();
|
||||||
|
}
|
||||||
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
|
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||||
|
|
||||||
|
const float MAX_COLOR = 255.0f;
|
||||||
|
xColor backgroundColor = getBackgroundColor();
|
||||||
|
float alpha = getAlpha();
|
||||||
|
glColor4f(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, alpha);
|
||||||
|
|
||||||
|
glm::vec2 dimensions = getDimensions();
|
||||||
|
glm::vec2 halfDimensions = dimensions * 0.5f;
|
||||||
|
|
||||||
|
const float SLIGHTLY_BEHIND = -0.005f;
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex3f(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||||
|
glVertex3f(halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||||
|
glVertex3f(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||||
|
glVertex3f(-halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
const int FIXED_FONT_POINT_SIZE = 40;
|
||||||
|
const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation
|
||||||
|
|
||||||
|
TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
|
||||||
|
float LINE_SCALE_RATIO = 1.2f;
|
||||||
|
float maxHeight = (float)textRenderer->calculateHeight("Xy") * LINE_SCALE_RATIO;
|
||||||
|
|
||||||
|
float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
||||||
|
|
||||||
|
glTranslatef(-(halfDimensions.x - _leftMargin), halfDimensions.y - _topMargin, 0.0f);
|
||||||
|
|
||||||
|
glm::vec2 clipMinimum(0.0f, 0.0f);
|
||||||
|
glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor,
|
||||||
|
(dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor);
|
||||||
|
|
||||||
|
glScalef(scaleFactor, -scaleFactor, 1.0);
|
||||||
|
enableClipPlane(GL_CLIP_PLANE0, -1.0f, 0.0f, 0.0f, clipMinimum.x + clipDimensions.x);
|
||||||
|
enableClipPlane(GL_CLIP_PLANE1, 1.0f, 0.0f, 0.0f, -clipMinimum.x);
|
||||||
|
enableClipPlane(GL_CLIP_PLANE2, 0.0f, -1.0f, 0.0f, clipMinimum.y + clipDimensions.y);
|
||||||
|
enableClipPlane(GL_CLIP_PLANE3, 0.0f, 1.0f, 0.0f, -clipMinimum.y);
|
||||||
|
|
||||||
|
glColor3f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR);
|
||||||
|
QStringList lines = _text.split("\n");
|
||||||
|
int lineOffset = maxHeight;
|
||||||
|
foreach(QString thisLine, lines) {
|
||||||
|
textRenderer->draw(0, lineOffset, qPrintable(thisLine));
|
||||||
|
lineOffset += maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_CLIP_PLANE0);
|
||||||
|
glDisable(GL_CLIP_PLANE1);
|
||||||
|
glDisable(GL_CLIP_PLANE2);
|
||||||
|
glDisable(GL_CLIP_PLANE3);
|
||||||
|
|
||||||
|
} glPopMatrix();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text3DOverlay::enableClipPlane(GLenum plane, float x, float y, float z, float w) {
|
||||||
|
GLdouble coefficients[] = { x, y, z, w };
|
||||||
|
glClipPlane(plane, coefficients);
|
||||||
|
glEnable(plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
|
Planar3DOverlay::setProperties(properties);
|
||||||
|
|
||||||
|
QScriptValue text = properties.property("text");
|
||||||
|
if (text.isValid()) {
|
||||||
|
setText(text.toVariant().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue backgroundColor = properties.property("backgroundColor");
|
||||||
|
if (backgroundColor.isValid()) {
|
||||||
|
QScriptValue red = backgroundColor.property("red");
|
||||||
|
QScriptValue green = backgroundColor.property("green");
|
||||||
|
QScriptValue blue = backgroundColor.property("blue");
|
||||||
|
if (red.isValid() && green.isValid() && blue.isValid()) {
|
||||||
|
_backgroundColor.red = red.toVariant().toInt();
|
||||||
|
_backgroundColor.green = green.toVariant().toInt();
|
||||||
|
_backgroundColor.blue = blue.toVariant().toInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.property("lineHeight").isValid()) {
|
||||||
|
setLineHeight(properties.property("lineHeight").toVariant().toFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.property("leftMargin").isValid()) {
|
||||||
|
setLeftMargin(properties.property("leftMargin").toVariant().toFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.property("topMargin").isValid()) {
|
||||||
|
setTopMargin(properties.property("topMargin").toVariant().toFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.property("rightMargin").isValid()) {
|
||||||
|
setRightMargin(properties.property("rightMargin").toVariant().toFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.property("bottomMargin").isValid()) {
|
||||||
|
setBottomMargin(properties.property("bottomMargin").toVariant().toFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScriptValue isFacingAvatarValue = properties.property("isFacingAvatar");
|
||||||
|
if (isFacingAvatarValue.isValid()) {
|
||||||
|
_isFacingAvatar = isFacingAvatarValue.toVariant().toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
61
interface/src/ui/overlays/Text3DOverlay.h
Normal file
61
interface/src/ui/overlays/Text3DOverlay.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// Text3DOverlay.h
|
||||||
|
// interface/src/ui/overlays
|
||||||
|
//
|
||||||
|
// 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_Text3DOverlay_h
|
||||||
|
#define hifi_Text3DOverlay_h
|
||||||
|
|
||||||
|
// include this before QGLWidget, which includes an earlier version of OpenGL
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include "Planar3DOverlay.h"
|
||||||
|
|
||||||
|
class Text3DOverlay : public Planar3DOverlay {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Text3DOverlay();
|
||||||
|
~Text3DOverlay();
|
||||||
|
virtual void render();
|
||||||
|
|
||||||
|
// getters
|
||||||
|
const QString& getText() const { return _text; }
|
||||||
|
float getLineHeight() const { return _lineHeight; }
|
||||||
|
float getLeftMargin() const { return _leftMargin; }
|
||||||
|
float getTopMargin() const { return _topMargin; }
|
||||||
|
float getRightMargin() const { return _rightMargin; }
|
||||||
|
float getBottomMargin() const { return _bottomMargin; }
|
||||||
|
xColor getBackgroundColor();
|
||||||
|
|
||||||
|
// setters
|
||||||
|
void setText(const QString& text) { _text = text; }
|
||||||
|
void setLineHeight(float value) { _lineHeight = value; }
|
||||||
|
void setLeftMargin(float margin) { _leftMargin = margin; }
|
||||||
|
void setTopMargin(float margin) { _topMargin = margin; }
|
||||||
|
void setRightMargin(float margin) { _rightMargin = margin; }
|
||||||
|
void setBottomMargin(float margin) { _bottomMargin = margin; }
|
||||||
|
|
||||||
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void enableClipPlane(GLenum plane, float x, float y, float z, float w);
|
||||||
|
|
||||||
|
QString _text;
|
||||||
|
xColor _backgroundColor;
|
||||||
|
float _lineHeight;
|
||||||
|
float _leftMargin;
|
||||||
|
float _topMargin;
|
||||||
|
float _rightMargin;
|
||||||
|
float _bottomMargin;
|
||||||
|
bool _isFacingAvatar;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_Text3DOverlay_h
|
|
@ -107,7 +107,8 @@ PacketRecord* Endpoint::maybeCreateReceiveRecord() const {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketRecord::PacketRecord(const MetavoxelLOD& lod, const MetavoxelData& data) :
|
PacketRecord::PacketRecord(int packetNumber, const MetavoxelLOD& lod, const MetavoxelData& data) :
|
||||||
|
_packetNumber(packetNumber),
|
||||||
_lod(lod),
|
_lod(lod),
|
||||||
_data(data) {
|
_data(data) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
PacketRecord* baselineReceiveRecord = NULL);
|
PacketRecord* baselineReceiveRecord = NULL);
|
||||||
virtual ~Endpoint();
|
virtual ~Endpoint();
|
||||||
|
|
||||||
const DatagramSequencer& getSequencer() const { return _sequencer; }
|
DatagramSequencer& getSequencer() { return _sequencer; }
|
||||||
|
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ protected slots:
|
||||||
virtual void handleMessage(const QVariant& message, Bitstream& in);
|
virtual void handleMessage(const QVariant& message, Bitstream& in);
|
||||||
|
|
||||||
void recordSend();
|
void recordSend();
|
||||||
void recordReceive();
|
virtual void recordReceive();
|
||||||
|
|
||||||
void clearSendRecordsBefore(int index);
|
virtual void clearSendRecordsBefore(int index);
|
||||||
void clearReceiveRecordsBefore(int index);
|
virtual void clearReceiveRecordsBefore(int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -71,14 +71,16 @@ protected:
|
||||||
class PacketRecord {
|
class PacketRecord {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PacketRecord(const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData());
|
PacketRecord(int packetNumber = 0, const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData());
|
||||||
virtual ~PacketRecord();
|
virtual ~PacketRecord();
|
||||||
|
|
||||||
|
int getPacketNumber() const { return _packetNumber; }
|
||||||
const MetavoxelLOD& getLOD() const { return _lod; }
|
const MetavoxelLOD& getLOD() const { return _lod; }
|
||||||
const MetavoxelData& getData() const { return _data; }
|
const MetavoxelData& getData() const { return _data; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
int _packetNumber;
|
||||||
MetavoxelLOD _lod;
|
MetavoxelLOD _lod;
|
||||||
MetavoxelData _data;
|
MetavoxelData _data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -216,12 +216,71 @@ void MetavoxelClient::applyEdit(const MetavoxelEditMessage& edit, bool reliable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PacketRecord* MetavoxelClient::getAcknowledgedSendRecord(int packetNumber) const {
|
||||||
|
PacketRecord* lastAcknowledged = getLastAcknowledgedSendRecord();
|
||||||
|
if (lastAcknowledged->getPacketNumber() == packetNumber) {
|
||||||
|
return lastAcknowledged;
|
||||||
|
}
|
||||||
|
foreach (PacketRecord* record, _clearedSendRecords) {
|
||||||
|
if (record->getPacketNumber() == packetNumber) {
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketRecord* MetavoxelClient::getAcknowledgedReceiveRecord(int packetNumber) const {
|
||||||
|
PacketRecord* lastAcknowledged = getLastAcknowledgedReceiveRecord();
|
||||||
|
if (lastAcknowledged->getPacketNumber() == packetNumber) {
|
||||||
|
return lastAcknowledged;
|
||||||
|
}
|
||||||
|
foreach (PacketRecord* record, _clearedReceiveRecords) {
|
||||||
|
if (record->getPacketNumber() == packetNumber) {
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelClient::dataChanged(const MetavoxelData& oldData) {
|
void MetavoxelClient::dataChanged(const MetavoxelData& oldData) {
|
||||||
// make thread-safe copy
|
// make thread-safe copy
|
||||||
QWriteLocker locker(&_dataCopyLock);
|
QWriteLocker locker(&_dataCopyLock);
|
||||||
_dataCopy = _data;
|
_dataCopy = _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelClient::recordReceive() {
|
||||||
|
Endpoint::recordReceive();
|
||||||
|
|
||||||
|
// clear the cleared lists
|
||||||
|
foreach (PacketRecord* record, _clearedSendRecords) {
|
||||||
|
delete record;
|
||||||
|
}
|
||||||
|
_clearedSendRecords.clear();
|
||||||
|
|
||||||
|
foreach (PacketRecord* record, _clearedReceiveRecords) {
|
||||||
|
delete record;
|
||||||
|
}
|
||||||
|
_clearedReceiveRecords.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetavoxelClient::clearSendRecordsBefore(int index) {
|
||||||
|
// move to cleared list
|
||||||
|
QList<PacketRecord*>::iterator end = _sendRecords.begin() + index + 1;
|
||||||
|
for (QList<PacketRecord*>::const_iterator it = _sendRecords.begin(); it != end; it++) {
|
||||||
|
_clearedSendRecords.append(*it);
|
||||||
|
}
|
||||||
|
_sendRecords.erase(_sendRecords.begin(), end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetavoxelClient::clearReceiveRecordsBefore(int index) {
|
||||||
|
// move to cleared list
|
||||||
|
QList<PacketRecord*>::iterator end = _receiveRecords.begin() + index + 1;
|
||||||
|
for (QList<PacketRecord*>::const_iterator it = _receiveRecords.begin(); it != end; it++) {
|
||||||
|
_clearedReceiveRecords.append(*it);
|
||||||
|
}
|
||||||
|
_receiveRecords.erase(_receiveRecords.begin(), end);
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelClient::writeUpdateMessage(Bitstream& out) {
|
void MetavoxelClient::writeUpdateMessage(Bitstream& out) {
|
||||||
ClientStateMessage state = { _updater->getLOD() };
|
ClientStateMessage state = { _updater->getLOD() };
|
||||||
out << QVariant::fromValue(state);
|
out << QVariant::fromValue(state);
|
||||||
|
@ -232,7 +291,9 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
|
||||||
if (userType == MetavoxelDeltaMessage::Type) {
|
if (userType == MetavoxelDeltaMessage::Type) {
|
||||||
PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord();
|
PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord();
|
||||||
if (_reliableDeltaChannel) {
|
if (_reliableDeltaChannel) {
|
||||||
_remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _remoteDataLOD = _reliableDeltaLOD);
|
MetavoxelData reference = _remoteData;
|
||||||
|
MetavoxelLOD referenceLOD = _remoteDataLOD;
|
||||||
|
_remoteData.readDelta(reference, referenceLOD, in, _remoteDataLOD = _reliableDeltaLOD);
|
||||||
_sequencer.getInputStream().persistReadMappings(in.getAndResetReadMappings());
|
_sequencer.getInputStream().persistReadMappings(in.getAndResetReadMappings());
|
||||||
in.clearPersistentMappings();
|
in.clearPersistentMappings();
|
||||||
_reliableDeltaChannel = NULL;
|
_reliableDeltaChannel = NULL;
|
||||||
|
@ -255,13 +316,22 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
|
||||||
}
|
}
|
||||||
} else if (userType == MetavoxelDeltaPendingMessage::Type) {
|
} else if (userType == MetavoxelDeltaPendingMessage::Type) {
|
||||||
// check the id to make sure this is not a delta we've already processed
|
// check the id to make sure this is not a delta we've already processed
|
||||||
int id = message.value<MetavoxelDeltaPendingMessage>().id;
|
MetavoxelDeltaPendingMessage pending = message.value<MetavoxelDeltaPendingMessage>();
|
||||||
if (id > _reliableDeltaID) {
|
if (pending.id > _reliableDeltaID) {
|
||||||
_reliableDeltaID = id;
|
_reliableDeltaID = pending.id;
|
||||||
_reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX);
|
_reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX);
|
||||||
_reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream());
|
_reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream());
|
||||||
_reliableDeltaLOD = getLastAcknowledgedSendRecord()->getLOD();
|
PacketRecord* sendRecord = getAcknowledgedSendRecord(pending.receivedPacketNumber);
|
||||||
PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord();
|
if (!sendRecord) {
|
||||||
|
qWarning() << "Missing send record for delta" << pending.receivedPacketNumber;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_reliableDeltaLOD = sendRecord->getLOD();
|
||||||
|
PacketRecord* receiveRecord = getAcknowledgedReceiveRecord(pending.sentPacketNumber);
|
||||||
|
if (!receiveRecord) {
|
||||||
|
qWarning() << "Missing receive record for delta" << pending.sentPacketNumber;
|
||||||
|
return;
|
||||||
|
}
|
||||||
_remoteDataLOD = receiveRecord->getLOD();
|
_remoteDataLOD = receiveRecord->getLOD();
|
||||||
_remoteData = receiveRecord->getData();
|
_remoteData = receiveRecord->getData();
|
||||||
}
|
}
|
||||||
|
@ -271,10 +341,11 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketRecord* MetavoxelClient::maybeCreateSendRecord() const {
|
PacketRecord* MetavoxelClient::maybeCreateSendRecord() const {
|
||||||
return new PacketRecord(_reliableDeltaChannel ? _reliableDeltaLOD : _updater->getLOD());
|
return new PacketRecord(_sequencer.getOutgoingPacketNumber(),
|
||||||
|
_reliableDeltaChannel ? _reliableDeltaLOD : _updater->getLOD());
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketRecord* MetavoxelClient::maybeCreateReceiveRecord() const {
|
PacketRecord* MetavoxelClient::maybeCreateReceiveRecord() const {
|
||||||
return new PacketRecord(_remoteDataLOD, _remoteData);
|
return new PacketRecord(_sequencer.getIncomingPacketNumber(), _remoteDataLOD, _remoteData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,8 +116,16 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
PacketRecord* getAcknowledgedSendRecord(int packetNumber) const;
|
||||||
|
PacketRecord* getAcknowledgedReceiveRecord(int packetNumber) const;
|
||||||
|
|
||||||
virtual void dataChanged(const MetavoxelData& oldData);
|
virtual void dataChanged(const MetavoxelData& oldData);
|
||||||
|
|
||||||
|
virtual void recordReceive();
|
||||||
|
|
||||||
|
virtual void clearSendRecordsBefore(int index);
|
||||||
|
virtual void clearReceiveRecordsBefore(int index);
|
||||||
|
|
||||||
virtual void writeUpdateMessage(Bitstream& out);
|
virtual void writeUpdateMessage(Bitstream& out);
|
||||||
virtual void handleMessage(const QVariant& message, Bitstream& in);
|
virtual void handleMessage(const QVariant& message, Bitstream& in);
|
||||||
|
|
||||||
|
@ -132,9 +140,13 @@ protected:
|
||||||
ReliableChannel* _reliableDeltaChannel;
|
ReliableChannel* _reliableDeltaChannel;
|
||||||
MetavoxelLOD _reliableDeltaLOD;
|
MetavoxelLOD _reliableDeltaLOD;
|
||||||
int _reliableDeltaID;
|
int _reliableDeltaID;
|
||||||
|
QVariant _reliableDeltaMessage;
|
||||||
|
|
||||||
MetavoxelData _dataCopy;
|
MetavoxelData _dataCopy;
|
||||||
QReadWriteLock _dataCopyLock;
|
QReadWriteLock _dataCopyLock;
|
||||||
|
|
||||||
|
QList<PacketRecord*> _clearedSendRecords;
|
||||||
|
QList<PacketRecord*> _clearedReceiveRecords;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_MetavoxelClientManager_h
|
#endif // hifi_MetavoxelClientManager_h
|
||||||
|
|
|
@ -734,6 +734,22 @@ int VoxelMaterialSpannerEditVisitor::visit(MetavoxelInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if there are no visible colors, we can clear everything
|
||||||
|
bool foundOpaque = false;
|
||||||
|
for (const QRgb* src = colorContents.constData(), *end = src + colorContents.size(); src != end; src++) {
|
||||||
|
if (qAlpha(*src) != 0) {
|
||||||
|
foundOpaque = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundOpaque) {
|
||||||
|
info.outputValues[0] = AttributeValue(_outputs.at(0));
|
||||||
|
info.outputValues[1] = AttributeValue(_outputs.at(1));
|
||||||
|
info.outputValues[2] = AttributeValue(_outputs.at(2));
|
||||||
|
return STOP_RECURSION;
|
||||||
|
}
|
||||||
|
|
||||||
VoxelColorDataPointer newColorPointer(new VoxelColorData(colorContents, VOXEL_BLOCK_SAMPLES));
|
VoxelColorDataPointer newColorPointer(new VoxelColorData(colorContents, VOXEL_BLOCK_SAMPLES));
|
||||||
info.outputValues[0] = AttributeValue(info.inputValues.at(0).getAttribute(),
|
info.outputValues[0] = AttributeValue(info.inputValues.at(0).getAttribute(),
|
||||||
encodeInline<VoxelColorDataPointer>(newColorPointer));
|
encodeInline<VoxelColorDataPointer>(newColorPointer));
|
||||||
|
|
|
@ -68,6 +68,8 @@ class MetavoxelDeltaPendingMessage {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
STREAM int id;
|
STREAM int id;
|
||||||
|
STREAM int sentPacketNumber;
|
||||||
|
STREAM int receivedPacketNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaPendingMessage)
|
DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaPendingMessage)
|
||||||
|
|
|
@ -81,7 +81,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
case PacketTypeAudioStreamStats:
|
case PacketTypeAudioStreamStats:
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeMetavoxelData:
|
case PacketTypeMetavoxelData:
|
||||||
return 7;
|
return 8;
|
||||||
case PacketTypeVoxelData:
|
case PacketTypeVoxelData:
|
||||||
return VERSION_VOXELS_HAS_FILE_BREAKS;
|
return VERSION_VOXELS_HAS_FILE_BREAKS;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -58,6 +58,10 @@ glm::vec3 Vec3::normalize(const glm::vec3& v) {
|
||||||
return glm::normalize(v);
|
return glm::normalize(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Vec3::mix(const glm::vec3& v1, const glm::vec3& v2, float m) {
|
||||||
|
return glm::mix(v1, v2, m);
|
||||||
|
}
|
||||||
|
|
||||||
void Vec3::print(const QString& lable, const glm::vec3& v) {
|
void Vec3::print(const QString& lable, const glm::vec3& v) {
|
||||||
qDebug() << qPrintable(lable) << v.x << "," << v.y << "," << v.z;
|
qDebug() << qPrintable(lable) << v.x << "," << v.y << "," << v.z;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ public slots:
|
||||||
float distance(const glm::vec3& v1, const glm::vec3& v2);
|
float distance(const glm::vec3& v1, const glm::vec3& v2);
|
||||||
float orientedAngle(const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3);
|
float orientedAngle(const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3);
|
||||||
glm::vec3 normalize(const glm::vec3& v);
|
glm::vec3 normalize(const glm::vec3& v);
|
||||||
|
glm::vec3 mix(const glm::vec3& v1, const glm::vec3& v2, float m);
|
||||||
void print(const QString& lable, const glm::vec3& v);
|
void print(const QString& lable, const glm::vec3& v);
|
||||||
bool equal(const glm::vec3& v1, const glm::vec3& v2);
|
bool equal(const glm::vec3& v1, const glm::vec3& v2);
|
||||||
};
|
};
|
||||||
|
|
|
@ -603,31 +603,27 @@ int RandomVisitor::visit(MetavoxelInfo& info) {
|
||||||
class TestSendRecord : public PacketRecord {
|
class TestSendRecord : public PacketRecord {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TestSendRecord(const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData(),
|
TestSendRecord(int packetNumber = 0, const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData(),
|
||||||
const SharedObjectPointer& localState = SharedObjectPointer(), int packetNumber = 0);
|
const SharedObjectPointer& localState = SharedObjectPointer());
|
||||||
|
|
||||||
const SharedObjectPointer& getLocalState() const { return _localState; }
|
const SharedObjectPointer& getLocalState() const { return _localState; }
|
||||||
int getPacketNumber() const { return _packetNumber; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
SharedObjectPointer _localState;
|
SharedObjectPointer _localState;
|
||||||
int _packetNumber;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TestSendRecord::TestSendRecord(const MetavoxelLOD& lod, const MetavoxelData& data,
|
TestSendRecord::TestSendRecord(int packetNumber, const MetavoxelLOD& lod, const MetavoxelData& data,
|
||||||
const SharedObjectPointer& localState, int packetNumber) :
|
const SharedObjectPointer& localState) :
|
||||||
PacketRecord(lod, data),
|
PacketRecord(packetNumber, lod, data),
|
||||||
_localState(localState),
|
_localState(localState) {
|
||||||
_packetNumber(packetNumber) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestReceiveRecord : public PacketRecord {
|
class TestReceiveRecord : public PacketRecord {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TestReceiveRecord(const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData(),
|
TestReceiveRecord(int packetNumber = 0, const MetavoxelLOD& lod = MetavoxelLOD(),
|
||||||
const SharedObjectPointer& remoteState = SharedObjectPointer());
|
const MetavoxelData& data = MetavoxelData(), const SharedObjectPointer& remoteState = SharedObjectPointer());
|
||||||
|
|
||||||
const SharedObjectPointer& getRemoteState() const { return _remoteState; }
|
const SharedObjectPointer& getRemoteState() const { return _remoteState; }
|
||||||
|
|
||||||
|
@ -636,9 +632,9 @@ private:
|
||||||
SharedObjectPointer _remoteState;
|
SharedObjectPointer _remoteState;
|
||||||
};
|
};
|
||||||
|
|
||||||
TestReceiveRecord::TestReceiveRecord(const MetavoxelLOD& lod,
|
TestReceiveRecord::TestReceiveRecord(int packetNumber, const MetavoxelLOD& lod,
|
||||||
const MetavoxelData& data, const SharedObjectPointer& remoteState) :
|
const MetavoxelData& data, const SharedObjectPointer& remoteState) :
|
||||||
PacketRecord(lod, data),
|
PacketRecord(packetNumber, lod, data),
|
||||||
_remoteState(remoteState) {
|
_remoteState(remoteState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,14 +1106,14 @@ void TestEndpoint::handleMessage(const QVariant& message, Bitstream& in) {
|
||||||
|
|
||||||
PacketRecord* TestEndpoint::maybeCreateSendRecord() const {
|
PacketRecord* TestEndpoint::maybeCreateSendRecord() const {
|
||||||
if (_reliableDeltaChannel) {
|
if (_reliableDeltaChannel) {
|
||||||
return new TestSendRecord(_reliableDeltaLOD, _reliableDeltaData, _localState, _sequencer.getOutgoingPacketNumber());
|
return new TestSendRecord(_sequencer.getOutgoingPacketNumber(), _reliableDeltaLOD, _reliableDeltaData, _localState);
|
||||||
}
|
}
|
||||||
return new TestSendRecord(_lod, (_mode == METAVOXEL_CLIENT_MODE) ? MetavoxelData() : _data,
|
return new TestSendRecord(_sequencer.getOutgoingPacketNumber(), _lod,
|
||||||
_localState, _sequencer.getOutgoingPacketNumber());
|
(_mode == METAVOXEL_CLIENT_MODE) ? MetavoxelData() : _data, _localState);
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketRecord* TestEndpoint::maybeCreateReceiveRecord() const {
|
PacketRecord* TestEndpoint::maybeCreateReceiveRecord() const {
|
||||||
return new TestReceiveRecord(_remoteDataLOD, _remoteData, _remoteState);
|
return new TestReceiveRecord(_sequencer.getIncomingPacketNumber(), _remoteDataLOD, _remoteData, _remoteState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestEndpoint::handleHighPriorityMessage(const QVariant& message) {
|
void TestEndpoint::handleHighPriorityMessage(const QVariant& message) {
|
||||||
|
|
Loading…
Reference in a new issue