Merge branch 'master' into oculus_old_renderer

This commit is contained in:
Bradley Austin Davis 2015-04-01 09:09:06 -07:00
commit e520a62bcf
18 changed files with 169 additions and 77 deletions

View file

@ -180,7 +180,7 @@ void AssignmentClientMonitor::readPendingDatagrams() {
senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) {
if (!packetUUID.isNull()) { if (!packetUUID.isNull()) {
matchingNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode matchingNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode
(packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false); (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false);
AssignmentClientChildData *childData = new AssignmentClientChildData("unknown"); AssignmentClientChildData *childData = new AssignmentClientChildData("unknown");
matchingNode->setLinkedData(childData); matchingNode->setLinkedData(childData);
} else { } else {

View file

@ -95,6 +95,13 @@
"can_set": true "can_set": true
} }
] ]
},
{
"name": "editors_are_rezzers",
"type": "checkbox",
"label": "Only editors can create new entities",
"help": "When checked, only those who can edit the domain can create new entites.",
"default": false
} }
] ]
}, },

View file

@ -47,6 +47,7 @@ const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io";
const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users"; const QString ALLOWED_USERS_SETTINGS_KEYPATH = "security.allowed_users";
const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity"; const QString MAXIMUM_USER_CAPACITY = "security.maximum_user_capacity";
const QString ALLOWED_EDITORS_SETTINGS_KEYPATH = "security.allowed_editors"; const QString ALLOWED_EDITORS_SETTINGS_KEYPATH = "security.allowed_editors";
const QString EDITORS_ARE_REZZERS_KEYPATH = "security.editors_are_rezzers";
DomainServer::DomainServer(int argc, char* argv[]) : DomainServer::DomainServer(int argc, char* argv[]) :
@ -646,9 +647,23 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock
QStringList allowedEditors = allowedEditorsVariant ? allowedEditorsVariant->toStringList() : QStringList(); QStringList allowedEditors = allowedEditorsVariant ? allowedEditorsVariant->toStringList() : QStringList();
bool canAdjustLocks = allowedEditors.isEmpty() || allowedEditors.contains(username); bool canAdjustLocks = allowedEditors.isEmpty() || allowedEditors.contains(username);
const QVariant* editorsAreRezzersVariant =
valueForKeyPath(_settingsManager.getSettingsMap(), EDITORS_ARE_REZZERS_KEYPATH);
bool onlyEditorsAreRezzers = false;
if (editorsAreRezzersVariant) {
onlyEditorsAreRezzers = editorsAreRezzersVariant->toBool();
}
bool canRez = true;
if (onlyEditorsAreRezzers) {
canRez = canAdjustLocks;
}
SharedNodePointer newNode = SharedNodePointer newNode =
DependencyManager::get<LimitedNodeList>()->addOrUpdateNode(nodeUUID, nodeType, DependencyManager::get<LimitedNodeList>()->addOrUpdateNode(nodeUUID, nodeType,
publicSockAddr, localSockAddr, canAdjustLocks); publicSockAddr, localSockAddr,
canAdjustLocks, canRez);
// when the newNode is created the linked data is also created // when the newNode is created the linked data is also created
// if this was a static assignment set the UUID, set the sendingSockAddr // if this was a static assignment set the UUID, set the sendingSockAddr
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData()); DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData());
@ -903,6 +918,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append); QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
broadcastDataStream << node->getUUID(); broadcastDataStream << node->getUUID();
broadcastDataStream << node->getCanAdjustLocks(); broadcastDataStream << node->getCanAdjustLocks();
broadcastDataStream << node->getCanRez();
int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos(); int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos();

View file

