mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 16:02:08 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into orange
This commit is contained in:
commit
b74a1af5ba
9 changed files with 197 additions and 48 deletions
|
@ -109,7 +109,14 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
|||
// set the sending sock addr and node interest set on this node
|
||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
nodeData->setSendingSockAddr(message->getSenderSockAddr());
|
||||
nodeData->setNodeInterestSet(nodeConnection.interestList.toSet());
|
||||
|
||||
// guard against patched agents asking to hear about other agents
|
||||
auto safeInterestSet = nodeConnection.interestList.toSet();
|
||||
if (nodeConnection.nodeType == NodeType::Agent) {
|
||||
safeInterestSet.remove(NodeType::Agent);
|
||||
}
|
||||
|
||||
nodeData->setNodeInterestSet(safeInterestSet);
|
||||
nodeData->setPlaceName(nodeConnection.placeName);
|
||||
|
||||
// signal that we just connected a node so the DomainServer can get it a list
|
||||
|
|
|
@ -843,7 +843,14 @@ void DomainServer::processListRequestPacket(QSharedPointer<ReceivedMessage> mess
|
|||
|
||||
// update the NodeInterestSet in case there have been any changes
|
||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(sendingNode->getLinkedData());
|
||||
nodeData->setNodeInterestSet(nodeRequestData.interestList.toSet());
|
||||
|
||||
// guard against patched agents asking to hear about other agents
|
||||
auto safeInterestSet = nodeRequestData.interestList.toSet();
|
||||
if (sendingNode->getType() == NodeType::Agent) {
|
||||
safeInterestSet.remove(NodeType::Agent);
|
||||
}
|
||||
|
||||
nodeData->setNodeInterestSet(safeInterestSet);
|
||||
|
||||
// update the connecting hostname in case it has changed
|
||||
nodeData->setPlaceName(nodeRequestData.placeName);
|
||||
|
@ -950,7 +957,8 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
if (nodeData->isAuthenticated()) {
|
||||
// if this authenticated node has any interest types, send back those nodes as well
|
||||
limitedNodeList->eachNode([&](const SharedNodePointer& otherNode){
|
||||
if (otherNode->getUUID() != node->getUUID() && nodeInterestSet.contains(otherNode->getType())) {
|
||||
if (otherNode->getUUID() != node->getUUID()
|
||||
&& nodeInterestSet.contains(otherNode->getType())) {
|
||||
|
||||
// since we're about to add a node to the packet we start a segment
|
||||
domainListPackets->startSegment();
|
||||
|
|
|
@ -37,7 +37,17 @@ static int cameraModeId = qRegisterMetaType<CameraMode>();
|
|||
|
||||
class Camera : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @namespace Camera
|
||||
* @property position {Vec3} The position of the camera.
|
||||
* @property orientation {Quat} The orientation of the camera.
|
||||
* @property mode {string} The current camera mode.
|
||||
* @property cameraEntity {EntityID} The position and rotation properties of
|
||||
* the entity specified by this ID are then used as the camera's position and
|
||||
* orientation. Only works when <code>mode</code> is "entity".
|
||||
* @property frustum {Object} The frustum of the camera.
|
||||
*/
|
||||
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
|
||||
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
|
||||
Q_PROPERTY(QString mode READ getModeString WRITE setModeString)
|
||||
|
@ -47,13 +57,13 @@ class Camera : public QObject {
|
|||
public:
|
||||
Camera();
|
||||
|
||||
void initialize(); // instantly put the camera at the ideal position and orientation.
|
||||
void initialize(); // instantly put the camera at the ideal position and orientation.
|
||||
|
||||
void update( float deltaTime );
|
||||
|
||||
CameraMode getMode() const { return _mode; }
|
||||
void setMode(CameraMode m);
|
||||
|
||||
|
||||
void loadViewFrustum(ViewFrustum& frustum) const;
|
||||
ViewFrustum toViewFrustum() const;
|
||||
|
||||
|
@ -80,20 +90,44 @@ public slots:
|
|||
QUuid getCameraEntity() const;
|
||||
void setCameraEntity(QUuid entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Compute a {PickRay} based on the current camera configuration and the position x,y on the screen.
|
||||
* @function Camera.computePickRay
|
||||
* @param {float} x X-coordinate on screen.
|
||||
* @param {float} y Y-coordinate on screen.
|
||||
* @return {PickRay} The computed {PickRay}.
|
||||
*/
|
||||
PickRay computePickRay(float x, float y);
|
||||
|
||||
// These only work on independent cameras
|
||||
/// one time change to what the camera is looking at
|
||||
void lookAt(const glm::vec3& value);
|
||||
/**jsdoc
|
||||
* Set the camera to look at position <code>position</code>. Only works while in <code>independent</code>.
|
||||
* camera mode.
|
||||
* @function Camera.lookAt
|
||||
* @param {Vec3} Position Position to look at.
|
||||
*/
|
||||
void lookAt(const glm::vec3& position);
|
||||
|
||||
/// fix what the camera is looking at, and keep the camera looking at this even if position changes
|
||||
void keepLookingAt(const glm::vec3& value);
|
||||
/**jsdoc
|
||||
* Set the camera to continue looking at position <code>position</code>.
|
||||
* Only works while in `independent` camera mode.
|
||||
* @function Camera.keepLookingAt
|
||||
* @param {Vec3} position Position to keep looking at.
|
||||
*/
|
||||
void keepLookingAt(const glm::vec3& position);
|
||||
|
||||
/// stops the keep looking at feature, doesn't change what's being looked at, but will stop camera from
|
||||
/// continuing to update it's orientation to keep looking at the item
|
||||
/**jsdoc
|
||||
* Stops the camera from continually looking at a position that was set with
|
||||
* `keepLookingAt`
|
||||
* @function Camera.stopLookingAt
|
||||
*/
|
||||
void stopLooking() { _isKeepLookingAt = false; }
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Triggered when camera mode has changed.
|
||||
* @function Camera.modeUpdated
|
||||
* @return {Signal}
|
||||
*/
|
||||
void modeUpdated(const QString& newMode);
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
/**jsdoc
|
||||
* @namespace Clipboard
|
||||
*/
|
||||
class ClipboardScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -21,13 +24,47 @@ public:
|
|||
signals:
|
||||
void readyToImport();
|
||||
|
||||
public slots:
|
||||
glm::vec3 getContentsDimensions(); /// returns the overall dimensions of everything on the blipboard
|
||||
float getClipboardContentsLargestDimension(); /// returns the largest dimension of everything on the clipboard
|
||||
bool importEntities(const QString& filename);
|
||||
bool exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs);
|
||||
bool exportEntities(const QString& filename, float x, float y, float z, float s);
|
||||
QVector<EntityItemID> pasteEntities(glm::vec3 position);
|
||||
public:
|
||||
/**jsdoc
|
||||
* @function Clipboard.getContentsDimensions
|
||||
* @return {Vec3} The extents of the contents held in the clipboard.
|
||||
*/
|
||||
Q_INVOKABLE glm::vec3 getContentsDimensions();
|
||||
|
||||
/**jsdoc
|
||||
* Compute largest dimension of the extents of the contents held in the clipboard
|
||||
* @function Clipboard.getClipboardContentsLargestDimension
|
||||
* @return {float} The largest dimension computed.
|
||||
*/
|
||||
Q_INVOKABLE float getClipboardContentsLargestDimension();
|
||||
|
||||
/**jsdoc
|
||||
* Import entities from a .json file containing entity data into the clipboard.
|
||||
* You can generate * a .json file using {Clipboard.exportEntities}.
|
||||
* @function Clipboard.importEntities
|
||||
* @param {string} filename Filename of file to import.
|
||||
* @return {bool} True if the import was succesful, otherwise false.
|
||||
*/
|
||||
Q_INVOKABLE bool importEntities(const QString& filename);
|
||||
|
||||
/**jsdoc
|
||||
* Export the entities listed in `entityIDs` to the file `filename`
|
||||
* @function Clipboard.exportEntities
|
||||
* @param {string} filename Path to the file to export entities to.
|
||||
* @param {EntityID[]} entityIDs IDs of entities to export.
|
||||
* @return {bool} True if the export was succesful, otherwise false.
|
||||
*/
|
||||
Q_INVOKABLE bool exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs);
|
||||
Q_INVOKABLE bool exportEntities(const QString& filename, float x, float y, float z, float s);
|
||||
|
||||
/**jsdoc
|
||||
* Paste the contents of the clipboard into the world.
|
||||
* @function Clipboard.pasteEntities
|
||||
* @param {Vec3} position Position to paste clipboard at.
|
||||
* @return {EntityID[]} Array of entity IDs for the new entities that were
|
||||
* created as a result of the paste operation.
|
||||
*/
|
||||
Q_INVOKABLE QVector<EntityItemID> pasteEntities(glm::vec3 position);
|
||||
};
|
||||
|
||||
#endif // hifi_ClipboardScriptingInterface_h
|
||||
|
|
|
@ -56,6 +56,9 @@ QScriptValue RayToEntityIntersectionResultToScriptValue(QScriptEngine* engine, c
|
|||
void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, RayToEntityIntersectionResult& results);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @namespace Entities
|
||||
*/
|
||||
/// handles scripting of Entity commands from JS passed to assigned clients
|
||||
class EntityScriptingInterface : public OctreeScriptingInterface, public Dependency {
|
||||
Q_OBJECT
|
||||
|
@ -87,40 +90,90 @@ public:
|
|||
ActivityTracking getActivityTracking() const { return _activityTracking; }
|
||||
public slots:
|
||||
|
||||
// returns true if the DomainServer will allow this Node/Avatar to make changes
|
||||
/**jsdoc
|
||||
* Returns `true` if the DomainServer will allow this Node/Avatar to make changes
|
||||
*
|
||||
* @function Entities.canAdjustLocks
|
||||
* @return {bool} `true` if the client can adjust locks, `false` if not.
|
||||
*/
|
||||
Q_INVOKABLE bool canAdjustLocks();
|
||||
|
||||
// returns true if the DomainServer will allow this Node/Avatar to rez new entities
|
||||
/**jsdoc
|
||||
* @function Entities.canRez
|
||||
* @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new entities
|
||||
*/
|
||||
Q_INVOKABLE bool canRez();
|
||||
|
||||
/**jsdoc
|
||||
* @function Entities.canRezTmp
|
||||
* @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new temporary entities
|
||||
*/
|
||||
Q_INVOKABLE bool canRezTmp();
|
||||
|
||||
/// adds a model with the specific properties
|
||||
/**jsdoc
|
||||
* Add a new entity with the specified properties. If `clientOnly` is true, the entity will
|
||||
* not be sent to the server and will only be visible/accessible on the local client.
|
||||
*
|
||||
* @function Entities.addEntity
|
||||
* @param {EntityItemProperties} properties Properties of the entity to create.
|
||||
* @param {bool} [clientOnly=false] Whether the entity should only exist locally or not.
|
||||
* @return {EntityID} The entity ID of the newly created entity. The ID will be a null
|
||||
* UUID (`{00000000-0000-0000-0000-000000000000}`) if the entity could not be created.
|
||||
*/
|
||||
Q_INVOKABLE QUuid addEntity(const EntityItemProperties& properties, bool clientOnly = false);
|
||||
|
||||
/// temporary method until addEntity can be used from QJSEngine
|
||||
/// Deliberately not adding jsdoc, only used internally.
|
||||
Q_INVOKABLE QUuid addModelEntity(const QString& name, const QString& modelUrl, const QString& shapeType, bool dynamic,
|
||||
const glm::vec3& position, const glm::vec3& gravity);
|
||||
|
||||
/// gets the current model properties for a specific model
|
||||
/// this function will not find return results in script engine contexts which don't have access to models
|
||||
/**jsdoc
|
||||
* Return the properties for the specified {EntityID}.
|
||||
* not be sent to the server and will only be visible/accessible on the local client.
|
||||
* @param {EntityItemProperties} properties Properties of the entity to create.
|
||||
* @param {EntityPropertyFlags} [desiredProperties=[]] Array containing the names of the properties you
|
||||
* would like to get. If the array is empty, all properties will be returned.
|
||||
* @return {EntityItemProperties} The entity properties for the specified entity.
|
||||
*/
|
||||
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID);
|
||||
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties);
|
||||
|
||||
/// edits a model updating only the included properties, will return the identified EntityItemID in case of
|
||||
/// successful edit, if the input entityID is for an unknown model this function will have no effect
|
||||
/**jsdoc
|
||||
* Updates an entity with the specified properties.
|
||||
*
|
||||
* @function Entities.editEntity
|
||||
* @return {EntityID} The EntityID of the entity if the edit was successful, otherwise the null {EntityID}.
|
||||
*/
|
||||
Q_INVOKABLE QUuid editEntity(QUuid entityID, const EntityItemProperties& properties);
|
||||
|
||||
/// deletes a model
|
||||
/**jsdoc
|
||||
* Deletes an entity.
|
||||
*
|
||||
* @function Entities.deleteEntity
|
||||
* @param {EntityID} entityID The ID of the entity to delete.
|
||||
*/
|
||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||
|
||||
/// Allows a script to call a method on an entity's script. The method will execute in the entity script
|
||||
/// engine. If the entity does not have an entity script or the method does not exist, this call will have
|
||||
/// no effect.
|
||||
/**jsdoc
|
||||
* Call a method on an entity. If it is running an entity script (specified by the `script` property)
|
||||
* and it exposes a property with the specified name `method`, it will be called
|
||||
* using `params` as the list of arguments.
|
||||
*
|
||||
* @function Entities.callEntityMethod
|
||||
* @param {EntityID} entityID The ID of the entity to call the method on.
|
||||
* @param {string} method The name of the method to call.
|
||||
* @param {string[]} params The list of parameters to call the specified method with.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||
|
||||
/// finds the closest model to the center point, within the radius
|
||||
/// will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||
/// this function will not find any models in script engine contexts which don't have access to models
|
||||
/**jsdoc
|
||||
*/
|
||||
Q_INVOKABLE QUuid findClosestEntity(const glm::vec3& center, float radius) const;
|
||||
|
||||
/// finds models within the search sphere specified by the center point and radius
|
||||
|
|
|
@ -1188,20 +1188,15 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac
|
|||
thisURL = resolvePath(file);
|
||||
}
|
||||
|
||||
if (!_includedURLs.contains(thisURL)) {
|
||||
if (!isStandardLibrary && !currentSandboxURL.isEmpty() && (thisURL.scheme() == "file") &&
|
||||
(currentSandboxURL.scheme() != "file" ||
|
||||
!thisURL.toString(strippingFlags).startsWith(currentSandboxURL.toString(strippingFlags), getSensitivity()))) {
|
||||
qCWarning(scriptengine) << "Script.include() ignoring file path"
|
||||
<< thisURL << "outside of original entity script" << currentSandboxURL;
|
||||
} else {
|
||||
// We could also check here for CORS, but we don't yet.
|
||||
// It turns out that QUrl.resolve will not change hosts and copy authority, so we don't need to check that here.
|
||||
urls.append(thisURL);
|
||||
_includedURLs << thisURL;
|
||||
}
|
||||
if (!isStandardLibrary && !currentSandboxURL.isEmpty() && (thisURL.scheme() == "file") &&
|
||||
(currentSandboxURL.scheme() != "file" ||
|
||||
!thisURL.toString(strippingFlags).startsWith(currentSandboxURL.toString(strippingFlags), getSensitivity()))) {
|
||||
qCWarning(scriptengine) << "Script.include() ignoring file path"
|
||||
<< thisURL << "outside of original entity script" << currentSandboxURL;
|
||||
} else {
|
||||
qCDebug(scriptengine) << "Script.include() ignoring previously included url:" << thisURL;
|
||||
// We could also check here for CORS, but we don't yet.
|
||||
// It turns out that QUrl.resolve will not change hosts and copy authority, so we don't need to check that here.
|
||||
urls.append(thisURL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1221,13 +1216,20 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac
|
|||
if (contents.isNull()) {
|
||||
qCDebug(scriptengine) << "Error loading file: " << url << "line:" << __LINE__;
|
||||
} else {
|
||||
// Set the parent url so that path resolution will be relative
|
||||
// to this script's url during its initial evaluation
|
||||
_parentURL = url.toString();
|
||||
auto operation = [&]() {
|
||||
evaluate(contents, url.toString());
|
||||
};
|
||||
doWithEnvironment(capturedEntityIdentifier, capturedSandboxURL, operation);
|
||||
std::lock_guard<std::recursive_mutex> lock(_lock);
|
||||
if (!_includedURLs.contains(url)) {
|
||||
_includedURLs << url;
|
||||
// Set the parent url so that path resolution will be relative
|
||||
// to this script's url during its initial evaluation
|
||||
_parentURL = url.toString();
|
||||
auto operation = [&]() {
|
||||
evaluate(contents, url.toString());
|
||||
};
|
||||
|
||||
doWithEnvironment(capturedEntityIdentifier, capturedSandboxURL, operation);
|
||||
} else {
|
||||
qCDebug(scriptengine) << "Script.include() skipping evaluation of previously included url:" << url;
|
||||
}
|
||||
}
|
||||
}
|
||||
_parentURL = parentURL;
|
||||
|
|
|
@ -245,6 +245,7 @@ protected:
|
|||
|
||||
std::function<bool()> _emitScriptUpdates{ [](){ return true; } };
|
||||
|
||||
std::recursive_mutex _lock;
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptEngine_h
|
||||
|
|
|
@ -63,6 +63,7 @@ function setupAudioMenus() {
|
|||
selectedOutputDevice = outputDeviceSetting;
|
||||
}
|
||||
}
|
||||
print("audio output devices: " + outputDevices);
|
||||
for(var i = 0; i < outputDevices.length; i++) {
|
||||
var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice);
|
||||
var menuItem = "Use " + outputDevices[i] + " for Output";
|
||||
|
@ -87,6 +88,7 @@ function setupAudioMenus() {
|
|||
selectedInputDevice = inputDeviceSetting;
|
||||
}
|
||||
}
|
||||
print("audio input devices: " + inputDevices);
|
||||
for(var i = 0; i < inputDevices.length; i++) {
|
||||
var thisDeviceSelected = (inputDevices[i] == selectedInputDevice);
|
||||
var menuItem = "Use " + inputDevices[i] + " for Input";
|
||||
|
@ -103,13 +105,17 @@ function setupAudioMenus() {
|
|||
}
|
||||
|
||||
function onDevicechanged() {
|
||||
print("audio devices changed, removing Audio > Devices menu...");
|
||||
Menu.removeMenu("Audio > Devices");
|
||||
print("now setting up Audio > Devices menu");
|
||||
setupAudioMenus();
|
||||
}
|
||||
|
||||
// Have a small delay before the menu's get setup and the audio devices can switch to the last selected ones
|
||||
Script.setTimeout(function () {
|
||||
print("connecting deviceChanged");
|
||||
AudioDevice.deviceChanged.connect(onDevicechanged);
|
||||
print("setting up Audio > Devices menu for first time");
|
||||
setupAudioMenus();
|
||||
}, 5000);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ exports.handlers = {
|
|||
'../../libraries/script-engine/src',
|
||||
'../../libraries/networking/src',
|
||||
'../../libraries/animation/src',
|
||||
'../../libraries/entities/src',
|
||||
];
|
||||
var exts = ['.h', '.cpp'];
|
||||
|
||||
|
|
Loading…
Reference in a new issue