@ -90,44 +90,49 @@ var score = 0;
var bulletID = false; var bulletID = false;
var targetID = false; var targetID = false;
// Create a reticle image in center of screen // Create overlay buttons and reticle
var BUTTON_SIZE = 32;
var PADDING = 3;
var NUM_BUTTONS = 3;
var screenSize = Controller.getViewportDimensions(); var screenSize = Controller.getViewportDimensions();
var startX = screenSize.x / 2 - (NUM_BUTTONS * (BUTTON_SIZE + PADDING)) / 2;
var reticle = Overlays.addOverlay("image", { var reticle = Overlays.addOverlay("image", {
x: screenSize.x / 2 - 16, x: screenSize.x / 2 - (BUTTON_SIZE / 2),
y: screenSize.y / 2 - 16, y: screenSize.y / 2 - (BUTTON_SIZE / 2),
width: 32, width: BUTTON_SIZE,
height: 32, height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/billiardsReticle.png", imageURL: HIFI_PUBLIC_BUCKET + "images/billiardsReticle.png",
color: { red: 255, green: 255, blue: 255},
alpha: 1 alpha: 1
}); });
var offButton = Overlays.addOverlay("image", { var offButton = Overlays.addOverlay("image", {
x: screenSize.x - 48, x: startX,
y: 96, y: screenSize.y - (BUTTON_SIZE + PADDING),
width: 32, width: BUTTON_SIZE,
height: 32, height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/close.png", imageURL: HIFI_PUBLIC_BUCKET + "images/close.png",
color: { red: 255, green: 255, blue: 255}, alpha: 1
});
startX += BUTTON_SIZE + PADDING;
var platformButton = Overlays.addOverlay("image", {
x: startX,
y: screenSize.y - (BUTTON_SIZE + PADDING),
width: BUTTON_SIZE,
height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/city.png",
alpha: 1 alpha: 1
}); });
var platformButton = Overlays.addOverlay("image", { startX += BUTTON_SIZE + PADDING;
x: screenSize.x - 48,
y: 130,
width: 32,
height: 32,
imageURL: HIFI_PUBLIC_BUCKET + "images/city.png",
color: { red: 255, green: 255, blue: 255},
alpha: 1
});
var gridButton = Overlays.addOverlay("image", { var gridButton = Overlays.addOverlay("image", {
x: screenSize.x - 48, x: startX,
y: 164, y: screenSize.y - (BUTTON_SIZE + PADDING),
width: 32, width: BUTTON_SIZE,
height: 32, height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/blocks.png", imageURL: HIFI_PUBLIC_BUCKET + "images/blocks.png",
color: { red: 255, green: 255, blue: 255},
alpha: 1 alpha: 1
}); });
@ -282,7 +287,7 @@ function makePlatform(gravity, scale, size) {
z: pos.z - (separation * size / 2.0) + z * separation }, z: pos.z - (separation * size / 2.0) + z * separation },
dimensions: dimensions, dimensions: dimensions,
color: { red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255 }, color: { red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255 },
velocity: { x: 0, y: 0, z: 0 }, velocity: { x: 0, y: 0.05, z: 0 },
gravity: { x: 0, y: gravity, z: 0 }, gravity: { x: 0, y: gravity, z: 0 },
lifetime: TARGET_LIFE, lifetime: TARGET_LIFE,
damping: 0.1, damping: 0.1,
@ -297,7 +302,7 @@ function makePlatform(gravity, scale, size) {
type: "Box", type: "Box",
position: { x: pos.x, y: pos.y - separation / 2.0, z: pos.z }, position: { x: pos.x, y: pos.y - separation / 2.0, z: pos.z },
dimensions: { x: 2.0 * separation * size, y: separation / 2.0, z: 2.0 * separation * size }, dimensions: { x: 2.0 * separation * size, y: separation / 2.0, z: 2.0 * separation * size },
color: { red: 128, green: 128, blue: 128 }, color: { red: 100, green: 100, blue: 100 },
lifetime: TARGET_LIFE lifetime: TARGET_LIFE
}); });

View file

@ -23,21 +23,27 @@ HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
var rollSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/dice/diceRoll.wav"); var rollSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/dice/diceRoll.wav");
var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to create new objects."
var screenSize = Controller.getViewportDimensions(); var screenSize = Controller.getViewportDimensions();
var BUTTON_SIZE = 32;
var PADDING = 3;
var offButton = Overlays.addOverlay("image", { var offButton = Overlays.addOverlay("image", {
x: screenSize.x - 48, x: screenSize.x / 2 - BUTTON_SIZE,
y: 96, y: screenSize.y- (BUTTON_SIZE + PADDING),
width: 32, width: BUTTON_SIZE,
height: 32, height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/close.png", imageURL: HIFI_PUBLIC_BUCKET + "images/close.png",
color: { red: 255, green: 255, blue: 255}, color: { red: 255, green: 255, blue: 255},
alpha: 1 alpha: 1
}); });
var diceButton = Overlays.addOverlay("image", { var diceButton = Overlays.addOverlay("image", {
x: screenSize.x - 48, x: screenSize.x / 2 + PADDING,
y: 130, y: screenSize.y - (BUTTON_SIZE + PADDING),
width: 32, width: BUTTON_SIZE,
height: 32, height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/die.png", imageURL: HIFI_PUBLIC_BUCKET + "images/die.png",
color: { red: 255, green: 255, blue: 255}, color: { red: 255, green: 255, blue: 255},
alpha: 1 alpha: 1
@ -48,21 +54,28 @@ var LIFETIME = 300;
// NOTE: angularVelocity is in radians/sec // NOTE: angularVelocity is in radians/sec
var MAX_ANGULAR_SPEED = Math.PI; var MAX_ANGULAR_SPEED = Math.PI;
function shootDice(position, velocity) { function shootDice(position, velocity) {
for (var i = 0; i < NUMBER_OF_DICE; i++) { if (!Entities.canRez()) {
dice.push(Entities.addEntity( Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
{ type: "Model", } else {
modelURL: HIFI_PUBLIC_BUCKET + "models/props/Dice/goldDie.fbx", for (var i = 0; i < NUMBER_OF_DICE; i++) {
position: position, dice.push(Entities.addEntity(
velocity: velocity, { type: "Model",
rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360), modelURL: HIFI_PUBLIC_BUCKET + "models/props/Dice/goldDie.fbx",
angularVelocity: { x: Math.random() * MAX_ANGULAR_SPEED, y: Math.random() * MAX_ANGULAR_SPEED, z: Math.random() * MAX_ANGULAR_SPEED }, position: position,
lifetime: LIFETIME, velocity: velocity,
gravity: { x: 0, y: GRAVITY, z: 0 }, rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360),
shapeType: "box", angularVelocity: { x: Math.random() * MAX_ANGULAR_SPEED,
collisionsWillMove: true y: Math.random() * MAX_ANGULAR_SPEED,
})); z: Math.random() * MAX_ANGULAR_SPEED },
position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation())))); lifetime: LIFETIME,
gravity: { x: 0, y: GRAVITY, z: 0 },
shapeType: "box",
collisionsWillMove: true
}));
position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation()))));
}
} }
} }
@ -92,7 +105,7 @@ function mousePressEvent(event) {
var clickedText = false; var clickedText = false;
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
if (clickedOverlay == offButton) { if (clickedOverlay == offButton) {
deleteDice(); Script.stop();
} else if (clickedOverlay == diceButton) { } else if (clickedOverlay == diceButton) {
var HOW_HARD = 2.0; var HOW_HARD = 2.0;
var position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation())); var position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation()));

View file

@ -132,7 +132,7 @@
this.updateLightIDInUserData(); this.updateLightIDInUserData();
} else { } else {
var that = this; var that = this;
Script.setTimeout(function() { that.maybeUpdateLightIDInUserData() }, 500); Script.setTimeout(function() { that.maybeUpdateLightIDInUserData() }, 500);
} }
} }
@ -213,6 +213,10 @@
this.preload = function(entityID) { this.preload = function(entityID) {
this.preOperation(entityID); this.preOperation(entityID);
}; };
this.unload = function(){
Entities.deleteEntity(this.lightID);
}
this.clickReleaseOnEntity = function(entityID, mouseEvent) { this.clickReleaseOnEntity = function(entityID, mouseEvent) {
this.preOperation(entityID); this.preOperation(entityID);

View file

@ -24,6 +24,7 @@
#include "LoginDialog.h" #include "LoginDialog.h"
#include "UIUtil.h" #include "UIUtil.h"
const QString CREATE_ACCOUNT_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/create";
const QString FORGOT_PASSWORD_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/users/password/new"; const QString FORGOT_PASSWORD_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/users/password/new";
LoginDialog::LoginDialog(QWidget* parent) : LoginDialog::LoginDialog(QWidget* parent) :
@ -45,6 +46,7 @@ LoginDialog::LoginDialog(QWidget* parent) :
this, &LoginDialog::close); this, &LoginDialog::close);
UIUtil::scaleWidgetFontSizes(this); UIUtil::scaleWidgetFontSizes(this);
_ui->accountLabel->setText(_ui->accountLabel->text().arg(CREATE_ACCOUNT_URL, FORGOT_PASSWORD_URL));
// Initialize toggle connection // Initialize toggle connection
toggleQAction(); toggleQAction();

View file

@ -447,7 +447,7 @@ border-radius: 4px; padding-top: 1px;</string>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="accountLabel">
<property name="font"> <property name="font">
<font> <font>
<family>Helvetica,Arial,sans-serif</family> <family>Helvetica,Arial,sans-serif</family>
@ -456,9 +456,12 @@ border-radius: 4px; padding-top: 1px;</string>
</property> </property>
<property name="text"> <property name="text">
<string>&lt;style type=&quot;text/css&quot;&gt; <string>&lt;style type=&quot;text/css&quot;&gt;
a { text-decoration: none; color: #267077;} a { text-decoration: none; color: #267077; margin:0;padding:0;}
#create {font-weight:bold;}
p {margin:5px 0;}
&lt;/style&gt; &lt;/style&gt;
&lt;a href=&quot;https://metaverse.highfidelity.com/password/new&quot;&gt;Recover password?&lt;/a&gt;</string> &lt;p&gt;&lt;a id=&quot;create&quot; href=&quot;%1&quot;&gt;Create account&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;%2&quot;&gt;Recover password&lt;/a&gt;&lt;/p&gt;</string>
</property> </property>
<property name="openExternalLinks"> <property name="openExternalLinks">
<bool>true</bool> <bool>true</bool>

View file

@ -23,6 +23,7 @@ EntityScriptingInterface::EntityScriptingInterface() :
{ {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &NodeList::canAdjustLocksChanged, this, &EntityScriptingInterface::canAdjustLocksChanged); connect(nodeList.data(), &NodeList::canAdjustLocksChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptingInterface::canRezChanged);
} }
void EntityScriptingInterface::queueEntityMessage(PacketType packetType, void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
@ -30,12 +31,15 @@ void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties); getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties);
} }
bool EntityScriptingInterface::canAdjustLocks() { bool EntityScriptingInterface::canAdjustLocks() {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
return nodeList->getThisNodeCanAdjustLocks(); return nodeList->getThisNodeCanAdjustLocks();
} }
bool EntityScriptingInterface::canRez() {
auto nodeList = DependencyManager::get<NodeList>();
return nodeList->getThisNodeCanRez();
}
void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) { void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) {
if (_entityTree) { if (_entityTree) {

View file

@ -66,6 +66,9 @@ public slots:
// returns true if the DomainServer will allow this Node/Avatar to make changes // returns true if the DomainServer will allow this Node/Avatar to make changes
Q_INVOKABLE bool canAdjustLocks(); Q_INVOKABLE bool canAdjustLocks();
// returns true if the DomainServer will allow this Node/Avatar to rez new entities
Q_INVOKABLE bool canRez();
/// adds a model with the specific properties /// adds a model with the specific properties
Q_INVOKABLE EntityItemID addEntity(const EntityItemProperties& properties); Q_INVOKABLE EntityItemID addEntity(const EntityItemProperties& properties);
@ -117,6 +120,7 @@ signals:
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
void canAdjustLocksChanged(bool canAdjustLocks); void canAdjustLocksChanged(bool canAdjustLocks);
void canRezChanged(bool canRez);
void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event); void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);

View file

@ -659,12 +659,14 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
qDebug() << "User attempted to edit an unknown entity. ID:" << entityItemID; qDebug() << "User attempted to edit an unknown entity. ID:" << entityItemID;
} }
} else { } else {
// this is a new entity... assign a new entityID if (senderNode->getCanRez()) {
entityItemID = assignEntityID(entityItemID); // this is a new entity... assign a new entityID
EntityItem* newEntity = addEntity(entityItemID, properties); entityItemID = assignEntityID(entityItemID);
if (newEntity) { EntityItem* newEntity = addEntity(entityItemID, properties);
newEntity->markAsChangedOnServer(); if (newEntity) {
notifyNewlyCreatedEntity(*newEntity, senderNode); newEntity->markAsChangedOnServer();
notifyNewlyCreatedEntity(*newEntity, senderNode);
}
} }
} }
} }

View file

@ -47,7 +47,8 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short
_publicSockAddr(), _publicSockAddr(),
_stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT), _stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT),
_packetStatTimer(), _packetStatTimer(),
_thisNodeCanAdjustLocks(false) _thisNodeCanAdjustLocks(false),
_thisNodeCanRez(true)
{ {
static bool firstCall = true; static bool firstCall = true;
if (firstCall) { if (firstCall) {
@ -106,6 +107,13 @@ void LimitedNodeList::setThisNodeCanAdjustLocks(bool canAdjustLocks) {
} }
} }
void LimitedNodeList::setThisNodeCanRez(bool canRez) {
if (_thisNodeCanRez != canRez) {
_thisNodeCanRez = canRez;
emit canRezChanged(canRez);
}
}
QUdpSocket& LimitedNodeList::getDTLSSocket() { QUdpSocket& LimitedNodeList::getDTLSSocket() {
if (!_dtlsSocket) { if (!_dtlsSocket) {
// DTLS socket getter called but no DTLS socket exists, create it now // DTLS socket getter called but no DTLS socket exists, create it now
@ -415,7 +423,7 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) {
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
bool canAdjustLocks) { bool canAdjustLocks, bool canRez) {
NodeHash::const_iterator it = _nodeHash.find(uuid); NodeHash::const_iterator it = _nodeHash.find(uuid);
if (it != _nodeHash.end()) { if (it != _nodeHash.end()) {
@ -424,11 +432,12 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
matchingNode->setPublicSocket(publicSocket); matchingNode->setPublicSocket(publicSocket);
matchingNode->setLocalSocket(localSocket); matchingNode->setLocalSocket(localSocket);
matchingNode->setCanAdjustLocks(canAdjustLocks); matchingNode->setCanAdjustLocks(canAdjustLocks);
matchingNode->setCanRez(canRez);
return matchingNode; return matchingNode;
} else { } else {
// we didn't have this node, so add them // we didn't have this node, so add them
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks); Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket, canAdjustLocks, canRez);
SharedNodePointer newNodePointer(newNode); SharedNodePointer newNodePointer(newNode);
_nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer)); _nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodePointer));

View file

@ -84,6 +84,9 @@ public:
bool getThisNodeCanAdjustLocks() const { return _thisNodeCanAdjustLocks; } bool getThisNodeCanAdjustLocks() const { return _thisNodeCanAdjustLocks; }
void setThisNodeCanAdjustLocks(bool canAdjustLocks); void setThisNodeCanAdjustLocks(bool canAdjustLocks);
bool getThisNodeCanRez() const { return _thisNodeCanRez; }
void setThisNodeCanRez(bool canRez);
void rebindNodeSocket(); void rebindNodeSocket();
QUdpSocket& getNodeSocket() { return _nodeSocket; } QUdpSocket& getNodeSocket() { return _nodeSocket; }
@ -114,7 +117,8 @@ public:
SharedNodePointer sendingNodeForPacket(const QByteArray& packet); SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks); const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
bool canAdjustLocks, bool canRez);
const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; } const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; }
const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; } const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; }
@ -206,6 +210,7 @@ signals:
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr); void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
void canAdjustLocksChanged(bool canAdjustLocks); void canAdjustLocksChanged(bool canAdjustLocks);
void canRezChanged(bool canRez);
void dataSent(const quint8 channel_type, const int bytes); void dataSent(const quint8 channel_type, const int bytes);
void dataReceived(const quint8 channel_type, const int bytes); void dataReceived(const quint8 channel_type, const int bytes);
@ -241,6 +246,7 @@ protected:
QElapsedTimer _packetStatTimer; QElapsedTimer _packetStatTimer;
bool _thisNodeCanAdjustLocks; bool _thisNodeCanAdjustLocks;
bool _thisNodeCanRez;
template<typename IteratorLambda> template<typename IteratorLambda>
void eachNodeHashIterator(IteratorLambda functor) { void eachNodeHashIterator(IteratorLambda functor) {

View file

@ -41,7 +41,7 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) {
} }
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
const HifiSockAddr& localSocket, bool canAdjustLocks) : const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez) :
NetworkPeer(uuid, publicSocket, localSocket), NetworkPeer(uuid, publicSocket, localSocket),
_type(type), _type(type),
_activeSocket(NULL), _activeSocket(NULL),
@ -53,7 +53,8 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
_clockSkewUsec(0), _clockSkewUsec(0),
_mutex(), _mutex(),
_clockSkewMovingPercentile(30, 0.8f), // moving 80th percentile of 30 samples _clockSkewMovingPercentile(30, 0.8f), // moving 80th percentile of 30 samples
_canAdjustLocks(canAdjustLocks) _canAdjustLocks(canAdjustLocks),
_canRez(canRez)
{ {
} }
@ -133,6 +134,7 @@ QDataStream& operator<<(QDataStream& out, const Node& node) {
out << node._publicSocket; out << node._publicSocket;
out << node._localSocket; out << node._localSocket;
out << node._canAdjustLocks; out << node._canAdjustLocks;
out << node._canRez;
return out; return out;
} }
@ -143,6 +145,7 @@ QDataStream& operator>>(QDataStream& in, Node& node) {
in >> node._publicSocket; in >> node._publicSocket;
in >> node._localSocket; in >> node._localSocket;
in >> node._canAdjustLocks; in >> node._canAdjustLocks;
in >> node._canRez;
return in; return in;
} }

View file

@ -45,7 +45,7 @@ class Node : public NetworkPeer {
Q_OBJECT Q_OBJECT
public: public:
Node(const QUuid& uuid, NodeType_t type, Node(const QUuid& uuid, NodeType_t type,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks); const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, bool canAdjustLocks, bool canRez);
~Node(); ~Node();
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; } bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
@ -79,6 +79,9 @@ public:
void setCanAdjustLocks(bool canAdjustLocks) { _canAdjustLocks = canAdjustLocks; } void setCanAdjustLocks(bool canAdjustLocks) { _canAdjustLocks = canAdjustLocks; }
bool getCanAdjustLocks() { return _canAdjustLocks; } bool getCanAdjustLocks() { return _canAdjustLocks; }
void setCanRez(bool canRez) { _canRez = canRez; }
bool getCanRez() { return _canRez; }
void activatePublicSocket(); void activatePublicSocket();
void activateLocalSocket(); void activateLocalSocket();
@ -105,6 +108,7 @@ private:
QMutex _mutex; QMutex _mutex;
MovingPercentile _clockSkewMovingPercentile; MovingPercentile _clockSkewMovingPercentile;
bool _canAdjustLocks; bool _canAdjustLocks;
bool _canRez;
}; };
QDebug operator<<(QDebug debug, const Node &message); QDebug operator<<(QDebug debug, const Node &message);

View file

@ -403,6 +403,10 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
bool thisNodeCanAdjustLocks; bool thisNodeCanAdjustLocks;
packetStream >> thisNodeCanAdjustLocks; packetStream >> thisNodeCanAdjustLocks;
setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks); setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks);
bool thisNodeCanRez;
packetStream >> thisNodeCanRez;
setThisNodeCanRez(thisNodeCanRez);
// pull each node in the packet // pull each node in the packet
while(packetStream.device()->pos() < packet.size()) { while(packetStream.device()->pos() < packet.size()) {
@ -411,8 +415,9 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
QUuid nodeUUID, connectionUUID; QUuid nodeUUID, connectionUUID;
HifiSockAddr nodePublicSocket, nodeLocalSocket; HifiSockAddr nodePublicSocket, nodeLocalSocket;
bool canAdjustLocks; bool canAdjustLocks;
bool canRez;
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canAdjustLocks; packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> canAdjustLocks >> canRez;
// if the public socket address is 0 then it's reachable at the same IP // if the public socket address is 0 then it's reachable at the same IP
// as the domain server // as the domain server
@ -420,7 +425,8 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
nodePublicSocket.setAddress(_domainHandler.getIP()); nodePublicSocket.setAddress(_domainHandler.getIP());
} }
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket, canAdjustLocks); SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket,
nodeLocalSocket, canAdjustLocks, canRez);
packetStream >> connectionUUID; packetStream >> connectionUUID;
node->setConnectionSecret(connectionUUID); node->setConnectionSecret(connectionUUID);

View file

@ -64,7 +64,7 @@ PacketVersion versionForPacketType(PacketType type) {
return 2; return 2;
case PacketTypeDomainList: case PacketTypeDomainList:
case PacketTypeDomainListRequest: case PacketTypeDomainListRequest:
return 4; return 5;
case PacketTypeCreateAssignment: case PacketTypeCreateAssignment:
case PacketTypeRequestAssignment: case PacketTypeRequestAssignment:
return 2; return 2;

View file

@ -212,6 +212,9 @@ btVector3 CharacterController::perpindicularComponent(const btVector3& direction
} }
const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f);
const float DEFAULT_GRAVITY = 5.0f;
const float TERMINAL_VELOCITY = 55.0f;
const float JUMP_SPEED = 5.0f;
CharacterController::CharacterController(AvatarData* avatarData) { CharacterController::CharacterController(AvatarData* avatarData) {
assert(avatarData); assert(avatarData);
@ -226,9 +229,9 @@ CharacterController::CharacterController(AvatarData* avatarData) {
_velocityTimeInterval = 0.0f; _velocityTimeInterval = 0.0f;
_verticalVelocity = 0.0f; _verticalVelocity = 0.0f;
_verticalOffset = 0.0f; _verticalOffset = 0.0f;
_gravity = 5.0f; // slower than Earth's _gravity = DEFAULT_GRAVITY; // slower than Earth's
_maxFallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s. _maxFallSpeed = TERMINAL_VELOCITY; // Terminal velocity of a sky diver in m/s.
_jumpSpeed = 5.0f; _jumpSpeed = JUMP_SPEED;
_isOnGround = false; _isOnGround = false;
_isJumping = false; _isJumping = false;
_isHovering = true; _isHovering = true;
@ -350,6 +353,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
return penetration; return penetration;
} }
void CharacterController::scanDown(btCollisionWorld* world) { void CharacterController::scanDown(btCollisionWorld* world) {
// we test with downward raycast and if we don't find floor close enough then turn on "hover" // we test with downward raycast and if we don't find floor close enough then turn on "hover"
btKinematicClosestNotMeRayResultCallback callback(_ghostObject); btKinematicClosestNotMeRayResultCallback callback(_ghostObject);