mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 17:54:20 +02:00
Merge pull request #16323 from highfidelity/master
Merge master into instancing
This commit is contained in:
commit
63fa9afa13
105 changed files with 1405 additions and 1013 deletions
|
@ -82,6 +82,9 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
|
|||
}
|
||||
|
||||
_assignmentServerSocket = HifiSockAddr(_assignmentServerHostname, assignmentServerPort, true);
|
||||
if (_assignmentServerSocket.isNull()) {
|
||||
qCCritical(assignment_client) << "PAGE: Couldn't resolve domain server address" << _assignmentServerHostname;
|
||||
}
|
||||
_assignmentServerSocket.setObjectName("AssignmentServer");
|
||||
nodeList->setAssignmentServerSocket(_assignmentServerSocket);
|
||||
|
||||
|
@ -183,16 +186,21 @@ void AssignmentClient::sendAssignmentRequest() {
|
|||
// we want to check again for the local domain-server port in case the DS has restarted
|
||||
quint16 localAssignmentServerPort;
|
||||
if (nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, localAssignmentServerPort)) {
|
||||
if (localAssignmentServerPort != _assignmentServerSocket.getPort()) {
|
||||
qCDebug(assignment_client) << "Port for local assignment server read from shared memory is"
|
||||
<< localAssignmentServerPort;
|
||||
if (localAssignmentServerPort == 0) {
|
||||
qCWarning(assignment_client) << "ALERT: Server port from shared memory is 0";
|
||||
} else {
|
||||
if (localAssignmentServerPort != _assignmentServerSocket.getPort()) {
|
||||
qCDebug(assignment_client) << "Port for local assignment server read from shared memory is"
|
||||
<< localAssignmentServerPort;
|
||||
|
||||
_assignmentServerSocket.setPort(localAssignmentServerPort);
|
||||
nodeList->setAssignmentServerSocket(_assignmentServerSocket);
|
||||
_assignmentServerSocket.setPort(localAssignmentServerPort);
|
||||
nodeList->setAssignmentServerSocket(_assignmentServerSocket);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qCWarning(assignment_client) << "Failed to read local assignment server port from shared memory"
|
||||
<< "- will send assignment request to previous assignment server socket.";
|
||||
qCWarning(assignment_client) << "ALERT: Failed to read local assignment server port from shared memory ("
|
||||
<< DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY
|
||||
<< ")- will send assignment request to previous assignment server socket.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,7 +258,7 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer<ReceivedMessa
|
|||
// Starts an event loop, and emits workerThread->started()
|
||||
workerThread->start();
|
||||
} else {
|
||||
qCWarning(assignment_client) << "Received an assignment that could not be unpacked. Re-requesting.";
|
||||
qCWarning(assignment_client) << "ALERT: Received an assignment that could not be unpacked. Re-requesting.";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor
|
|||
const int WAIT_FOR_CHILD_MSECS = 1000;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
HANDLE PROCESS_GROUP = createProcessGroup();
|
||||
void* PROCESS_GROUP = createProcessGroup();
|
||||
#endif
|
||||
|
||||
AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmentClientForks,
|
||||
|
|
|
@ -24,7 +24,9 @@
|
|||
ThreadedAssignment* AssignmentFactory::unpackAssignment(ReceivedMessage& message) {
|
||||
|
||||
quint8 packedType;
|
||||
message.peekPrimitive(&packedType);
|
||||
if (message.peekPrimitive(&packedType) != sizeof(packedType)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Assignment::Type unpackedType = (Assignment::Type) packedType;
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
class EntitySimulation;
|
||||
|
||||
/**jsdoc
|
||||
* The <code>EntityViewer</code> API provides a headless viewer for assignment client scripts, so that they can "see" entities
|
||||
* in order for them to be available in the {@link Entities} API.
|
||||
*
|
||||
* @namespace EntityViewer
|
||||
*
|
||||
* @hifi-assignment-client
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* Updates the entities currently in view.
|
||||
* @function EntityViewer.queryOctree
|
||||
*/
|
||||
void queryOctree();
|
||||
|
@ -36,26 +37,30 @@ public slots:
|
|||
// setters for camera attributes
|
||||
|
||||
/**jsdoc
|
||||
* Sets the position of the view frustum.
|
||||
* @function EntityViewer.setPosition
|
||||
* @param {Vec3} position
|
||||
* @param {Vec3} position - The position of the view frustum.
|
||||
*/
|
||||
void setPosition(const glm::vec3& position) { _hasViewFrustum = true; _viewFrustum.setPosition(position); }
|
||||
|
||||
/**jsdoc
|
||||
* Sets the orientation of the view frustum.
|
||||
* @function EntityViewer.setOrientation
|
||||
* @param {Quat} orientation
|
||||
* @param {Quat} orientation - The orientation of the view frustum.
|
||||
*/
|
||||
void setOrientation(const glm::quat& orientation) { _hasViewFrustum = true; _viewFrustum.setOrientation(orientation); }
|
||||
|
||||
/**jsdoc
|
||||
* Sets the radius of the center "keyhole" in the view frustum.
|
||||
* @function EntityViewer.setCenterRadius
|
||||
* @param {number} radius
|
||||
* @param {number} radius - The radius of the center "keyhole" in the view frustum.
|
||||
*/
|
||||
void setCenterRadius(float radius) { _hasViewFrustum = true; _viewFrustum.setCenterRadius(radius); }
|
||||
|
||||
/**jsdoc
|
||||
* Sets the radius of the center "keyhole" in the view frustum.
|
||||
* @function EntityViewer.setKeyholeRadius
|
||||
* @param {number} radius
|
||||
* @param {number} radius - The radius of the center "keyhole" in the view frustum.
|
||||
* @deprecated This function is deprecated and will be removed. Use {@link EntityViewer.setCenterRadius|setCenterRadius}
|
||||
* instead.
|
||||
*/
|
||||
|
@ -66,33 +71,38 @@ public slots:
|
|||
|
||||
/**jsdoc
|
||||
* @function EntityViewer.setVoxelSizeScale
|
||||
* @param {number} sizeScale
|
||||
* @param {number} sizeScale - The voxel size scale.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void setVoxelSizeScale(float sizeScale) { _octreeQuery.setOctreeSizeScale(sizeScale) ; }
|
||||
|
||||
/**jsdoc
|
||||
* @function EntityViewer.setBoundaryLevelAdjust
|
||||
* @param {number} boundaryLevelAdjust
|
||||
* @param {number} boundaryLevelAdjust - The boundary level adjust factor.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _octreeQuery.setBoundaryLevelAdjust(boundaryLevelAdjust); }
|
||||
|
||||
/**jsdoc
|
||||
* Sets the maximum number of entity packets to receive from the domain server per second.
|
||||
* @function EntityViewer.setMaxPacketsPerSecond
|
||||
* @param {number} maxPacketsPerSecond
|
||||
* @param {number} maxPacketsPerSecond - The maximum number of entity packets to receive per second.
|
||||
*/
|
||||
void setMaxPacketsPerSecond(int maxPacketsPerSecond) { _octreeQuery.setMaxQueryPacketsPerSecond(maxPacketsPerSecond); }
|
||||
|
||||
// getters for camera attributes
|
||||
|
||||
/**jsdoc
|
||||
* Gets the position of the view frustum.
|
||||
* @function EntityViewer.getPosition
|
||||
* @returns {Vec3}
|
||||
* @returns {Vec3} The position of the view frustum.
|
||||
*/
|
||||
const glm::vec3& getPosition() const { return _viewFrustum.getPosition(); }
|
||||
|
||||
/**jsdoc
|
||||
* Gets the orientation of the view frustum.
|
||||
* @function EntityViewer.getOrientation
|
||||
* @returns {Quat}
|
||||
* @returns {Quat} The orientation of the view frustum.
|
||||
*/
|
||||
const glm::quat& getOrientation() const { return _viewFrustum.getOrientation(); }
|
||||
|
||||
|
@ -101,26 +111,30 @@ public slots:
|
|||
|
||||
/**jsdoc
|
||||
* @function EntityViewer.getVoxelSizeScale
|
||||
* @returns {number}
|
||||
* @returns {number} The voxel size scale.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
float getVoxelSizeScale() const { return _octreeQuery.getOctreeSizeScale(); }
|
||||
|
||||
/**jsdoc
|
||||
* @function EntityViewer.getBoundaryLevelAdjust
|
||||
* @returns {number}
|
||||
* @returns {number} The boundary level adjust factor.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
int getBoundaryLevelAdjust() const { return _octreeQuery.getBoundaryLevelAdjust(); }
|
||||
|
||||
/**jsdoc
|
||||
* Gets the maximum number of entity packets to receive from the domain server per second.
|
||||
* @function EntityViewer.getMaxPacketsPerSecond
|
||||
* @returns {number}
|
||||
* @returns {number} The maximum number of entity packets to receive per second.
|
||||
*/
|
||||
int getMaxPacketsPerSecond() const { return _octreeQuery.getMaxQueryPacketsPerSecond(); }
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Gets the number of nodes in the octree.
|
||||
* @function EntityViewer.getOctreeElementsCount
|
||||
* @returns {number}
|
||||
* @returns {number} The number of nodes in the octree.
|
||||
*/
|
||||
unsigned getOctreeElementsCount() const { return _tree->getOctreeElementsCount(); }
|
||||
|
||||
|
|
|
@ -14,9 +14,9 @@ elseif (WIN32)
|
|||
elseif (APPLE)
|
||||
vcpkg_download_distfile(
|
||||
WEBRTC_SOURCE_ARCHIVE
|
||||
URLS https://hifi-public.s3.amazonaws.com/seth/webrtc-20190626-osx.tar.gz
|
||||
SHA512 fc70cec1b5ee87395137b7090f424e2fc2300fc17d744d5ffa1cf7aa0e0f1a069a9d72ba1ad2fb4a640ebeb6c218bda24351ba0083e1ff96c4a4b5032648a9d2
|
||||
FILENAME webrtc-20190626-osx.tar.gz
|
||||
URLS https://hifi-public.s3.amazonaws.com/seth/webrtc-m78-osx.tar.gz
|
||||
SHA512 8b547da921cc96f5c22b4253a1c9e707971bb627898fbdb6b238ef1318c7d2512e878344885c936d4bd6a66005cc5b63dfc3fa5ddd14f17f378dcaa17b5e25df
|
||||
FILENAME webrtc-m78-osx.tar.gz
|
||||
)
|
||||
else ()
|
||||
# else Linux desktop
|
||||
|
|
|
@ -252,6 +252,7 @@
|
|||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <VersionHelpers.h>
|
||||
#include <Windows.h>
|
||||
|
||||
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||
// FIXME seems to be broken.
|
||||
|
@ -532,6 +533,11 @@ bool isDomainURL(QUrl url) {
|
|||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static const UINT UWM_IDENTIFY_INSTANCES =
|
||||
RegisterWindowMessage("UWM_IDENTIFY_INSTANCES_{8AB82783-B74A-4258-955B-8188C22AA0D6}_" + qgetenv("USERNAME"));
|
||||
static const UINT UWM_SHOW_APPLICATION =
|
||||
RegisterWindowMessage("UWM_SHOW_APPLICATION_{71123FD6-3DA8-4DC1-9C27-8A12A6250CBA}_" + qgetenv("USERNAME"));
|
||||
|
||||
class MyNativeEventFilter : public QAbstractNativeEventFilter {
|
||||
public:
|
||||
static MyNativeEventFilter& getInstance() {
|
||||
|
@ -4957,7 +4963,7 @@ extern "C" {
|
|||
CCHAR NumberOfProcessors;
|
||||
};
|
||||
|
||||
NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemInformation(
|
||||
NTSYSCALLAPI LONG NTAPI NtQuerySystemInformation(
|
||||
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
_Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
|
||||
_In_ ULONG SystemInformationLength,
|
||||
|
@ -4966,12 +4972,12 @@ extern "C" {
|
|||
|
||||
}
|
||||
template <typename T>
|
||||
NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, T& t) {
|
||||
LONG NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, T& t) {
|
||||
return NtQuerySystemInformation(SystemInformationClass, &t, (ULONG)sizeof(T), nullptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, std::vector<T>& t) {
|
||||
LONG NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, std::vector<T>& t) {
|
||||
return NtQuerySystemInformation(SystemInformationClass, t.data(), (ULONG)(sizeof(T) * t.size()), nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -91,12 +91,6 @@ namespace controller {
|
|||
class StateController;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static const UINT UWM_IDENTIFY_INSTANCES =
|
||||
RegisterWindowMessage("UWM_IDENTIFY_INSTANCES_{8AB82783-B74A-4258-955B-8188C22AA0D6}_" + qgetenv("USERNAME"));
|
||||
static const UINT UWM_SHOW_APPLICATION =
|
||||
RegisterWindowMessage("UWM_SHOW_APPLICATION_{71123FD6-3DA8-4DC1-9C27-8A12A6250CBA}_" + qgetenv("USERNAME"));
|
||||
#endif
|
||||
|
||||
static const QString RUNNING_MARKER_FILENAME = "Interface.running";
|
||||
static const QString SCRIPTS_SWITCH = "scripts";
|
||||
|
|
|
@ -20,7 +20,7 @@ class FancyCamera : public Camera {
|
|||
|
||||
/**jsdoc
|
||||
* The <code>Camera</code> API provides access to the "camera" that defines your view in desktop and HMD display modes.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
|
||||
*
|
||||
* @namespace Camera
|
||||
*
|
||||
|
|
|
@ -829,7 +829,7 @@ Menu::Menu() {
|
|||
// Help > Release Notes
|
||||
action = addActionToQMenuAndActionHash(helpMenu, "Release Notes");
|
||||
connect(action, &QAction::triggered, qApp, [] {
|
||||
QDesktopServices::openUrl(QUrl("http://steamcommunity.com/games/390540/announcements/"));
|
||||
QDesktopServices::openUrl(QUrl("https://docs.highfidelity.com/release-notes.html"));
|
||||
});
|
||||
|
||||
// Help > Report a Bug!
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include <DependencyManager.h>
|
||||
|
||||
/**jsdoc
|
||||
* The <code>SpeechRecognizer</code> API provides facilities to recognize voice commands.
|
||||
* <p>Speech recognition is enabled or disabled via the Developer > Scripting > Enable Speech Control API menu item or
|
||||
* the {@link SpeechRecognizer.setEnabled} method.</p>
|
||||
*
|
||||
* @namespace SpeechRecognizer
|
||||
*
|
||||
* @hifi-interface
|
||||
|
@ -40,36 +44,86 @@ public:
|
|||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* Enables or disables speech recognition.
|
||||
* @function SpeechRecognizer.setEnabled
|
||||
* @param {boolean} enabled
|
||||
* @param {boolean} enabled - <code>true</code> to enable speech recognition, <code>false</code> to disable.
|
||||
*/
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
/**jsdoc
|
||||
* Adds a voice command to the speech recognizer.
|
||||
* @function SpeechRecognizer.addCommand
|
||||
* @param {string} command
|
||||
* @param {string} command - The voice command to recognize.
|
||||
*/
|
||||
void addCommand(const QString& command);
|
||||
|
||||
/**jsdoc
|
||||
* Removes a voice command from the speech recognizer.
|
||||
* @function SpeechRecognizer.removeCommand
|
||||
* @param {string} command
|
||||
* @param {string} command - The voice command to stop recognizing.
|
||||
*/
|
||||
void removeCommand(const QString& command);
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a voice command has been recognized.
|
||||
* @function SpeechRecognizer.commandRecognized
|
||||
* @param {string} command
|
||||
* @param {string} command - The voice command recognized.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Turn your avatar upon voice command.</caption>
|
||||
* var TURN_LEFT = "turn left";
|
||||
* var TURN_RIGHT = "turn right";
|
||||
* var TURN_RATE = 0.5;
|
||||
* var TURN_DURATION = 1000; // ms
|
||||
* var turnRate = 0;
|
||||
*
|
||||
* function getTurnRate() {
|
||||
* return turnRate;
|
||||
* }
|
||||
*
|
||||
* var MAPPING_NAME = "com.highfidelity.controllers.example.speechRecognizer";
|
||||
* var mapping = Controller.newMapping(MAPPING_NAME);
|
||||
*
|
||||
* mapping.from(getTurnRate).to(Controller.Actions.Yaw);
|
||||
* Controller.enableMapping(MAPPING_NAME);
|
||||
*
|
||||
* function onCommandRecognized(command) {
|
||||
* print("Speech command: " + command);
|
||||
* switch (command) {
|
||||
* case TURN_LEFT:
|
||||
* turnRate = -TURN_RATE;
|
||||
* break;
|
||||
* case TURN_RIGHT:
|
||||
* turnRate = TURN_RATE;
|
||||
* break;
|
||||
* }
|
||||
* Script.setTimeout(function () {
|
||||
* turnRate = 0;
|
||||
* }, TURN_DURATION);
|
||||
* }
|
||||
*
|
||||
* SpeechRecognizer.addCommand(TURN_LEFT);
|
||||
* SpeechRecognizer.addCommand(TURN_RIGHT);
|
||||
* SpeechRecognizer.commandRecognized.connect(onCommandRecognized);
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* Controller.disableMapping(MAPPING_NAME);
|
||||
* SpeechRecognizer.removeCommand(TURN_LEFT);
|
||||
* SpeechRecognizer.removeCommand(TURN_RIGHT);
|
||||
* });
|
||||
*/
|
||||
void commandRecognized(const QString& command);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when speech recognition is enabled or disabled.
|
||||
* @function SpeechRecognizer.enabledUpdated
|
||||
* @param {boolean} enabled
|
||||
* @param {boolean} enabled - <code>true</code> if speech recognition is enabled, <code>false</code> if it is disabled.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when speech recognition is enabled or disabled.</caption>
|
||||
* SpeechRecognizer.enabledUpdated.connect(function (enabled) {
|
||||
* print("Speech recognition: " + (enabled ? "enabled" : "disabled"));
|
||||
* });
|
||||
*/
|
||||
void enabledUpdated(bool enabled);
|
||||
|
||||
|
|
|
@ -2175,7 +2175,7 @@ static float lookAtCostFunction(const glm::vec3& myForward, const glm::vec3& myP
|
|||
}
|
||||
|
||||
void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) {
|
||||
glm::vec3 myForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FORWARD;
|
||||
glm::vec3 myForward = _lookAtYaw * IDENTITY_FORWARD;
|
||||
glm::vec3 myPosition = getHead()->getEyePosition();
|
||||
CameraMode mode = qApp->getCamera().getMode();
|
||||
if (mode == CAMERA_MODE_FIRST_PERSON) {
|
||||
|
@ -2553,7 +2553,7 @@ void MyAvatar::clearWornAvatarEntities() {
|
|||
}
|
||||
|
||||
/**jsdoc
|
||||
* Information about an avatar entity.
|
||||
* <p>Information about an avatar entity.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Property</th><th>Type</th><th>Description</th></tr>
|
||||
|
@ -3560,7 +3560,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
if (faceForward || _shouldTurnToFaceCamera) {
|
||||
const float REORIENT_FORWARD_BLEND = 0.25f;
|
||||
const float REORIENT_TURN_BLEND = 0.03f;
|
||||
const float DIAGONAL_TURN_BLEND = 0.02f;
|
||||
const float DIAGONAL_TURN_BLEND = 0.1f;
|
||||
float blend = (_shouldTurnToFaceCamera ? REORIENT_TURN_BLEND : REORIENT_FORWARD_BLEND) * timeScale;
|
||||
if (blend > 1.0f) {
|
||||
blend = 1.0f;
|
||||
|
@ -3772,7 +3772,8 @@ glm::vec3 MyAvatar::scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 rig
|
|||
// Desktop mode.
|
||||
direction = (zSpeed * forward) + (xSpeed * right);
|
||||
CameraMode mode = qApp->getCamera().getMode();
|
||||
if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_SELFIE) && zSpeed != 0.0f && xSpeed != 0.0f){
|
||||
if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_SELFIE) &&
|
||||
zSpeed != 0.0f && xSpeed != 0.0f && !isFlying()){
|
||||
direction = (zSpeed * forward);
|
||||
}
|
||||
|
||||
|
|
|
@ -170,10 +170,12 @@ class MyAvatar : public Avatar {
|
|||
* collision. It can be a mono or stereo 16-bit WAV file running at either 24kHz or 48kHz. The latter is down-sampled
|
||||
* by the audio mixer, so all audio effectively plays back at a 24khz. 48kHz RAW files are also supported.
|
||||
* @property {number} audioListenerMode=0 - Specifies the listening position when hearing spatialized audio. Must be one
|
||||
* of the following property values:<br />
|
||||
* <code>Myavatar.audioListenerModeHead</code><br />
|
||||
* <code>Myavatar.audioListenerModeCamera</code><br />
|
||||
* <code>Myavatar.audioListenerModeCustom</code>
|
||||
* of the following property values:
|
||||
* <ul>
|
||||
* <li><code>MyAvatar.audioListenerModeHead</code></li>
|
||||
* <li><code>MyAvatar.audioListenerModeCamera</code></li>
|
||||
* <li><code>MyAvatar.audioListenerModeCustom</code></li>
|
||||
* </ul>
|
||||
* @property {number} audioListenerModeHead=0 - The audio listening position is at the avatar's head. <em>Read-only.</em>
|
||||
* @property {number} audioListenerModeCamera=1 - The audio listening position is at the camera. <em>Read-only.</em>
|
||||
* @property {number} audioListenerModeCustom=2 - The audio listening position is at a the position specified by set by the
|
||||
|
@ -182,8 +184,8 @@ class MyAvatar : public Avatar {
|
|||
* property value is <code>audioListenerModeCustom</code>.
|
||||
* @property {Quat} customListenOrientation=Quat.IDENTITY - The listening orientation used when the
|
||||
* <code>audioListenerMode</code> property value is <code>audioListenerModeCustom</code>.
|
||||
* @property {boolean} hasScriptedBlendshapes=false - <code>true</code> to transmit blendshapes over the network.<br />
|
||||
* <strong>Note:</strong> Currently doesn't work. Use {@link MyAvatar.setForceFaceTrackerConnected} instead.
|
||||
* @property {boolean} hasScriptedBlendshapes=false - <code>true</code> to transmit blendshapes over the network.
|
||||
* <p><strong>Note:</strong> Currently doesn't work. Use {@link MyAvatar.setForceFaceTrackerConnected} instead.</p>
|
||||
* @property {boolean} hasProceduralBlinkFaceMovement=true - <code>true</code> if procedural blinking is turned on.
|
||||
* @property {boolean} hasProceduralEyeFaceMovement=true - <code>true</code> if procedural eye movement is turned on.
|
||||
* @property {boolean} hasAudioEnabledFaceMovement=true - <code>true</code> to move the mouth blendshapes with voice audio
|
||||
|
@ -241,8 +243,8 @@ class MyAvatar : public Avatar {
|
|||
* @property {boolean} useAdvancedMovementControls - Returns and sets the value of the Interface setting, Settings >
|
||||
* Controls > Walking. Note: Setting the value has no effect unless Interface is restarted.
|
||||
* @property {boolean} showPlayArea - Returns and sets the value of the Interface setting, Settings > Controls > Show room
|
||||
* boundaries while teleporting.<br />
|
||||
* <strong>Note:</strong> Setting the value has no effect unless Interface is restarted.
|
||||
* boundaries while teleporting.
|
||||
* <p><strong>Note:</strong> Setting the value has no effect unless Interface is restarted.</p>
|
||||
*
|
||||
* @property {number} yawSpeed=75 - The mouse X sensitivity value in Settings > General. <em>Read-only.</em>
|
||||
* @property {number} pitchSpeed=50 - The mouse Y sensitivity value in Settings > General. <em>Read-only.</em>
|
||||
|
@ -491,9 +493,10 @@ public:
|
|||
* <tr><td><code>2</code></td><td>Auto</td><td>Interface detects when the user is standing or seated in the real world.
|
||||
* Avatar leaning is disabled when the user is sitting (i.e., avatar always recenters), and avatar leaning is enabled
|
||||
* when the user is standing (i.e., avatar leans, then if leans too far it recenters).</td></tr>
|
||||
* <tr><td><code>3</code></td><td>DisableHMDLean</td><td>Both avatar leaning and recentering are disabled regardless of
|
||||
* <tr><td><code>3</code></td><td>DisableHMDLean</td><td><p>Both avatar leaning and recentering are disabled regardless of
|
||||
* what the user is doing in the real world and no matter what their avatar is doing in the virtual world. Enables
|
||||
* the avatar to sit on the floor when the user sits on the floor.<br /><strong>Note:</strong> Experimental.</td></tr>
|
||||
* the avatar to sit on the floor when the user sits on the floor.</p>
|
||||
* <p><strong>Note:</strong> Experimental.</p></td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {number} MyAvatar.SitStandModelType
|
||||
|
@ -782,7 +785,7 @@ public:
|
|||
* additional properties specified when adding the different handlers.</p>
|
||||
* <p>A handler may change a value from <code>animStateDictionaryIn</code> or add different values in the
|
||||
* <code>animStateDictionaryOut</code> returned. Any property values set in <code>animStateDictionaryOut</code> will
|
||||
* override those of the internal animation machinery.</p.
|
||||
* override those of the internal animation machinery.</p>
|
||||
* @function MyAvatar.addAnimationStateHandler
|
||||
* @param {function} handler - The animation state handler function to add.
|
||||
* @param {Array<string>|null} propertiesList - The list of {@link MyAvatar.AnimStateDictionary|AnimStateDictionary}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "Profile.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
extern "C" {
|
||||
typedef int(__stdcall * CHECKMINSPECPROC) ();
|
||||
}
|
||||
|
|
|
@ -78,17 +78,17 @@ PickFilter getPickFilter(unsigned int filter) {
|
|||
* @property {boolean} [enabled=false] - <code>true</code> if this pick should start enabled, <code>false</code> if it should
|
||||
* start disabled. Disabled picks do not update their pick results.
|
||||
* @property {FilterFlags} [filter=0] - The filter for this pick to use. Construct using {@link Picks} FilterFlags property
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* @property {number} [maxDistance=0.0] - The maximum distance at which this pick will intersect. A value of <code>0.0</code>
|
||||
* means no maximum.
|
||||
* @property {Uuid} [parentID] - The ID of the parent: an avatar, an entity, or another pick.
|
||||
* @property {number} [parentJointIndex=0] - The joint of the parent to parent to, for example, an avatar joint.
|
||||
* A value of <code>0</code> means no joint.<br />
|
||||
* <em>Used only if <code>parentID</code> is specified.</em>
|
||||
* A value of <code>0</code> means no joint.
|
||||
* <p><em>Used only if <code>parentID</code> is specified.</em></p>
|
||||
* @property {string} [joint] - <code>"Mouse"</code> parents the pick to the mouse; <code>"Avatar"</code> parents the pick to
|
||||
* the user's avatar head; a joint name parents to the joint in the user's avatar; otherwise, the pick is "static", not
|
||||
* parented to anything.<br />
|
||||
* <em>Used only if <code>parentID</code> is not specified.</em>
|
||||
* parented to anything.
|
||||
* <p><em>Used only if <code>parentID</code> is not specified.</em></p>
|
||||
* @property {Vec3} [position=Vec3.ZERO] - The offset of the ray origin from its parent if parented, otherwise the ray origin
|
||||
* in world coordinates.
|
||||
* @property {Vec3} [posOffset] - Synonym for <code>position</code>.
|
||||
|
@ -164,7 +164,7 @@ std::shared_ptr<PickQuery> PickScriptingInterface::buildRayPick(const QVariantMa
|
|||
* @property {boolean} [enabled=false] - <code>true</code> if this pick should start enabled, <code>false</code> if it should
|
||||
* start disabled. Disabled picks do not update their pick results.
|
||||
* @property {number} [filter=0] - The filter for this pick to use. Construct using {@link Picks} FilterFlags property
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* <p><strong>Note:</strong> Stylus picks do not intersect avatars or the HUD.</p>
|
||||
* @property {number} [maxDistance=0.0] - The maximum distance at which this pick will intersect. A value of <code>0.0</code>
|
||||
* means no maximum.
|
||||
|
@ -212,17 +212,17 @@ std::shared_ptr<PickQuery> PickScriptingInterface::buildStylusPick(const QVarian
|
|||
* @property {boolean} [enabled=false] - <code>true</code> if this pick should start enabled, <code>false</code> if it should
|
||||
* start disabled. Disabled picks do not update their pick results.
|
||||
* @property {number} [filter=0] - The filter for this pick to use. Construct using {@link Picks} FilterFlags property
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* @property {number} [maxDistance=0.0] - The maximum distance at which this pick will intersect. A value of <code>0.0</code>
|
||||
* means no maximum.
|
||||
* @property {Uuid} [parentID] - The ID of the parent: an avatar, an entity, or another pick.
|
||||
* @property {number} [parentJointIndex=0] - The joint of the parent to parent to, for example, an avatar joint.
|
||||
* A value of <code>0</code> means no joint.<br />
|
||||
* <em>Used only if <code>parentID</code> is specified.</em>
|
||||
* A value of <code>0</code> means no joint.
|
||||
* <p><em>Used only if <code>parentID</code> is specified.</em></p>
|
||||
* @property {string} [joint] - <code>"Mouse"</code> parents the pick to the mouse; <code>"Avatar"</code> parents the pick to
|
||||
* the user's avatar head; a joint name parents to the joint in the user's avatar; otherwise, the pick is "static", not
|
||||
* parented to anything.
|
||||
* <em>Used only if <code>parentID</code> is not specified.</em>
|
||||
* <p><em>Used only if <code>parentID</code> is not specified.</em></p>
|
||||
* @property {Vec3} [position=Vec3.ZERO] - The offset of the parabola origin from its parent if parented, otherwise the
|
||||
* parabola origin in world coordinates.
|
||||
* @property {Vec3} [posOffset] - Synonym for <code>position</code>.
|
||||
|
@ -321,18 +321,18 @@ std::shared_ptr<PickQuery> PickScriptingInterface::buildParabolaPick(const QVari
|
|||
* @property {boolean} [enabled=false] - <code>true</code> if this pick should start enabled, <code>false</code> if it should
|
||||
* start disabled. Disabled picks do not update their pick results.
|
||||
* @property {FilterFlags} [filter=0] - The filter for this pick to use. Construct using {@link Picks} FilterFlags property
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* values (e.g., <code>Picks.PICK_DOMAIN_ENTITIES</code>) combined with <code>|</code> (bitwise OR) operators.
|
||||
* <p><strong>Note:</strong> Collision picks do not intersect the HUD.</p>
|
||||
* @property {number} [maxDistance=0.0] - The maximum distance at which this pick will intersect. A value of <code>0.0</code>
|
||||
* means no maximum.
|
||||
* @property {Uuid} [parentID] - The ID of the parent: an avatar, an entity, or another pick.
|
||||
* @property {number} [parentJointIndex=0] - The joint of the parent to parent to, for example, an avatar joint.
|
||||
* A value of <code>0</code> means no joint.<br />
|
||||
* <em>Used only if <code>parentID</code> is specified.</em>
|
||||
* A value of <code>0</code> means no joint.
|
||||
* <p><em>Used only if <code>parentID</code> is specified.</em></p>
|
||||
* @property {string} [joint] - <code>"Mouse"</code> parents the pick to the mouse; <code>"Avatar"</code> parents the pick to
|
||||
* the user's avatar head; a joint name parents to the joint in the user's avatar; otherwise, the pick is "static", not
|
||||
* parented to anything.<br />
|
||||
* <em>Used only if <code>parentID</code> is not specified.</em>
|
||||
* parented to anything.
|
||||
* <p><em>Used only if <code>parentID</code> is not specified.</em></p>
|
||||
* @property {boolean} [scaleWithParent=true] - <code>true</code> to scale the pick's dimensions and threshold according to the
|
||||
* scale of the parent.
|
||||
*
|
||||
|
@ -344,9 +344,11 @@ std::shared_ptr<PickQuery> PickScriptingInterface::buildParabolaPick(const QVari
|
|||
* the collision region. The depth is in world coordinates but scales with the parent if defined.
|
||||
* @property {CollisionMask} [collisionGroup=8] - The type of objects the collision region collides as. Objects whose collision
|
||||
* masks overlap with the region's collision group are considered to be colliding with the region.
|
||||
* @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A collision pick's type is {@link PickType.Collision}.
|
||||
* @property {Vec3} baseScale - Returned from {@link Picks.getPickProperties} when the pick has a parent with varying scale (usually an avatar or an entity).
|
||||
* Its value is the original scale of the parent at the moment the pick was created, and is used to rescale the pick, and/or the pointer which owns this pick, if any.
|
||||
* @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or
|
||||
* {@link Picks.getPickScriptParameters}. A collision pick's type is {@link PickType.Collision}.
|
||||
* @property {Vec3} baseScale - Returned from {@link Picks.getPickProperties} when the pick has a parent with varying scale
|
||||
* (usually an avatar or an entity). Its value is the original scale of the parent at the moment the pick was created, and
|
||||
* is used to rescale the pick, and/or the pointer which owns this pick, if any.
|
||||
*/
|
||||
std::shared_ptr<PickQuery> PickScriptingInterface::buildCollisionPick(const QVariantMap& propMap) {
|
||||
bool enabled = false;
|
||||
|
|
|
@ -287,7 +287,7 @@ public slots:
|
|||
/**jsdoc
|
||||
* @function Picks.PICK_ENTITIES
|
||||
* @deprecated This function is deprecated and will be removed. Use the <code>Picks.PICK_DOMAIN_ENTITIES |
|
||||
* Picks.PICK_AVATAR_ENTITIES</cpode> properties expression instead.
|
||||
* Picks.PICK_AVATAR_ENTITIES</code> properties expression instead.
|
||||
* @returns {number}
|
||||
*/
|
||||
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::DOMAIN_ENTITIES) | PickFilter::getBitMask(PickFilter::FlagBit::AVATAR_ENTITIES); }
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
* @property {Controller.Standard|Controller.Actions|function} action - The controller output or function that triggers the
|
||||
* events on the entity or overlay. If a function, it must return a number <code>>= 1.0</code> to start the action
|
||||
* and <code>< 1.0</code> to terminate the action.
|
||||
* @property {string} button - Which button to trigger.
|
||||
* @property {string} button - Which button to trigger:
|
||||
* <ul>
|
||||
* <li><code>"Primary"</code>, <code>"Secondary"</code>, and <code>"Tertiary"</code> cause {@link Entities} and
|
||||
* {@link Overlays} mouse pointer events. Other button names also cause mouse events but the <code>button</code>
|
||||
|
|
|
@ -50,12 +50,14 @@ class AccountServicesScriptingInterface : public QObject {
|
|||
* <code>"Unknown user"</code>. <em>Read-only.</em>
|
||||
* @property {boolean} loggedIn - <code>true</code> if the user is logged in, otherwise <code>false</code>.
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} findableBy - The user's visibility to other users:<br />
|
||||
* <code>"none"</code> - user appears offline.<br />
|
||||
* <code>"friends"</code> - user is visible only to friends.<br />
|
||||
* <code>"connections"</code> - user is visible to friends and connections.<br />
|
||||
* <code>"all"</code> - user is visible to everyone.
|
||||
* @property {string} metaverseServerURL - The metaverse server that the user is authenticated against when logged in
|
||||
* @property {string} findableBy - The user's visibility to other users:
|
||||
* <ul>
|
||||
* <li><code>"none"</code> — user appears offline.</li>
|
||||
* <li><code>"friends"</code> — user is visible only to friends.</li>
|
||||
* <li><code>"connections"</code> — user is visible to friends and connections.</li>
|
||||
* <li><code>"all"</code> — user is visible to everyone.</li>
|
||||
* </ul>
|
||||
* @property {string} metaverseServerURL - The metaverse server that the user is authenticated against when logged in
|
||||
* — typically <code>"https://metaverse.highfidelity.com"</code>. <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
|
@ -160,11 +162,13 @@ signals:
|
|||
/**jsdoc
|
||||
* Triggered when the user's visibility to others changes.
|
||||
* @function AccountServices.findableByChanged
|
||||
* @param {string} findableBy - The user's visibility to other people:<br />
|
||||
* <code>"none"</code> - user appears offline.<br />
|
||||
* <code>"friends"</code> - user is visible only to friends.<br />
|
||||
* <code>"connections"</code> - user is visible to friends and connections.<br />
|
||||
* <code>"all"</code> - user is visible to everyone.
|
||||
* @param {string} findableBy - The user's visibility to other people:
|
||||
* <ul>
|
||||
* <li><code>"none"</code> — user appears offline.</li>
|
||||
* <li><code>"friends"</code> — user is visible only to friends.</li>
|
||||
* <li><code>"connections"</code> — user is visible to friends and connections.</li>
|
||||
* <li><code>"all"</code> — user is visible to everyone.</li>
|
||||
* </ul>
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when your visiblity changes.</caption>
|
||||
* AccountServices.findableByChanged.connect(function (findableBy) {
|
||||
|
|
|
@ -168,7 +168,6 @@ class ScriptEngine;
|
|||
* <td><code>startFarTrigger</code><br /><code>continueFarTrigger</code><br /><code>stopFarTrigger</code></td>
|
||||
* <td>These methods are called when a user is more than 0.3m away from the entity, the entity is triggerable, and the
|
||||
* user starts, continues, or stops squeezing the trigger.</td>
|
||||
* </td>
|
||||
* <td>A light switch that can be toggled on and off from a distance.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
|
@ -217,25 +216,25 @@ class ScriptEngine;
|
|||
*
|
||||
* @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
|
||||
* points in a {@link RouteObject} mapping. A synonym for <code>Controller.Hardware.Actions</code>.
|
||||
* <em>Read-only.</em><br /><br />
|
||||
* Default mappings are provided from the <code>Controller.Hardware.Keyboard</code> and <code>Controller.Standard</code> to
|
||||
* actions in
|
||||
* <em>Read-only.</em>
|
||||
* <p>Default mappings are provided from the <code>Controller.Hardware.Keyboard</code> and <code>Controller.Standard</code>
|
||||
* to actions in
|
||||
* <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/keyboardMouse.json">
|
||||
* keyboardMouse.json</a> and
|
||||
* <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/standard.json">
|
||||
* standard.json</a>, respectively.
|
||||
* standard.json</a>, respectively.</p>
|
||||
*
|
||||
* @property {Controller.Hardware} Hardware - Standard and hardware-specific controller and computer outputs, plus predefined
|
||||
* actions on Interface and the user's avatar. The outputs can be mapped to <code>Actions</code> or functions in a
|
||||
* {@link RouteObject} mapping. Additionally, hardware-specific controller outputs can be mapped to <code>Standard</code>
|
||||
* controller outputs. <em>Read-only.</em>
|
||||
* {@link RouteObject} mapping. Additionally, hardware-specific controller outputs can be mapped to
|
||||
* <code>Controller.Standard</code> controller outputs. <em>Read-only.</em>
|
||||
*
|
||||
* @property {Controller.Standard} Standard - Standard controller outputs that can be mapped to <code>Actions</code> or
|
||||
* functions in a {@link RouteObject} mapping. <em>Read-only.</em><br /><br />
|
||||
* Each hardware device has a mapping from its outputs to <code>Controller.Standard</code> items, specified in a JSON file.
|
||||
* functions in a {@link RouteObject} mapping. <em>Read-only.</em>
|
||||
* <p>Each hardware device has a mapping from its outputs to <code>Controller.Standard</code> items, specified in a JSON file.
|
||||
* For example, <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/leapmotion.json">
|
||||
* leapmotion.json</a> and
|
||||
* <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/vive.json">vive.json</a>.
|
||||
* <a href="https://github.com/highfidelity/hifi/blob/master/interface/resources/controllers/vive.json">vive.json</a>.</p>
|
||||
*/
|
||||
|
||||
/// handles scripting of input controller commands from JS
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
* @property {InteractiveWindow.DockArea} RIGHT - Dock to the right edge of the Interface window.
|
||||
*/
|
||||
/**jsdoc
|
||||
* A docking location of an <code>InteractiveWindow</code>.
|
||||
* <p>A docking location of an <code>InteractiveWindow</code>.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</p><th>Description</th>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>TOP</td><td>Dock to the top edge of the Interface window.</td></tr>
|
||||
|
@ -73,10 +73,10 @@ int DesktopScriptingInterface::getHeight() {
|
|||
* own separate window.
|
||||
*/
|
||||
/**jsdoc
|
||||
* A display mode for an <code>InteractiveWindow</code>.
|
||||
* <p>A display mode for an <code>InteractiveWindow</code>.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</p><th>Description</th>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>VIRTUAL</td><td>The window is displayed inside Interface: in the desktop window in
|
||||
|
|
|
@ -24,7 +24,8 @@ class MenuItemProperties;
|
|||
* <h3>Groupings</h3>
|
||||
*
|
||||
* <p>A "grouping" provides a way to group a set of menus or menu items together so that they can all be set visible or invisible
|
||||
* as a group.</p> There is currently only one available group: <code>"Developer"</code>. This grouping can be toggled in the
|
||||
* as a group.</p>
|
||||
* <p>There is currently only one available group: <code>"Developer"</code>. This grouping can be toggled in the
|
||||
* "Settings" menu.</p>
|
||||
* <p>If a menu item doesn't belong to a group, it is always displayed.</p>
|
||||
*
|
||||
|
|
|
@ -44,7 +44,7 @@ SelectionScriptingInterface::SelectionScriptingInterface() {
|
|||
}
|
||||
|
||||
/**jsdoc
|
||||
* The type of a specific item in a selection list.
|
||||
* <p>The type of a specific item in a selection list.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
* @property {WalletScriptingInterface.WalletStatus} walletStatus - The status of the user's wallet. <em>Read-only.</em>
|
||||
* @property {boolean} limitedCommerce - <code>true</code> if Interface is running in limited commerce mode. In limited commerce
|
||||
* mode, certain Interface functionalities are disabled, e.g., users can't buy items that are not free from the Marketplace.
|
||||
* The Oculus Store version of Interface runs in limited commerce mode. <em>Read-only.</em>
|
||||
* The Oculus Store and Steam versions of Interface run in limited commerce mode. <em>Read-only.</em>
|
||||
*/
|
||||
class WalletScriptingInterface : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
|
@ -73,9 +73,9 @@ public:
|
|||
/**jsdoc
|
||||
* Check that a certified avatar entity is owned by the avatar whose entity it is. The result of the check is provided via
|
||||
* the {@link WalletScriptingInterface.ownershipVerificationSuccess|ownershipVerificationSuccess} and
|
||||
* {@link WalletScriptingInterface.ownershipVerificationFailed|ownershipVerificationFailed} signals.<br />
|
||||
* <strong>Warning:</strong> Neither of these signals are triggered if the entity is not an avatar entity or is not
|
||||
* certified.
|
||||
* {@link WalletScriptingInterface.ownershipVerificationFailed|ownershipVerificationFailed} signals.
|
||||
* <p><strong>Warning:</strong> Neither of these signals are triggered if the entity is not an avatar entity or is not
|
||||
* certified.</p>
|
||||
* @function WalletScriptingInterface.proveAvatarEntityOwnershipVerification
|
||||
* @param {Uuid} entityID - The avatar entity's ID.
|
||||
* @example <caption>Check the ownership of all nearby certified avatar entities.</caption>
|
||||
|
|
|
@ -326,10 +326,10 @@ public slots:
|
|||
* full resolution is used (window dimensions in desktop mode; HMD display dimensions in HMD mode), otherwise one of the
|
||||
* dimensions is adjusted in order to match the aspect ratio.
|
||||
* @param {string} [filename=""] - If a filename is not provided, the image is saved as "hifi-snap-by-<user
|
||||
* name>-on-YYYY-MM-DD_HH-MM-SS".<br />
|
||||
* Still images are saved in JPEG or PNG format according to the extension provided — <code>".jpg"</code>,
|
||||
* name>-on-YYYY-MM-DD_HH-MM-SS".
|
||||
* <p>Still images are saved in JPEG or PNG format according to the extension provided — <code>".jpg"</code>,
|
||||
* <code>".jpeg"</code>, or <code>".png"</code> — or if not provided then in JPEG format with an extension of
|
||||
* <code>".jpg"</code>. Animated images are saved in GIF format.
|
||||
* <code>".jpg"</code>. Animated images are saved in GIF format.</p>
|
||||
*
|
||||
* @example <caption>Using the snapshot function and signals.</caption>
|
||||
* function onStillSnapshotTaken(path, notify) {
|
||||
|
@ -365,10 +365,10 @@ public slots:
|
|||
* @param {boolean} [notify=true] - This value is passed on through the {@link Window.stillSnapshotTaken|stillSnapshotTaken}
|
||||
* signal.
|
||||
* @param {string} [filename=""] - If a filename is not provided, the image is saved as "hifi-snap-by-<user
|
||||
* name>-on-YYYY-MM-DD_HH-MM-SS".<br />
|
||||
* Images are saved in JPEG or PNG format according to the extension provided — <code>".jpg"</code>,
|
||||
* name>-on-YYYY-MM-DD_HH-MM-SS".
|
||||
* <p>Images are saved in JPEG or PNG format according to the extension provided — <code>".jpg"</code>,
|
||||
* <code>".jpeg"</code>, or <code>".png"</code> — or if not provided then in JPEG format with an extension of
|
||||
* <code>".jpg"</code>.
|
||||
* <code>".jpg"</code>.</p>
|
||||
*/
|
||||
void takeSecondaryCameraSnapshot(const bool& notify = true, const QString& filename = QString());
|
||||
|
||||
|
@ -384,10 +384,10 @@ public slots:
|
|||
* @param {boolean} [notify=true] - This value is passed on through the {@link Window.stillSnapshotTaken|stillSnapshotTaken}
|
||||
* signal.
|
||||
* @param {string} [filename=""] - If a filename is not provided, the image is saved as "hifi-snap-by-<user
|
||||
* name>-on-YYYY-MM-DD_HH-MM-SS".<br />
|
||||
* Images are saved in JPEG or PNG format according to the extension provided — <code>".jpg"</code>,
|
||||
* name>-on-YYYY-MM-DD_HH-MM-SS".
|
||||
* <p>Images are saved in JPEG or PNG format according to the extension provided — <code>".jpg"</code>,
|
||||
* <code>".jpeg"</code>, or <code>".png"</code> — or if not provided then in JPEG format with an extension of
|
||||
* <code>".jpg"</code>.
|
||||
* <code>".jpg"</code>.</p>
|
||||
*/
|
||||
void takeSecondaryCamera360Snapshot(const glm::vec3& cameraPosition, const bool& cubemapOutputFormat = false, const bool& notify = true, const QString& filename = QString());
|
||||
|
||||
|
@ -515,13 +515,13 @@ public slots:
|
|||
|
||||
/**jsdoc
|
||||
* Opens a URL in the Interface window or other application, depending on the URL's scheme. The following schemes are
|
||||
* supported:<br />
|
||||
* supported:
|
||||
* <ul>
|
||||
* <li><code>hifi</code>: Navigate to the URL in Interface.</li>
|
||||
* <li><code>hifiapp</code>: Open a system app in Interface.</li>
|
||||
* </ul>
|
||||
* Other schemes will either be handled by the OS (e.g. <code>http</code>, <code>https</code>, or <code>mailto</code>) or
|
||||
* will display a dialog asking the user to confirm that they want to try to open the URL.
|
||||
* <p>Other schemes will either be handled by the OS (e.g. <code>http</code>, <code>https</code>, or <code>mailto</code>) or
|
||||
* will display a dialog asking the user to confirm that they want to try to open the URL.</p>
|
||||
* @function Window.openUrl
|
||||
* @param {string} url - The URL to open.
|
||||
*/
|
||||
|
@ -623,8 +623,8 @@ private slots:
|
|||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when you change the domain you're visiting. <strong>Warning:</strong> Is not emitted if you go to a domain
|
||||
* that isn't running.
|
||||
* Triggered when you change the domain you're visiting.
|
||||
* <p><strong>Warning:</strong> Is not emitted if you go to a domain that isn't running.</p>
|
||||
* @function Window.domainChanged
|
||||
* @param {string} domainURL - The domain's URL.
|
||||
* @returns {Signal}
|
||||
|
|
|
@ -56,8 +56,8 @@ namespace InteractiveWindowEnums {
|
|||
Q_NAMESPACE
|
||||
|
||||
/**jsdoc
|
||||
* A set of flags controlling <code>InteractiveWindow</code> behavior. The value is constructed by using the
|
||||
* <code>|</code> (bitwise OR) operator on the individual flag values.<br />
|
||||
* <p>A set of flags controlling <code>InteractiveWindow</code> behavior. The value is constructed by using the
|
||||
* <code>|</code> (bitwise OR) operator on the individual flag values.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Flag Name</th><th>Value</th><th>Description</th></tr>
|
||||
|
|
|
@ -1346,49 +1346,48 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* <td>Some text.</td>
|
||||
* <td>{@link Overlays.OverlayProperties-Text|OverlayProperties-Text}</td></tr>
|
||||
* <tr><td><code>"cube"</code></td><td>3D</td>
|
||||
* <td>A cube. A <code>"shape"</code> overlay can also be used to create a cube.<br/>
|
||||
* <span class="important">Deprecated.</span>
|
||||
* </td>
|
||||
* <td><p>A cube. A <code>"shape"</code> overlay can also be used to create a cube.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Cube|OverlayProperties-Cube}</td></tr>
|
||||
* <tr><td><code>"sphere"</code></td><td>3D</td>
|
||||
* <td>A sphere. A <code>"shape"</code> overlay can also be used to create a sphere.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>A sphere. A <code>"shape"</code> overlay can also be used to create a sphere.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Sphere|OverlayProperties-Sphere}</td></tr>
|
||||
* <tr><td><code>"shape"</code></td><td>3D</td>
|
||||
* <td>A geometric shape, such as a cube, sphere, or cylinder.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>A geometric shape, such as a cube, sphere, or cylinder.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Shape|OverlayProperties-Shape}</td></tr>
|
||||
* <tr><td><code>"model"</code></td><td>3D</td>
|
||||
* <td>A model.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>A model.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Model|OverlayProperties-Model}</td></tr>
|
||||
* <tr><td><code>"image3d"</code></td><td>3D</td>
|
||||
* <td>An image. Synonym: <code>"billboard"</code>.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>An image. Synonym: <code>"billboard"</code>.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Image3D|OverlayProperties-Image3D}</td></tr>
|
||||
* <tr><td><code>"rectangle3d"</code></td><td>3D</td>
|
||||
* <td>A rectangle.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>A rectangle.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Rectangle3D|OverlayProperties-Rectangle3D}</td></tr>
|
||||
* <tr><td><code>"text3d"</code></td><td>3D</td>
|
||||
* <td>Some text.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>Some text.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Text3D|OverlayProperties-Text3D}</td></tr>
|
||||
* <tr><td><code>"web3d"</code></td><td>3D</td>
|
||||
* <td>Web content.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>Web content.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Web3D|OverlayProperties-Web3D}</td></tr>
|
||||
* <tr><td><code>"line3d"</code></td><td>3D</td>
|
||||
* <td>A line.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>A line.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Line3D|OverlayProperties-Line3D}</td></tr>
|
||||
* <tr><td><code>"grid"</code></td><td>3D</td>
|
||||
* <td>A grid of lines in a plane.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>A grid of lines in a plane.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Grid|OverlayProperties-Grid}</td></tr>
|
||||
* <tr><td><code>"circle3d"</code></td><td>3D</td>
|
||||
* <td>A circle.<br/>
|
||||
* <span class="important">Deprecated.</span></td>
|
||||
* <td><p>A circle.</p>
|
||||
* <p class="important">Deprecated.</p></td>
|
||||
* <td>{@link Overlays.OverlayProperties-Circle3D|OverlayProperties-Circle3D}</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
|
@ -1410,17 +1409,17 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @see {@link Overlays.OverlayProperties-Rectangle|OverlayProperties-Rectangle}
|
||||
* @see {@link Overlays.OverlayProperties-Image|OverlayProperties-Image}
|
||||
* @see {@link Overlays.OverlayProperties-Text|OverlayProperties-Text}
|
||||
* @see {@link Overlays.OverlayProperties-Cube|OverlayProperties-Cube} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Sphere|OverlayProperties-Sphere} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Shape|OverlayProperties-Shape} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Model|OverlayProperties-Model} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Rectangle3D|OverlayProperties-Rectangle3D} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Image3D|OverlayProperties-Image3D} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Text3D|OverlayProperties-Text3D} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Web3D|OverlayProperties-Web3D} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Line3D|OverlayProperties-Line3D} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Grid|OverlayProperties-Grid} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Circle3D|OverlayProperties-Circle3D} <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Cube|OverlayProperties-Cube} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Sphere|OverlayProperties-Sphere} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Shape|OverlayProperties-Shape} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Model|OverlayProperties-Model} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Rectangle3D|OverlayProperties-Rectangle3D} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Image3D|OverlayProperties-Image3D} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Text3D|OverlayProperties-Text3D} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Web3D|OverlayProperties-Web3D} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Line3D|OverlayProperties-Line3D} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Grid|OverlayProperties-Grid} — <span class="important">Deprecated.</span>
|
||||
* @see {@link Overlays.OverlayProperties-Circle3D|OverlayProperties-Circle3D} — <span class="important">Deprecated.</span>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
|
@ -1502,11 +1501,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -1520,7 +1519,7 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* <code>parentID</code> set, otherwise the same value as <code>rotation</code>. Synonym: <code>localOrientation</code>.
|
||||
* @property {boolean} isSolid=false - <code>true</code> if the overlay is rendered as a solid, <code>false</code> if it is
|
||||
* rendered as a wire frame.
|
||||
* Synonyms: <ode>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Synonyms: <code>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Antonyms: <code>isWire</code> and <code>wire</code>.
|
||||
* @property {boolean} ignorePickIntersection=false - <code>true</code> if {@link Picks} ignore the overlay, <code>false</code>
|
||||
* if they don't.
|
||||
|
@ -1550,11 +1549,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -1568,7 +1567,7 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* <code>parentID</code> set, otherwise the same value as <code>rotation</code>. Synonym: <code>localOrientation</code>.
|
||||
* @property {boolean} isSolid=false - <code>true</code> if the overlay is rendered as a solid, <code>false</code> if it is
|
||||
* rendered as a wire frame.
|
||||
* Synonyms: <ode>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Synonyms: <code>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Antonyms: <code>isWire</code> and <code>wire</code>.
|
||||
* @property {boolean} ignorePickIntersection=false - <code>true</code> if {@link Picks} ignore the overlay, <code>false</code>
|
||||
* if they don't.
|
||||
|
@ -1599,11 +1598,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -1617,7 +1616,7 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* <code>parentID</code> set, otherwise the same value as <code>rotation</code>. Synonym: <code>localOrientation</code>.
|
||||
* @property {boolean} isSolid=false - <code>true</code> if the overlay is rendered as a solid, <code>false</code> if it is
|
||||
* rendered as a wire frame.
|
||||
* Synonyms: <ode>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Synonyms: <code>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Antonyms: <code>isWire</code> and <code>wire</code>.
|
||||
* @property {boolean} ignorePickIntersection=false - <code>true</code> if {@link Picks} ignore the overlay, <code>false</code>
|
||||
* if they don't.
|
||||
|
@ -1641,7 +1640,7 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* <tr><th>Value</th><th>Dimensions</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>"Circle"</code></td><td>2D</td><td>A circle oriented in 3D.</td></td></tr>
|
||||
* <tr><td><code>"Circle"</code></td><td>2D</td><td>A circle oriented in 3D.</td></tr>
|
||||
* <tr><td><code>"Cone"</code></td><td>3D</td><td></td></tr>
|
||||
* <tr><td><code>"Cube"</code></td><td>3D</td><td></td></tr>
|
||||
* <tr><td><code>"Cylinder"</code></td><td>3D</td><td></td></tr>
|
||||
|
@ -1674,11 +1673,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -1692,7 +1691,7 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* <code>parentID</code> set, otherwise the same value as <code>rotation</code>. Synonym: <code>localOrientation</code>.
|
||||
* @property {boolean} isSolid=false - <code>true</code> if the overlay is rendered as a solid, <code>false</code> if it is
|
||||
* rendered as a wire frame.
|
||||
* Synonyms: <ode>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Synonyms: <code>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Antonyms: <code>isWire</code> and <code>wire</code>.
|
||||
* @property {boolean} ignorePickIntersection=false - <code>true</code> if {@link Picks} ignore the overlay, <code>false</code>
|
||||
* if they don't.
|
||||
|
@ -1761,17 +1760,17 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {Color} color=255,255,255 - The color of the overlay text. Synonym: <code>textColor</code>.
|
||||
* @property {number} alpha=0.7 - The opacity of the overlay text, <code>0.0</code> – <code>1.0</code>.
|
||||
* <p><em>Currently not used; use <code>textAlpha</code> instead.</em></p>
|
||||
* <CURRENTLY BROKEN>
|
||||
* @comment CURRENTLY BROKEN
|
||||
* @property {number} pulseMax=0 - The maximum value of the pulse multiplier.
|
||||
* @property {number} pulseMin=0 - The minimum value of the pulse multiplier.
|
||||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -1811,11 +1810,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -1857,11 +1856,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -1916,41 +1915,45 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* HUD surface.
|
||||
* @property {boolean} grabbable=false - <code>true</code> if the overlay can be grabbed, <code>false</code> if it can't be.
|
||||
* @property {Uuid} parentID=null - The avatar, entity, or overlay that the overlay is parented to.
|
||||
* <p><em>Currently doesn't work.</em></p>
|
||||
* @comment CURRENTLY BROKEN
|
||||
* @property {number} parentJointIndex=65535 - Integer value specifying the joint of the entity or avatar that the entity is
|
||||
* parented to if <code>parentID</code> is set. Use 65535 or -1 to parent to the parent's position and orientation rather
|
||||
* than a joint.
|
||||
*
|
||||
* @property {Uuid} endParentID=null - The avatar, entity, or overlay that the end point of the line is parented to.
|
||||
* <p><em>Currently doesn't work.</em></p>
|
||||
* <CURRENTLY BROKEN>
|
||||
* @comment CURRENTLY BROKEN
|
||||
* @property {number} endParentJointIndex=65535 - Integer value specifying the skeleton joint that the end point of the line is
|
||||
* attached to if <code>parentID</code> is an avatar skeleton. A value of <code>65535</code> means "no joint".
|
||||
* <p><em>Currently doesn't work.</em></p>
|
||||
* <CURRENTLY BROKEN>
|
||||
* @comment CURRENTLY BROKEN
|
||||
|
||||
* @property {Vec3} start - The start point of the line. Synonyms: <code>startPoint</code> and <code>p1</code>.
|
||||
* <p><em>If <code>parentID<code> is set, use <code>localStart</code> to set the local position of the start point.</em></p>
|
||||
* <CURRENTLY BROKEN>
|
||||
* <p><strong>Note:</strong> If <code>parentID</code> is set, use <code>localStart</code> to set the local position of the
|
||||
* start point.</p>
|
||||
* @property {Vec3} end - The end point of the line. Synonyms: <code>endPoint</code> and <code>p2</code>.
|
||||
* <p><em>If <code>parentID<code> is set, use <code>localEnd</code> to set the local position of the end point.</em></p>
|
||||
* <CURRENTLY BROKEN>
|
||||
* <p><strong>Note:</strong> If <code>parentID</code> is set, use <code>localEnd</code> to set the local position of the
|
||||
* end point.</p>
|
||||
|
||||
* @property {Vec3} localStart - The local position of the overlay relative to its parent if the overlay has a
|
||||
* <code>parentID</code> set, otherwise the same value as <code>start</code>.
|
||||
* <CURRENTLY BROKEN>
|
||||
* <p><em>Currently doesn't work.</em></p>
|
||||
* @comment CURRENTLY BROKEN
|
||||
* @property {Vec3} localEnd - The local position of the overlay relative to its parent if the overlay has a
|
||||
* <code>endParentID</code> set, otherwise the same value as <code>end</code>.
|
||||
* <CURRENTLY BROKEN>
|
||||
* <p><em>Currently doesn't work.</em></p>
|
||||
* @comment CURRENTLY BROKEN
|
||||
|
||||
* @property {number} length - The length of the line, in meters. This can be set after creating a line with start and end
|
||||
* points.
|
||||
* <p><em>Currently doesn't work.</em></p>
|
||||
* <CURRENTLY BROKEN>
|
||||
* @comment CURRENTLY BROKEN
|
||||
|
||||
* @property {number} glow=0 - If <code>glow > 0</code>, the line is rendered with a glow.
|
||||
* @property {number} lineWidth=0.02 - Width of the line, in meters.
|
||||
* <p><em>You can set this property's value but currently cannot retrieve its value. Use the <code>strokeWidths</code>
|
||||
* property to retrieve its value instead.</p>
|
||||
* property to retrieve its value instead.</em></p>
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
|
@ -1967,11 +1970,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -2010,11 +2013,11 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* @property {number} pulsePeriod=1 - The duration of the color and alpha pulse, in seconds. A pulse multiplier value goes from
|
||||
* <code>pulseMin</code> to <code>pulseMax</code>, then <code>pulseMax</code> to <code>pulseMin</code> in one period.
|
||||
* @property {number} alphaPulse=0 - If non-zero, the alpha of the overlay is pulsed: the alpha value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
* @property {number} colorPulse=0 - If non-zero, the color of the overlay is pulsed: the color value is multiplied by the
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* current pulse multiplier value each frame. If > 0 the pulse multiplier is applied in phase with the pulse period; if < 0
|
||||
* the pulse multiplier is applied out of phase with the pulse period. (The magnitude of the property isn't otherwise
|
||||
* used.)
|
||||
*
|
||||
|
@ -2029,7 +2032,7 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
|||
* <code>parentID</code> set, otherwise the same value as <code>rotation</code>. Synonym: <code>localOrientation</code>.
|
||||
* @property {boolean} isSolid=false - <code>true</code> if the overlay is rendered as a solid, <code>false</code> if it is
|
||||
* rendered as a wire frame.
|
||||
* Synonyms: <ode>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Synonyms: <code>solid</code>, <code>isFilled</code>, and <code>filled</code>.
|
||||
* Antonyms: <code>isWire</code> and <code>wire</code>.
|
||||
* @property {boolean} ignorePickIntersection=false - <code>true</code> if {@link Picks} ignore the overlay, <code>false</code>
|
||||
* if they don't.
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
* <p>Specifies the initial conditions of the IK solver.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</p><th>Description</th>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>RelaxToUnderPoses</td><td>This is a blend: it is 15/16 <code>PreviousSolution</code>
|
||||
|
@ -73,12 +73,14 @@ public:
|
|||
* <tr><td><code>1</code></td><td>RelaxToLimitCenterPoses</td><td>This is a blend: it is 15/16
|
||||
* <code>PreviousSolution</code> and 1/16 <code>LimitCenterPoses</code>. This should converge quickly because it is
|
||||
* close to the previous solution, but still provides the benefits of avoiding limb locking.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>PreviousSolution</td><td>The IK system will begin to solve from the same position and
|
||||
* orientations for each joint that was the result from the previous frame.<br />
|
||||
* Pros: As the end effectors typically do not move much from frame to frame, this is likely to converge quickly
|
||||
* to a valid solution.<br />
|
||||
* Cons: If the previous solution resulted in an awkward or uncomfortable posture, the next frame will also be
|
||||
* awkward and uncomfortable. It can also result in locked elbows and knees.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>PreviousSolution</td><td>
|
||||
* <p>The IK system will begin to solve from the same position and orientations for each joint that was the result
|
||||
* from the previous frame.</p>
|
||||
* <p>Pros: As the end effectors typically do not move much from frame to frame, this is likely to converge quickly
|
||||
* to a valid solution.</p>
|
||||
* <p>Cons: If the previous solution resulted in an awkward or uncomfortable posture, the next frame will also be
|
||||
* awkward and uncomfortable. It can also result in locked elbows and knees.</p>
|
||||
* </td></tr>
|
||||
* <tr><td><code>3</code></td><td>UnderPoses</td><td>The IK occurs at one of the top-most layers. It has access to the
|
||||
* full posture that was computed via canned animations and blends. We call this animated set of poses the "under
|
||||
* pose". The under poses are what would be visible if IK was completely disabled. Using the under poses as the
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
* <p>Specifies sets of joints.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</p><th>Description</th>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>FullBodyBoneSet</td><td>All joints.</td></tr>
|
||||
|
|
|
@ -20,14 +20,14 @@ public:
|
|||
* <p>An IK target type.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</p><th>Description</th>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>RotationAndPosition</td><td>Attempt to reach the rotation and position end
|
||||
* effector.</td></tr>
|
||||
* <tr><td><code>1</code></td><td>RotationOnly</td><td>Attempt to reach the end effector rotation only.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>HmdHead</td><td>A special mode of IK that would attempt to prevent unnecessary
|
||||
* bending of the spine.<br />
|
||||
* <tr><td><code>2</code></td><td>HmdHead</td><td>
|
||||
* <p>A special mode of IK that would attempt to prevent unnecessary bending of the spine.</p>
|
||||
* <p class="important">Deprecated: This target type is deprecated and will be removed.</p></td></tr>
|
||||
* <tr><td><code>3</code></td><td>HipsRelativeRotationAndPosition</td><td>Attempt to reach a rotation and position end
|
||||
* effector that is not in absolute rig coordinates but is offset by the avatar hips translation.</td></tr>
|
||||
|
|
|
@ -95,7 +95,7 @@ static const QString MAIN_STATE_MACHINE_RIGHT_HAND_POSITION("mainStateMachineRig
|
|||
* <p><strong>Warning:</strong> These properties are subject to change.
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Name</th><th>Type</p><th>Description</th>
|
||||
* <tr><th>Name</th><th>Type</th><th>Description</th>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>userAnimNone</code></td><td>boolean</td><td><code>true</code> when no user overrideAnimation is
|
||||
|
|
|
@ -545,7 +545,7 @@ void Avatar::relayJointDataToChildren() {
|
|||
}
|
||||
|
||||
/**jsdoc
|
||||
* An avatar has different types of data simulated at different rates, in Hz.
|
||||
* <p>An avatar has different types of data simulated at different rates, in Hz.</p>
|
||||
*
|
||||
* <table>
|
||||
* <thead>
|
||||
|
|
|
@ -470,7 +470,7 @@ public:
|
|||
/**jsdoc
|
||||
* Sets the joint of the entity or avatar that the avatar is parented to.
|
||||
* @function MyAvatar.setParentJointIndex
|
||||
* @param {number} parentJointIndex - he joint of the entity or avatar that the avatar should be parented to. Use
|
||||
* @param {number} parentJointIndex - The joint of the entity or avatar that the avatar should be parented to. Use
|
||||
* <code>65535</code> or <code>-1</code> to parent to the entity or avatar's position and orientation rather than a
|
||||
* joint.
|
||||
*/
|
||||
|
|
|
@ -1445,7 +1445,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
|||
}
|
||||
|
||||
/**jsdoc
|
||||
* The avatar mixer data comprises different types of data, with the data rates of each being tracked in kbps.
|
||||
* <p>The avatar mixer data comprises different types of data, with the data rates of each being tracked in kbps.</p>
|
||||
*
|
||||
* <table>
|
||||
* <thead>
|
||||
|
@ -1550,7 +1550,7 @@ float AvatarData::getDataRate(const QString& rateName) const {
|
|||
}
|
||||
|
||||
/**jsdoc
|
||||
* The avatar mixer data comprises different types of data updated at different rates, in Hz.
|
||||
* <p>The avatar mixer data comprises different types of data updated at different rates, in Hz.</p>
|
||||
*
|
||||
* <table>
|
||||
* <thead>
|
||||
|
|
|
@ -1277,9 +1277,9 @@ public:
|
|||
* @param {number} [scale=1.0] - The scale to apply to the model.
|
||||
* @param {boolean} [isSoft=false] - If the model has a skeleton, set this to <code>true</code> so that the bones of the
|
||||
* attached model's skeleton are rotated to fit the avatar's current pose. <code>isSoft</code> is used, for example,
|
||||
* to have clothing that moves with the avatar.<br />
|
||||
* If <code>true</code>, the <code>translation</code>, <code>rotation</code>, and <code>scale</code> parameters are
|
||||
* ignored.
|
||||
* to have clothing that moves with the avatar.
|
||||
* <p>If <code>true</code>, the <code>translation</code>, <code>rotation</code>, and <code>scale</code> parameters are
|
||||
* ignored.</p>
|
||||
* @param {boolean} [allowDuplicates=false] - If <code>true</code> then more than one copy of any particular model may be
|
||||
* attached to the same joint; if <code>false</code> then the same model cannot be attached to the same joint.
|
||||
* @param {boolean} [useSaved=true] - <em>Not used.</em>
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace controller {
|
|||
* <tr><th>Property</th><th>Type</th><th>Data</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td colSpan=4><strong>Avatar Movement</strong></td>
|
||||
* <tr><td colSpan=4><strong>Avatar Movement</strong></td></tr>
|
||||
* <tr><td><code>TranslateX</code></td><td>number</td><td>number</td><td>Move the user's avatar in the direction of its
|
||||
* x-axis, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>TranslateY</code></td><td>number</td><td>number</td><td>Move the user's avatar in the direction of its
|
||||
|
@ -71,7 +71,7 @@ namespace controller {
|
|||
* step increment, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>StepRoll</code></td><td>number</td><td>number</td><td>No action.</td></tr>
|
||||
*
|
||||
* <tr><td colSpan=4><strong>Avatar Skeleton</strong></td>
|
||||
* <tr><td colSpan=4><strong>Avatar Skeleton</strong></td></tr>
|
||||
* <tr><td><code>Hips</code></td><td>number</td><td>{@link Pose}</td><td>Set the hips pose of the user's avatar.
|
||||
* </td></tr>
|
||||
* <tr><td><code>Spine2</code></td><td>number</td><td>{@link Pose}</td><td>Set the spine2 pose of the user's avatar.
|
||||
|
@ -171,7 +171,7 @@ namespace controller {
|
|||
* <tr><td><code>RightFoot</code></td><td>number</td><td>{@link Pose}</td><td>Set the right foot pose of the user's
|
||||
* avatar.</td></tr>
|
||||
*
|
||||
* <tr><td colSpan=4><strong><strong>Application</strong></td>
|
||||
* <tr><td colSpan=4><strong>Application</strong></td></tr>
|
||||
* <tr><td><code>BoomIn</code></td><td>number</td><td>number</td><td>Zoom camera in from third person toward first
|
||||
* person view.</td></tr>
|
||||
* <tr><td><code>BoomOut</code></td><td>number</td><td>number</td><td>Zoom camera out from first person to third
|
||||
|
@ -212,7 +212,7 @@ namespace controller {
|
|||
* <tr><td><code>SecondaryAction</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
|
||||
* action is deprecated and will be removed. It takes no action.</span></td></tr>
|
||||
*
|
||||
* <tr><td colSpan=4><strong>Aliases</strong></td>
|
||||
* <tr><td colSpan=4><strong>Aliases</strong></td></tr>
|
||||
* <tr><td><code>Backward</code></td><td>number</td><td>number</td><td>Alias for <code>TranslateZ</code> in the
|
||||
* positive direction.</td></tr>
|
||||
* <tr><td><code>Forward</code></td><td>number</td><td>number</td><td>Alias for <code>TranslateZ</code> in the negative
|
||||
|
@ -234,7 +234,7 @@ namespace controller {
|
|||
* <tr><td><code>YawRight</code></td><td>number</td><td>number</td><td>Alias for <code>Yaw</code> in the negative
|
||||
* direction.</td></tr>
|
||||
*
|
||||
* <tr><td colSpan=4><strong>Deprecated Aliases</strong></td>
|
||||
* <tr><td colSpan=4><strong>Deprecated Aliases</strong></td></tr>
|
||||
* <tr><td><code>LEFT_HAND</code></td><td>number</td><td>{@link Pose}</td><td><span class="important">Deprecated: This
|
||||
* action is deprecated and will be removed. Use <code>LeftHand</code> instead.</span></td></tr>
|
||||
* <tr><td><code>RIGHT_HAND</code></td><td>number</td><td>{@link Pose}</td><td><span class="important">Deprecated: This
|
||||
|
@ -282,7 +282,7 @@ namespace controller {
|
|||
* <tr><td><code>ACTION2</code></td><td>number</td><td>number</td><td><span class="important">Deprecated: This
|
||||
* action is deprecated and will be removed. Use <code>SecondaryAction</code> instead.</span></td></tr>
|
||||
*
|
||||
* <tr><td colSpan=4><strong>Deprecated Trackers</strong></td>
|
||||
* <tr><td colSpan=4><strong>Deprecated Trackers</strong></td><tr>
|
||||
* <tr><td><code>TrackedObject00</code></td><td>number</td><td>{@link Pose}</td><td><span class="important">Deprecated:
|
||||
* This action is deprecated and will be removed. It takes no action.</span></td></tr>
|
||||
* <tr><td><code>TrackedObject01</code></td><td>number</td><td>{@link Pose}</td><td><span class="important">Deprecated:
|
||||
|
|
|
@ -33,7 +33,7 @@ void StandardController::focusOutEvent() {
|
|||
* identifying each output. <em>Read-only.</em></p>
|
||||
* <p>These outputs can be mapped to actions or functions in a {@link RouteObject} mapping. The data value provided by each
|
||||
* control is either a number or a {@link Pose}. Numbers are typically normalized to <code>0.0</code> or <code>1.0</code> for
|
||||
* button states, the range <code>0.0</code> – </code>1.0</code> for unidirectional scales, and the range
|
||||
* button states, the range <code>0.0</code> – <code>1.0</code> for unidirectional scales, and the range
|
||||
* <code>-1.0</code> – <code>1.0</code> for bidirectional scales.</p>
|
||||
* <p>Each hardware device has a mapping from its outputs to a subset of <code>Controller.Standard</code> items, specified in a
|
||||
* JSON file. For example,
|
||||
|
@ -118,8 +118,7 @@ void StandardController::focusOutEvent() {
|
|||
* button.</td></tr>
|
||||
* <tr><td><code>RightThumbUp</code></td><td>number</td><td>number</td><td>Right thumb not touching primary or secondary
|
||||
* thumb buttons.</td></tr>
|
||||
* <tr><td><code>LeftPrimaryIndex</code></td><td>number</td><td>number</td><td>Left primary index control
|
||||
* pressed.</em></td></tr>
|
||||
* <tr><td><code>LeftPrimaryIndex</code></td><td>number</td><td>number</td><td>Left primary index control pressed.</td></tr>
|
||||
* <tr><td><code>LeftSecondaryIndex</code></td><td>number</td><td>number</td><td>Left secondary index control pressed.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightPrimaryIndex</code></td><td>number</td><td>number</td><td>Right primary index control pressed.
|
||||
|
|
|
@ -86,7 +86,7 @@ class UserInputMapper;
|
|||
* @typedef {object} Controller.MappingJSONRoute
|
||||
* @property {string|Controller.MappingJSONAxis} from - The name of a {@link Controller.Hardware} property or an axis made from
|
||||
* them. If a property name, the leading <code>"Controller.Hardware."</code> can be omitted.
|
||||
* @property {boolean} [peek=false] - If <codd>true</code>, then peeking is enabled per {@link RouteObject#peek}.
|
||||
* @property {boolean} [peek=false] - If <code>true</code>, then peeking is enabled per {@link RouteObject#peek}.
|
||||
* @property {boolean} [debug=false] - If <code>true</code>, then debug is enabled per {@link RouteObject#debug}.
|
||||
* @property {string|string[]} [when=[]] - One or more numeric {@link Controller.Hardware} property names which are evaluated
|
||||
* as booleans and ANDed together. Prepend a property name with a <code>!</code> to do a logical NOT. The leading
|
||||
|
@ -135,8 +135,8 @@ public:
|
|||
|
||||
/**jsdoc
|
||||
* Creates a new {@link RouteObject} from a controller output, ready to be mapped to a standard control, action, or
|
||||
* function.<br />
|
||||
* This is a QML-specific version of {@link MappingObject#from|from}: use this version in QML files.
|
||||
* function.
|
||||
* <p>This is a QML-specific version of {@link MappingObject#from|from}: use this version in QML files.</p>
|
||||
* @function MappingObject#fromQml
|
||||
* @param {Controller.Standard|Controller.Hardware|function} source - The controller output or function that is the source
|
||||
* of the route data. If a function, it must return a number or a {@link Pose} value as the route data.
|
||||
|
@ -146,8 +146,8 @@ public:
|
|||
|
||||
/**jsdoc
|
||||
* Creates a new {@link RouteObject} from two numeric {@link Controller.Hardware} outputs, one applied in the negative
|
||||
* direction and the other in the positive direction, ready to be mapped to a standard control, action, or function.<br />
|
||||
* This is a QML-specific version of {@link MappingObject#makeAxis|makeAxis}: use this version in QML files.
|
||||
* direction and the other in the positive direction, ready to be mapped to a standard control, action, or function.
|
||||
* <p>This is a QML-specific version of {@link MappingObject#makeAxis|makeAxis}: use this version in QML files.</p>
|
||||
* @function MappingObject#makeAxisQml
|
||||
* @param {Controller.Hardware} source1 - The first, negative-direction controller output.
|
||||
* @param {Controller.Hardware} source2 - The second, positive-direction controller output.
|
||||
|
@ -189,8 +189,8 @@ public:
|
|||
Q_INVOKABLE QObject* makeAxis(const QScriptValue& source1, const QScriptValue& source2);
|
||||
|
||||
/**jsdoc
|
||||
* Enables or disables the mapping. When enabled, the routes in the mapping take effect.<br />
|
||||
* Synonymous with {@link Controller.enableMapping}.
|
||||
* Enables or disables the mapping. When enabled, the routes in the mapping take effect.
|
||||
* <p>Synonymous with {@link Controller.enableMapping}.</p>
|
||||
* @function MappingObject#enable
|
||||
* @param {boolean} enable=true - If <code>true</code> then the mapping is enabled, otherwise it is disabled.
|
||||
* @returns {MappingObject} The mapping object, so that further routes can be added.
|
||||
|
@ -198,8 +198,8 @@ public:
|
|||
Q_INVOKABLE QObject* enable(bool enable = true);
|
||||
|
||||
/**jsdoc
|
||||
* Disables the mapping. When disabled, the routes in the mapping have no effect.<br />
|
||||
* Synonymous with {@link Controller.disableMapping}.
|
||||
* Disables the mapping. When disabled, the routes in the mapping have no effect.
|
||||
* <p>Synonymous with {@link Controller.disableMapping}.</p>
|
||||
* @function MappingObject#disable
|
||||
* @returns {MappingObject} The mapping object, so that further routes can be added.
|
||||
*/
|
||||
|
|
|
@ -52,8 +52,8 @@ class RouteBuilderProxy : public QObject {
|
|||
|
||||
/**jsdoc
|
||||
* Terminates the route with a standard control, an action, or a script function. The output value from the route is
|
||||
* sent to the specified destination.<br />
|
||||
* This is a QML-specific version of {@link MappingObject#to|to}: use this version in QML files.
|
||||
* sent to the specified destination.
|
||||
* <p>This is a QML-specific version of {@link MappingObject#to|to}: use this version in QML files.</p>
|
||||
* @function RouteObject#toQml
|
||||
* @param {Controller.Standard|Controller.Actions|function} destination - The standard control, action, or JavaScript
|
||||
* function that the route output is mapped to. For a function, the parameter can be either the name of the function or
|
||||
|
@ -64,8 +64,8 @@ class RouteBuilderProxy : public QObject {
|
|||
/**jsdoc
|
||||
* Processes the route only if a condition is satisfied. The condition is evaluated before the route input is read, and
|
||||
* the input is read only if the condition is <code>true</code>. Thus, if the condition is not met then subsequent
|
||||
* routes using the same input are processed.<br />
|
||||
* This is a QML-specific version of {@link MappingObject#to|to}: use this version in QML files.
|
||||
* routes using the same input are processed.
|
||||
* <p>This is a QML-specific version of {@link MappingObject#when|when}: use this version in QML files.</p>
|
||||
* @function RouteObject#whenQml
|
||||
* @param {condition|condition[]} expression - <p>A <code>condition</code> may be a:</p>
|
||||
* <ul>
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QDesktopWidget>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QQuickWindow>
|
||||
#include <QtQuick/QQuickWindow>
|
||||
|
||||
#include <DebugDraw.h>
|
||||
#include <shared/QtHelpers.h>
|
||||
|
@ -177,9 +177,35 @@ QPointF CompositorHelper::getMouseEventPosition(QMouseEvent* event) {
|
|||
return event->localPos();
|
||||
}
|
||||
|
||||
static bool isWindowActive() {
|
||||
for (const auto& window : QGuiApplication::topLevelWindows()) {
|
||||
if (window->isActive()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompositorHelper::shouldCaptureMouse() const {
|
||||
if (!_allowMouseCapture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isHMD()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!isWindowActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui::Menu::isSomeSubmenuShown()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we're in HMD mode, and some window of ours is active, but we're not currently showing a popup menu
|
||||
return _allowMouseCapture && isHMD() && QApplication::activeWindow() && !ui::Menu::isSomeSubmenuShown();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CompositorHelper::setAllowMouseCapture(bool capture) {
|
||||
|
@ -206,9 +232,9 @@ void CompositorHelper::handleLeaveEvent() {
|
|||
mainWidgetFrame.moveTopLeft(topLeftScreen);
|
||||
}
|
||||
QRect uncoveredRect = mainWidgetFrame;
|
||||
foreach(QWidget* widget, QApplication::topLevelWidgets()) {
|
||||
if (widget->isWindow() && widget->isVisible() && widget != mainWidget) {
|
||||
QRect widgetFrame = widget->frameGeometry();
|
||||
for(QWindow* window : QGuiApplication::topLevelWindows()) {
|
||||
if (window->isVisible() && window != mainWidget->windowHandle()) {
|
||||
QRect widgetFrame = window->frameGeometry();
|
||||
if (widgetFrame.intersects(uncoveredRect)) {
|
||||
QRect intersection = uncoveredRect & widgetFrame;
|
||||
if (intersection.top() > uncoveredRect.top()) {
|
||||
|
@ -292,7 +318,7 @@ glm::vec2 CompositorHelper::getReticleMaximumPosition() const {
|
|||
if (isHMD()) {
|
||||
result = VIRTUAL_SCREEN_SIZE;
|
||||
} else {
|
||||
QRect rec = QApplication::desktop()->screenGeometry();
|
||||
QRect rec = QGuiApplication::primaryScreen()->geometry();
|
||||
result = glm::vec2(rec.right(), rec.bottom());
|
||||
}
|
||||
return result;
|
||||
|
@ -308,8 +334,8 @@ void CompositorHelper::sendFakeMouseEvent() {
|
|||
// in HMD mode we need to fake our mouse moves...
|
||||
QPoint globalPos(_reticlePositionInHMD.x, _reticlePositionInHMD.y);
|
||||
auto button = Qt::NoButton;
|
||||
auto buttons = QApplication::mouseButtons();
|
||||
auto modifiers = QApplication::keyboardModifiers();
|
||||
auto buttons = QGuiApplication::mouseButtons();
|
||||
auto modifiers = QGuiApplication::keyboardModifiers();
|
||||
QMouseEvent event(QEvent::MouseMove, globalPos, button, buttons, modifiers);
|
||||
_fakeMouseEvent = true;
|
||||
qApp->sendEvent(_renderingWidget, &event);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <gl/Config.h>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QFileInfo>
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include <shaders/Shaders.h>
|
||||
#include <gpu/gl/GLShared.h>
|
||||
#include <gpu/gl/GLBackend.h>
|
||||
#include <gpu/gl/GLTexelFormat.h>
|
||||
#include <GeometryCache.h>
|
||||
|
||||
#include <CursorManager.h>
|
||||
|
@ -371,7 +373,7 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha();
|
||||
cursorData.texture->setUsage(usage.build());
|
||||
cursorData.texture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
cursorData.texture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
cursorData.texture->assignStoredMip(0, image.sizeInBytes(), image.constBits());
|
||||
cursorData.texture->setAutoGenerateMips(true);
|
||||
}
|
||||
}
|
||||
|
@ -475,30 +477,48 @@ void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) {
|
|||
});
|
||||
}
|
||||
|
||||
ktx::StoragePointer textureToKtx(const gpu::Texture& texture) {
|
||||
ktx::Header header;
|
||||
{
|
||||
auto gpuDims = texture.getDimensions();
|
||||
header.pixelWidth = gpuDims.x;
|
||||
header.pixelHeight = gpuDims.y;
|
||||
header.pixelDepth = 0;
|
||||
}
|
||||
|
||||
{
|
||||
auto gltexelformat = gpu::gl::GLTexelFormat::evalGLTexelFormat(texture.getStoredMipFormat());
|
||||
header.glInternalFormat = gltexelformat.internalFormat;
|
||||
header.glFormat = gltexelformat.format;
|
||||
header.glBaseInternalFormat = gltexelformat.format;
|
||||
header.glType = gltexelformat.type;
|
||||
header.glTypeSize = 1;
|
||||
header.numberOfMipmapLevels = 1 + texture.getMaxMip();
|
||||
}
|
||||
|
||||
auto memKtx = ktx::KTX::createBare(header);
|
||||
auto storage = memKtx->_storage;
|
||||
uint32_t faceCount = std::max(header.numberOfFaces, 1u);
|
||||
uint32_t mipCount = std::max(header.numberOfMipmapLevels, 1u);
|
||||
for (uint32_t mip = 0; mip < mipCount; ++mip) {
|
||||
for (uint32_t face = 0; face < faceCount; ++face) {
|
||||
const auto& image = memKtx->_images[mip];
|
||||
auto& faceBytes = const_cast<gpu::Byte*&>(image._faceBytes[face]);
|
||||
if (texture.isStoredMipFaceAvailable(mip, face)) {
|
||||
auto storedImage = texture.accessStoredMipFace(mip, face);
|
||||
auto storedSize = storedImage->size();
|
||||
memcpy(faceBytes, storedImage->data(), storedSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::captureFrame(const std::string& filename) const {
|
||||
withOtherThreadContext([&] {
|
||||
using namespace gpu;
|
||||
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
|
||||
FramebufferPointer framebuffer{ Framebuffer::create("captureFramebuffer") };
|
||||
TextureCapturer captureLambda = [&](const std::string& filename, const gpu::TexturePointer& texture, uint16 layer) {
|
||||
QImage image;
|
||||
if (texture->getUsageType() == TextureUsageType::STRICT_RESOURCE) {
|
||||
image = QImage{ 1, 1, QImage::Format_ARGB32 };
|
||||
auto storedImage = texture->accessStoredMipFace(0, 0);
|
||||
memcpy(image.bits(), storedImage->data(), image.sizeInBytes());
|
||||
//if (texture == textureCache->getWhiteTexture()) {
|
||||
//} else if (texture == textureCache->getBlackTexture()) {
|
||||
//} else if (texture == textureCache->getBlueTexture()) {
|
||||
//} else if (texture == textureCache->getGrayTexture()) {
|
||||
} else {
|
||||
ivec4 rect = { 0, 0, texture->getWidth(), texture->getHeight() };
|
||||
framebuffer->setRenderBuffer(0, texture, layer);
|
||||
glBackend->syncGPUObject(*framebuffer);
|
||||
|
||||
image = QImage{ rect.z, rect.w, QImage::Format_ARGB32 };
|
||||
glBackend->downloadFramebuffer(framebuffer, rect, image);
|
||||
}
|
||||
QImageWriter(filename.c_str()).write(image);
|
||||
TextureCapturer captureLambda = [&](const gpu::TexturePointer& texture)->storage::StoragePointer {
|
||||
return textureToKtx(*texture);
|
||||
};
|
||||
|
||||
if (_currentFrame) {
|
||||
|
|
|
@ -290,7 +290,7 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
_previewTexture->setSource("HMD Preview Texture");
|
||||
_previewTexture->setUsage(gpu::Texture::Usage::Builder().withColor().build());
|
||||
_previewTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
_previewTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
_previewTexture->assignStoredMip(0, image.sizeInBytes(), image.constBits());
|
||||
_previewTexture->setAutoGenerateMips(true);
|
||||
|
||||
auto viewport = getViewportForSourceSize(uvec2(_previewTexture->getDimensions()));
|
||||
|
|
|
@ -168,47 +168,52 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
|
|||
entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider);
|
||||
|
||||
// Connect mouse events to entity script callbacks
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event);
|
||||
// FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event);
|
||||
});
|
||||
if (!_mouseAndPreloadSignalHandlersConnected) {
|
||||
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event);
|
||||
// FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event);
|
||||
});
|
||||
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event);
|
||||
});
|
||||
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event);
|
||||
});
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event);
|
||||
});
|
||||
|
||||
connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) {
|
||||
EntityItemPointer entity = getTree()->findEntityByID(entityID);
|
||||
if (entity) {
|
||||
entity->setScriptHasFinishedPreload(true);
|
||||
}
|
||||
});
|
||||
connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) {
|
||||
EntityItemPointer entity = getTree()->findEntityByID(entityID);
|
||||
if (entity) {
|
||||
entity->setScriptHasFinishedPreload(true);
|
||||
}
|
||||
});
|
||||
|
||||
_mouseAndPreloadSignalHandlersConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::stopDomainAndNonOwnedEntities() {
|
||||
|
|
|
@ -210,6 +210,8 @@ private:
|
|||
std::function<RayToEntityIntersectionResult(unsigned int)> _getPrevRayPickResultOperator;
|
||||
std::function<void(unsigned int, bool)> _setPrecisionPickingOperator;
|
||||
|
||||
bool _mouseAndPreloadSignalHandlersConnected { false };
|
||||
|
||||
class LayeredZone {
|
||||
public:
|
||||
LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {}
|
||||
|
|
|
@ -130,8 +130,8 @@ variables. These argument variables are used by the code which is run when bull
|
|||
* <tr><td><code>"ball-socket"</code></td><td>Object constraint</td>
|
||||
* <td>Connects two entities with a ball and socket joint.</td>
|
||||
* <td>{@link Entities.ActionArguments-BallSocket}</td></tr>
|
||||
* <tr><td><code>"spring"</code></td><td colspan="3">Synonym for <code>"tractor"</code>.
|
||||
* <span class="important">Deprecated.</span></td></tr>
|
||||
* <tr><td><code>"spring"</code></td><td> </td><td>Synonym for <code>"tractor"</code>.
|
||||
* <p class="important">Deprecated.</p></td><td> </td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {string} Entities.ActionType
|
||||
|
|
|
@ -940,7 +940,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* @property {number} materialMappingRot=0 - How much to rotate the material within the parent's UV-space, in degrees.
|
||||
* @property {boolean} materialRepeat=true - <code>true</code> if the material repeats, <code>false</code> if it doesn't. If
|
||||
* <code>false</code>, fragments outside of texCoord 0 – 1 will be discarded. Works in both <code>"uv"</code> and
|
||||
* </code>"projected"</code> modes.
|
||||
* <code>"projected"</code> modes.
|
||||
* @example <caption>Color a sphere using a Material entity.</caption>
|
||||
* var entityID = Entities.addEntity({
|
||||
* type: "Sphere",
|
||||
|
@ -1213,10 +1213,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* <code>dimensions / voxelVolumesize</code>.
|
||||
* @property {string} voxelData="ABAAEAAQAAAAHgAAEAB42u3BAQ0AAADCoPdPbQ8HFAAAAPBuEAAAAQ==" - Base-64 encoded compressed dump of
|
||||
* the PolyVox data. This property is typically not used in scripts directly; rather, functions that manipulate a PolyVox
|
||||
* entity update it.<br />
|
||||
* The size of this property increases with the size and complexity of the PolyVox entity, with the size depending on how
|
||||
* entity update it.
|
||||
* <p>The size of this property increases with the size and complexity of the PolyVox entity, with the size depending on how
|
||||
* the particular entity's voxels compress. Because this property value has to fit within a High Fidelity datagram packet,
|
||||
* there is a limit to the size and complexity of a PolyVox entity; edits which would result in an overflow are rejected.
|
||||
* there is a limit to the size and complexity of a PolyVox entity; edits which would result in an overflow are rejected.</p>
|
||||
* @property {Entities.PolyVoxSurfaceStyle} voxelSurfaceStyle=2 - The style of rendering the voxels' surface and how
|
||||
* neighboring PolyVox entities are joined.
|
||||
* @property {string} xTextureURL="" - The URL of the texture to map to surfaces perpendicular to the entity's local x-axis.
|
||||
|
@ -1305,7 +1305,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* @property {number} bottomMargin=0.0 - The bottom margin, in meters.
|
||||
* @property {boolean} unlit=false - <code>true</code> if the entity is unaffected by lighting, <code>false</code> if it is lit
|
||||
* by the key light and local lights.
|
||||
* @property {string} font="" - The font to render the text with. It can be one of the following: <code>"Courier"</code,
|
||||
* @property {string} font="" - The font to render the text with. It can be one of the following: <code>"Courier"</code>,
|
||||
* <code>"Inconsolata"</code>, <code>"Roboto"</code>, <code>"Timeless"</code>, or a path to a .sdff file.
|
||||
* @property {Entities.TextEffect} textEffect="none" - The effect that is applied to the text.
|
||||
* @property {Color} textEffectColor=255,255,255 - The color of the effect.
|
||||
|
|
|
@ -666,7 +666,7 @@ QScriptValue EntityScriptingInterface::getMultipleEntityProperties(QScriptContex
|
|||
const int ARGUMENT_EXTENDED_DESIRED_PROPERTIES = 1;
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
const auto entityIDs = qScriptValueToValue<QVector<QUuid>>(context->argument(ARGUMENT_ENTITY_IDS));
|
||||
const auto entityIDs = qscriptvalue_cast<QVector<QUuid>>(context->argument(ARGUMENT_ENTITY_IDS));
|
||||
return entityScriptingInterface->getMultipleEntityPropertiesInternal(engine, entityIDs, context->argument(ARGUMENT_EXTENDED_DESIRED_PROPERTIES));
|
||||
}
|
||||
|
||||
|
@ -716,7 +716,7 @@ QScriptValue EntityScriptingInterface::getMultipleEntityPropertiesInternal(QScri
|
|||
psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::FlagsActive);
|
||||
}
|
||||
|
||||
EntityPropertyFlags desiredProperties = qScriptValueToValue<EntityPropertyFlags>(extendedDesiredProperties);
|
||||
EntityPropertyFlags desiredProperties = qscriptvalue_cast<EntityPropertyFlags>(extendedDesiredProperties);
|
||||
bool needsScriptSemantics = desiredProperties.getHasProperty(PROP_POSITION) ||
|
||||
desiredProperties.getHasProperty(PROP_ROTATION) ||
|
||||
desiredProperties.getHasProperty(PROP_LOCAL_POSITION) ||
|
||||
|
|
|
@ -106,8 +106,9 @@ public:
|
|||
* "domain" entities, travel to different domains with a user as "avatar" entities, or be visible only to an individual user as
|
||||
* "local" entities (a.k.a. "overlays").
|
||||
*
|
||||
* <p>Note: For Interface scripts, the entities available to scripts are those that Interface has displayed and so knows
|
||||
* about.</p>
|
||||
* <p>Note: For Interface, avatar, and client entity scripts, the entities available to scripts are those that Interface has
|
||||
* displayed and so knows about. For assignment client scripts, the entities available are those that are "seen" by the
|
||||
* {@link EntityViewer}. For entity server scripts, all entities are available.</p>
|
||||
*
|
||||
* <h3>Entity Methods</h3>
|
||||
*
|
||||
|
@ -1871,7 +1872,7 @@ public slots:
|
|||
/**jsdoc
|
||||
* Called when a {@link Entities.getMeshes} call is complete.
|
||||
* @callback Entities~getMeshesCallback
|
||||
* @param {MeshProxy[]} meshes - If <code>success<</code> is <code>true</code>, a {@link MeshProxy} per mesh in the
|
||||
* @param {MeshProxy[]} meshes - If <code>success</code> is <code>true</code>, a {@link MeshProxy} per mesh in the
|
||||
* <code>Model</code> or <code>PolyVox</code> entity; otherwise <code>undefined</code>.
|
||||
* @param {boolean} success - <code>true</code> if the {@link Entities.getMeshes} call was successful, <code>false</code>
|
||||
* otherwise. The call may be unsuccessful if the requested entity could not be found.
|
||||
|
|
|
@ -46,18 +46,18 @@ public:
|
|||
* See also, the <code>"Box"</code> and <code>"Sphere"</code> entity types.</td>
|
||||
* <td>{@link Entities.EntityProperties-Shape|EntityProperties-Shape}</td></tr>
|
||||
* <tr><td><code>"Box"</code></td><td>A rectangular prism. This is a synonym of <code>"Shape"</code> for the case
|
||||
* where the entity's <code>shape</code> property value is <code>"Cube"</code>.<br />
|
||||
* If an entity is created with its <code>type</code>
|
||||
* where the entity's <code>shape</code> property value is <code>"Cube"</code>.
|
||||
* <p>If an entity is created with its <code>type</code>
|
||||
* set to <code>"Box"</code> it will always be created with a <code>shape</code> property value of
|
||||
* <code>"Cube"</code>. If an entity of type <code>Shape</code> or <code>Sphere</code> has its <code>shape</code> set
|
||||
* to <code>"Cube"</code> then its <code>type</code> will be reported as <code>"Box"</code>.
|
||||
* to <code>"Cube"</code> then its <code>type</code> will be reported as <code>"Box"</code>.</p></td>
|
||||
* <td>{@link Entities.EntityProperties-Box|EntityProperties-Box}</td></tr>
|
||||
* <tr><td><code>"Sphere"</code></td><td>A sphere. This is a synonym of <code>"Shape"</code> for the case
|
||||
* where the entity's <code>shape</code> property value is <code>"Sphere"</code>.<br />
|
||||
* If an entity is created with its <code>type</code>
|
||||
* where the entity's <code>shape</code> property value is <code>"Sphere"</code>.
|
||||
* <p>If an entity is created with its <code>type</code>
|
||||
* set to <code>"Sphere"</code> it will always be created with a <code>shape</code> property value of
|
||||
* <code>"Sphere"</code>. If an entity of type <code>Box</code> or <code>Shape</code> has its <code>shape</code> set
|
||||
* to <code>"Sphere"</code> then its <code>type</code> will be reported as <code>"Sphere"</code>.
|
||||
* to <code>"Sphere"</code> then its <code>type</code> will be reported as <code>"Sphere"</code>.</td>
|
||||
* <td>{@link Entities.EntityProperties-Sphere|EntityProperties-Sphere}</td></tr>
|
||||
* <tr><td><code>"Model"</code></td><td>A mesh model from a glTF, FBX, or OBJ file.</td>
|
||||
* <td>{@link Entities.EntityProperties-Model|EntityProperties-Model}</td></tr>
|
||||
|
|
|
@ -1859,7 +1859,7 @@ bool GLTFSerializer::readArray(const hifi::ByteArray& bin, int byteOffset, int c
|
|||
break;
|
||||
default:
|
||||
qWarning(modelformat) << "Unknown accessorType: " << accessorType;
|
||||
blobstream.unsetDevice();
|
||||
blobstream.setDevice(nullptr);
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
|
@ -1869,13 +1869,13 @@ bool GLTFSerializer::readArray(const hifi::ByteArray& bin, int byteOffset, int c
|
|||
blobstream >> value;
|
||||
outarray.push_back(value);
|
||||
} else {
|
||||
blobstream.unsetDevice();
|
||||
blobstream.setDevice(nullptr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blobstream.unsetDevice();
|
||||
blobstream.setDevice(nullptr);
|
||||
return true;
|
||||
}
|
||||
template<typename T>
|
||||
|
|
136
libraries/gpu/src/gpu/FrameIO.cpp
Normal file
136
libraries/gpu/src/gpu/FrameIO.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2019/10/03
|
||||
// Copyright 2013-2019 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 "FrameIO.h"
|
||||
#include <shared/Storage.h>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace gpu::hfb;
|
||||
|
||||
static bool skip(const uint8_t*& ptr, size_t& remaining, uint32_t size) {
|
||||
if (remaining < size) {
|
||||
return false;
|
||||
}
|
||||
ptr += size;
|
||||
remaining -= size;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool read(const uint8_t*& ptr, size_t& remaining, T& output) {
|
||||
uint32_t readSize = (uint32_t)sizeof(T);
|
||||
if (remaining < readSize) {
|
||||
return false;
|
||||
}
|
||||
memcpy(&output, ptr, readSize);
|
||||
return skip(ptr, remaining, readSize);
|
||||
}
|
||||
|
||||
Descriptor::Descriptor(const StoragePointer& storage) : storage(storage) {
|
||||
const auto* const start = storage->data();
|
||||
const auto* ptr = storage->data();
|
||||
auto remaining = storage->size();
|
||||
|
||||
try {
|
||||
// Can't parse files more than 4GB
|
||||
if (remaining > UINT32_MAX) {
|
||||
throw std::runtime_error("File too large");
|
||||
}
|
||||
|
||||
if (!read(ptr, remaining, header)) {
|
||||
throw std::runtime_error("Couldn't read binary header");
|
||||
}
|
||||
|
||||
if (header.length != storage->size()) {
|
||||
throw std::runtime_error("Header/Actual size mismatch");
|
||||
}
|
||||
|
||||
while (remaining != 0) {
|
||||
chunks.emplace_back();
|
||||
auto& chunk = chunks.back();
|
||||
ChunkHeader& chunkHeader = chunk;
|
||||
if (!read(ptr, remaining, chunkHeader)) {
|
||||
throw std::runtime_error("Coulnd't read chunk header");
|
||||
}
|
||||
chunk.offset = (uint32_t)(ptr - start);
|
||||
if (chunk.end() > storage->size()) {
|
||||
throw std::runtime_error("Chunk too large for file");
|
||||
}
|
||||
if (!skip(ptr, remaining, chunk.length)) {
|
||||
throw std::runtime_error("Skip chunk data failed");
|
||||
}
|
||||
}
|
||||
} catch (const std::runtime_error&) {
|
||||
// LOG somnething
|
||||
header.magic = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t Chunk::end() const {
|
||||
size_t result = offset;
|
||||
result += length;
|
||||
return result;
|
||||
}
|
||||
|
||||
StoragePointer Descriptor::getChunk(uint32_t chunkIndex) const {
|
||||
if (chunkIndex >= chunks.size()) {
|
||||
return {};
|
||||
}
|
||||
const auto& chunk = chunks[chunkIndex];
|
||||
if (chunk.end() > storage->size()) {
|
||||
return {};
|
||||
}
|
||||
return storage->createView(chunk.length, chunk.offset);
|
||||
}
|
||||
|
||||
static void writeUint(uint8_t*& dest, uint32_t value) {
|
||||
memcpy(dest, &value, sizeof(uint32_t));
|
||||
dest += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void writeChunk(uint8_t*& dest, uint32_t chunkType, const T& chunkData) {
|
||||
uint32_t chunkSize = static_cast<uint32_t>(chunkData.size());
|
||||
writeUint(dest, chunkSize);
|
||||
writeUint(dest, chunkType);
|
||||
memcpy(dest, chunkData.data(), chunkSize);
|
||||
dest += chunkSize;
|
||||
}
|
||||
|
||||
void gpu::hfb::writeFrame(const std::string& filename,
|
||||
const std::string& json,
|
||||
const Buffer& binaryBuffer,
|
||||
const StorageBuilders& ktxBuilders) {
|
||||
uint32_t strLen = (uint32_t)json.size();
|
||||
uint32_t size = gpu::hfb::HEADER_SIZE + gpu::hfb::CHUNK_HEADER_SIZE + strLen;
|
||||
size += gpu::hfb::CHUNK_HEADER_SIZE + (uint32_t)binaryBuffer.size();
|
||||
for (const auto& builder : ktxBuilders) {
|
||||
auto storage = builder();
|
||||
if (storage) {
|
||||
size += gpu::hfb::CHUNK_HEADER_SIZE + (uint32_t)storage->size();
|
||||
}
|
||||
}
|
||||
|
||||
auto outputConst = storage::FileStorage::create(filename.c_str(), size, nullptr);
|
||||
auto output = std::const_pointer_cast<storage::Storage>(outputConst);
|
||||
auto ptr = output->mutableData();
|
||||
writeUint(ptr, gpu::hfb::MAGIC);
|
||||
writeUint(ptr, gpu::hfb::VERSION);
|
||||
writeUint(ptr, size);
|
||||
writeChunk(ptr, gpu::hfb::CHUNK_TYPE_JSON, json);
|
||||
writeChunk(ptr, gpu::hfb::CHUNK_TYPE_BIN, binaryBuffer);
|
||||
for (const auto& builder : ktxBuilders) {
|
||||
static StoragePointer EMPTY_STORAGE{ std::make_shared<storage::MemoryStorage>(0, nullptr) };
|
||||
auto storage = builder();
|
||||
if (!storage) {
|
||||
storage = EMPTY_STORAGE;
|
||||
}
|
||||
writeChunk(ptr, gpu::hfb::CHUNK_TYPE_KTX, *storage);
|
||||
}
|
||||
assert((ptr - output->data()) == size);
|
||||
}
|
|
@ -12,17 +12,72 @@
|
|||
#include "Forward.h"
|
||||
#include "Format.h"
|
||||
|
||||
#include <shared/Storage.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
using TextureCapturer = std::function<void(const std::string&, const TexturePointer&, uint16 layer)>;
|
||||
using TextureLoader = std::function<void(const std::string&, const TexturePointer&, uint16 layer)>;
|
||||
using TextureCapturer = std::function<storage::StoragePointer(const TexturePointer&)>;
|
||||
//using TextureLoader = std::function<void(const storage::StoragePointer& storage, const TexturePointer&)>;
|
||||
void writeFrame(const std::string& filename, const FramePointer& frame, const TextureCapturer& capturer = nullptr);
|
||||
FramePointer readFrame(const std::string& filename, uint32_t externalTexture, const TextureLoader& loader = nullptr);
|
||||
FramePointer readFrame(const std::string& filename, uint32_t externalTexture);
|
||||
|
||||
using IndexOptimizer = std::function<void(Primitive, uint32_t faceCount, uint32_t indexCount, uint32_t* indices )>;
|
||||
void optimizeFrame(const std::string& filename, const IndexOptimizer& optimizer);
|
||||
namespace hfb {
|
||||
|
||||
using Storage = storage::Storage;
|
||||
using StoragePointer = storage::Pointer;
|
||||
using StorageBuilders = storage::Builders;
|
||||
|
||||
constexpr const char* const EXTENSION{ ".hfb" };
|
||||
constexpr uint32_t HEADER_SIZE{ sizeof(uint32_t) * 3 };
|
||||
constexpr uint32_t CHUNK_HEADER_SIZE = sizeof(uint32_t) * 2;
|
||||
constexpr uint32_t MAGIC{ 0x49464948 };
|
||||
constexpr uint32_t VERSION{ 0x01 };
|
||||
constexpr uint32_t CHUNK_TYPE_JSON{ 0x4E4F534A };
|
||||
constexpr uint32_t CHUNK_TYPE_KTX{ 0x0058544b };
|
||||
constexpr uint32_t CHUNK_TYPE_BIN{ 0x004E4942 };
|
||||
constexpr uint32_t CHUNK_TYPE_PNG{ 0x00474E50 };
|
||||
|
||||
using Buffer = std::vector<uint8_t>;
|
||||
|
||||
struct Header {
|
||||
uint32_t magic{ 0 };
|
||||
uint32_t version{ 0 };
|
||||
uint32_t length{ 0 };
|
||||
};
|
||||
|
||||
struct ChunkHeader {
|
||||
uint32_t length{ 0 };
|
||||
uint32_t type{ 0 };
|
||||
};
|
||||
|
||||
struct Chunk : public ChunkHeader {
|
||||
uint32_t offset{ 0 };
|
||||
|
||||
size_t end() const;
|
||||
};
|
||||
|
||||
using Chunks = std::vector<Chunk>;
|
||||
|
||||
struct Descriptor {
|
||||
using Pointer = std::shared_ptr<Descriptor>;
|
||||
|
||||
Header header;
|
||||
Chunks chunks;
|
||||
StoragePointer storage;
|
||||
|
||||
Descriptor(const StoragePointer& storage);
|
||||
operator bool() const { return header.magic == MAGIC; }
|
||||
StoragePointer getChunk(uint32_t chunk) const;
|
||||
};
|
||||
|
||||
void writeFrame(const std::string& filename,
|
||||
const std::string& json,
|
||||
const Buffer& binaryBuffer,
|
||||
const StorageBuilders& pngBuffers);
|
||||
|
||||
} // namespace hfb
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
|
|
|
@ -11,128 +11,130 @@
|
|||
|
||||
namespace gpu { namespace keys {
|
||||
|
||||
static const char* binary = "binary";
|
||||
static const char* L00 = "L00";
|
||||
static const char* L1m1 = "L1m1";
|
||||
static const char* L10 = "L10";
|
||||
static const char* L11 = "L11";
|
||||
static const char* L2m2 = "L2m2";
|
||||
static const char* L2m1 = "L2m1";
|
||||
static const char* L20 = "L20";
|
||||
static const char* L21 = "L21";
|
||||
static const char* L22 = "L22";
|
||||
|
||||
static const char* eyeProjections = "eyeProjections";
|
||||
static const char* eyeViews = "eyeViews";
|
||||
static const char* alphaToCoverageEnable = "alphaToCoverageEnable";
|
||||
static const char* antialisedLineEnable = "antialisedLineEnable";
|
||||
static const char* attributes = "attributes";
|
||||
static const char* batches = "batches";
|
||||
static const char* blendFunction = "blendFunction";
|
||||
static const char* borderColor = "borderColor";
|
||||
static const char* bufferMask = "bufferMask";
|
||||
static const char* buffers = "buffers";
|
||||
static const char* capturedTextures = "capturedTextures";
|
||||
static const char* channel = "channel";
|
||||
static const char* colorAttachments = "colorAttachments";
|
||||
static const char* colorWriteMask = "colorWriteMask";
|
||||
static const char* commands = "commands";
|
||||
static const char* comparisonFunction = "comparisonFunction";
|
||||
static const char* cullMode = "cullMode";
|
||||
static const char* data = "data";
|
||||
static const char* depth = "depth";
|
||||
static const char* depthBias = "depthBias";
|
||||
static const char* depthBiasSlopeScale = "depthBiasSlopeScale";
|
||||
static const char* depthClampEnable = "depthClampEnable";
|
||||
static const char* depthStencilAttachment = "depthStencilAttachment";
|
||||
static const char* depthTest = "depthTest";
|
||||
static const char* drawCallInfos = "drawCallInfos";
|
||||
static const char* drawcallUniform = "drawcallUniform";
|
||||
static const char* drawcallUniformReset = "drawcallUniformReset";
|
||||
static const char* element = "element";
|
||||
static const char* fillMode = "fillMode";
|
||||
static const char* filter = "filter";
|
||||
static const char* formats = "formats";
|
||||
static const char* frameIndex = "frameIndex";
|
||||
static const char* framebuffer = "framebuffer";
|
||||
static const char* framebuffers = "framebuffers";
|
||||
static const char* frequency = "frequency";
|
||||
static const char* frontFaceClockwise = "frontFaceClockwise";
|
||||
static const char* height = "height";
|
||||
static const char* id = "id";
|
||||
static const char* ktxFile = "ktxFile";
|
||||
static const char* layers = "layers";
|
||||
static const char* maxAnisotropy = "maxAnisotropy";
|
||||
static const char* maxMip = "maxMip";
|
||||
static const char* minMip = "minMip";
|
||||
static const char* mipOffset = "mipOffset";
|
||||
static const char* mips = "mips";
|
||||
static const char* multisampleEnable = "multisampleEnable";
|
||||
static const char* name = "name";
|
||||
static const char* namedData = "namedData";
|
||||
static const char* names = "names";
|
||||
static const char* objects = "objects";
|
||||
static const char* offset = "offset";
|
||||
static const char* pipelines = "pipelines";
|
||||
static const char* pose = "pose";
|
||||
static const char* profileRanges = "profileRanges";
|
||||
static const char* program = "program";
|
||||
static const char* programs = "programs";
|
||||
static const char* projectionJitter = "projectionJitter";
|
||||
static const char* queries = "queries";
|
||||
static const char* sampleCount = "sampleCount";
|
||||
static const char* sampleMask = "sampleMask";
|
||||
static const char* sampler = "sampler";
|
||||
static const char* samples = "samples";
|
||||
static const char* scissorEnable = "scissorEnable";
|
||||
static const char* shaders = "shaders";
|
||||
static const char* size = "size";
|
||||
static const char* skybox = "skybox";
|
||||
static const char* slot = "slot";
|
||||
static const char* source = "source";
|
||||
static const char* state = "state";
|
||||
static const char* stencilActivation = "stencilActivation";
|
||||
static const char* stencilTestBack = "stencilTestBack";
|
||||
static const char* stencilTestFront = "stencilTestFront";
|
||||
static const char* stereo = "stereo";
|
||||
static const char* subresource = "subresource";
|
||||
static const char* swapchains = "swapchains";
|
||||
static const char* texelFormat = "texelFormat";
|
||||
static const char* texture = "texture";
|
||||
static const char* textureTables = "textureTables";
|
||||
static const char* textures = "textures";
|
||||
static const char* transforms = "transforms";
|
||||
static const char* type = "type";
|
||||
static const char* usageType = "usageType";
|
||||
static const char* view = "view";
|
||||
static const char* width = "width";
|
||||
static const char* wrapModeU = "wrapModeU";
|
||||
static const char* wrapModeV = "wrapModeV";
|
||||
static const char* wrapModeW = "wrapModeW";
|
||||
constexpr const char* binary = "binary";
|
||||
constexpr const char* L00 = "L00";
|
||||
constexpr const char* L1m1 = "L1m1";
|
||||
constexpr const char* L10 = "L10";
|
||||
constexpr const char* L11 = "L11";
|
||||
constexpr const char* L2m2 = "L2m2";
|
||||
constexpr const char* L2m1 = "L2m1";
|
||||
constexpr const char* L20 = "L20";
|
||||
constexpr const char* L21 = "L21";
|
||||
constexpr const char* L22 = "L22";
|
||||
|
||||
constexpr const char* eyeProjections = "eyeProjections";
|
||||
constexpr const char* eyeViews = "eyeViews";
|
||||
constexpr const char* alphaToCoverageEnable = "alphaToCoverageEnable";
|
||||
constexpr const char* antialisedLineEnable = "antialisedLineEnable";
|
||||
constexpr const char* attributes = "attributes";
|
||||
constexpr const char* batches = "batches";
|
||||
constexpr const char* blendFunction = "blendFunction";
|
||||
constexpr const char* borderColor = "borderColor";
|
||||
constexpr const char* bufferMask = "bufferMask";
|
||||
constexpr const char* buffers = "buffers";
|
||||
constexpr const char* capturedTextures = "capturedTextures";
|
||||
constexpr const char* channel = "channel";
|
||||
constexpr const char* chunk = "chunk";
|
||||
constexpr const char* colorAttachments = "colorAttachments";
|
||||
constexpr const char* colorWriteMask = "colorWriteMask";
|
||||
constexpr const char* commands = "commands";
|
||||
constexpr const char* comparisonFunction = "comparisonFunction";
|
||||
constexpr const char* cullMode = "cullMode";
|
||||
constexpr const char* data = "data";
|
||||
constexpr const char* depth = "depth";
|
||||
constexpr const char* depthBias = "depthBias";
|
||||
constexpr const char* depthBiasSlopeScale = "depthBiasSlopeScale";
|
||||
constexpr const char* depthClampEnable = "depthClampEnable";
|
||||
constexpr const char* depthStencilAttachment = "depthStencilAttachment";
|
||||
constexpr const char* depthTest = "depthTest";
|
||||
constexpr const char* drawCallInfos = "drawCallInfos";
|
||||
constexpr const char* drawcallUniform = "drawcallUniform";
|
||||
constexpr const char* drawcallUniformReset = "drawcallUniformReset";
|
||||
constexpr const char* element = "element";
|
||||
constexpr const char* fillMode = "fillMode";
|
||||
constexpr const char* filter = "filter";
|
||||
constexpr const char* formats = "formats";
|
||||
constexpr const char* frameIndex = "frameIndex";
|
||||
constexpr const char* framebuffer = "framebuffer";
|
||||
constexpr const char* framebuffers = "framebuffers";
|
||||
constexpr const char* frequency = "frequency";
|
||||
constexpr const char* frontFaceClockwise = "frontFaceClockwise";
|
||||
constexpr const char* height = "height";
|
||||
constexpr const char* id = "id";
|
||||
constexpr const char* ktxFile = "ktxFile";
|
||||
constexpr const char* layers = "layers";
|
||||
constexpr const char* maxAnisotropy = "maxAnisotropy";
|
||||
constexpr const char* maxMip = "maxMip";
|
||||
constexpr const char* minMip = "minMip";
|
||||
constexpr const char* mipOffset = "mipOffset";
|
||||
constexpr const char* mips = "mips";
|
||||
constexpr const char* multisampleEnable = "multisampleEnable";
|
||||
constexpr const char* name = "name";
|
||||
constexpr const char* namedData = "namedData";
|
||||
constexpr const char* names = "names";
|
||||
constexpr const char* objects = "objects";
|
||||
constexpr const char* offset = "offset";
|
||||
constexpr const char* pipelines = "pipelines";
|
||||
constexpr const char* pose = "pose";
|
||||
constexpr const char* profileRanges = "profileRanges";
|
||||
constexpr const char* program = "program";
|
||||
constexpr const char* programs = "programs";
|
||||
constexpr const char* projectionJitter = "projectionJitter";
|
||||
constexpr const char* queries = "queries";
|
||||
constexpr const char* sampleCount = "sampleCount";
|
||||
constexpr const char* sampleMask = "sampleMask";
|
||||
constexpr const char* sampler = "sampler";
|
||||
constexpr const char* samples = "samples";
|
||||
constexpr const char* scissorEnable = "scissorEnable";
|
||||
constexpr const char* shaders = "shaders";
|
||||
constexpr const char* size = "size";
|
||||
constexpr const char* skybox = "skybox";
|
||||
constexpr const char* slot = "slot";
|
||||
constexpr const char* source = "source";
|
||||
constexpr const char* state = "state";
|
||||
constexpr const char* stencilActivation = "stencilActivation";
|
||||
constexpr const char* stencilTestBack = "stencilTestBack";
|
||||
constexpr const char* stencilTestFront = "stencilTestFront";
|
||||
constexpr const char* stereo = "stereo";
|
||||
constexpr const char* subresource = "subresource";
|
||||
constexpr const char* swapchains = "swapchains";
|
||||
constexpr const char* texelFormat = "texelFormat";
|
||||
constexpr const char* texture = "texture";
|
||||
constexpr const char* textureTables = "textureTables";
|
||||
constexpr const char* textures = "textures";
|
||||
constexpr const char* transforms = "transforms";
|
||||
constexpr const char* type = "type";
|
||||
constexpr const char* usageType = "usageType";
|
||||
constexpr const char* view = "view";
|
||||
constexpr const char* width = "width";
|
||||
constexpr const char* wrapModeU = "wrapModeU";
|
||||
constexpr const char* wrapModeV = "wrapModeV";
|
||||
constexpr const char* wrapModeW = "wrapModeW";
|
||||
|
||||
|
||||
static const char* backWriteMask = "backWriteMask";
|
||||
static const char* frontWriteMask = "frontWriteMask";
|
||||
static const char* reference = "reference";
|
||||
static const char* readMask = "readMask";
|
||||
static const char* failOp = "failOp";
|
||||
static const char* depthFailOp = "depthFailOp";
|
||||
static const char* passOp = "passOp";
|
||||
static const char* enabled = "enabled";
|
||||
static const char* blend = "blend";
|
||||
static const char* flags = "flags";
|
||||
static const char* writeMask = "writeMask";
|
||||
static const char* function = "function";
|
||||
static const char* sourceColor = "sourceColor";
|
||||
static const char* sourceAlpha = "sourceAlpha";
|
||||
static const char* destColor = "destColor";
|
||||
static const char* destAlpha = "destAlpha";
|
||||
static const char* opColor = "opColor";
|
||||
static const char* opAlpha = "opAlpha";
|
||||
static const char* enable = "enable";
|
||||
static const char* contextDisable = "contextDisable";
|
||||
constexpr const char* backWriteMask = "backWriteMask";
|
||||
constexpr const char* frontWriteMask = "frontWriteMask";
|
||||
constexpr const char* reference = "reference";
|
||||
constexpr const char* readMask = "readMask";
|
||||
constexpr const char* failOp = "failOp";
|
||||
constexpr const char* depthFailOp = "depthFailOp";
|
||||
constexpr const char* passOp = "passOp";
|
||||
constexpr const char* enabled = "enabled";
|
||||
constexpr const char* blend = "blend";
|
||||
constexpr const char* flags = "flags";
|
||||
constexpr const char* writeMask = "writeMask";
|
||||
constexpr const char* function = "function";
|
||||
constexpr const char* sourceColor = "sourceColor";
|
||||
constexpr const char* sourceAlpha = "sourceAlpha";
|
||||
constexpr const char* destColor = "destColor";
|
||||
constexpr const char* destAlpha = "destAlpha";
|
||||
constexpr const char* opColor = "opColor";
|
||||
constexpr const char* opAlpha = "opAlpha";
|
||||
constexpr const char* enable = "enable";
|
||||
constexpr const char* contextDisable = "contextDisable";
|
||||
|
||||
static const char* COMMAND_NAMES[] = {
|
||||
constexpr const char* COMMAND_NAMES[] = {
|
||||
"draw",
|
||||
"drawIndexed",
|
||||
"drawInstanced",
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <shared/FileUtils.h>
|
||||
#include <ktx/KTX.h>
|
||||
#include "Frame.h"
|
||||
#include "Batch.h"
|
||||
|
@ -22,24 +20,18 @@
|
|||
|
||||
namespace gpu {
|
||||
using json = nlohmann::json;
|
||||
using StoragePointer = storage::StoragePointer;
|
||||
using FileStorage = storage::FileStorage;
|
||||
|
||||
class Deserializer {
|
||||
public:
|
||||
static std::string getBaseName(const std::string& filename) {
|
||||
static const std::string ext{ ".json" };
|
||||
if (std::string::npos != filename.rfind(ext)) {
|
||||
return filename.substr(0, filename.size() - ext.size());
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
static std::string getBaseDir(const std::string& filename) {
|
||||
std::string result;
|
||||
if (0 == filename.find("assets:")) {
|
||||
auto lastSlash = filename.rfind('/');
|
||||
result = filename.substr(0, lastSlash + 1);
|
||||
} else {
|
||||
result = QFileInfo(filename.c_str()).absoluteDir().canonicalPath().toStdString();
|
||||
result = FileUtils::getParentPath(filename.c_str()).toStdString();
|
||||
if (*result.rbegin() != '/') {
|
||||
result += '/';
|
||||
}
|
||||
|
@ -47,15 +39,17 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
Deserializer(const std::string& filename, uint32_t externalTexture, const TextureLoader& loader) :
|
||||
basename(getBaseName(filename)), basedir(getBaseDir(filename)), externalTexture(externalTexture), textureLoader(loader) {
|
||||
Deserializer(const std::string& filename_, uint32_t externalTexture = 0) :
|
||||
filename(filename_), basedir(getBaseDir(filename_)), mappedFile(std::make_shared<FileStorage>(filename.c_str())),
|
||||
externalTexture(externalTexture) {
|
||||
descriptor = std::make_shared<hfb::Descriptor>(mappedFile);
|
||||
}
|
||||
|
||||
const std::string basename;
|
||||
const std::string filename;
|
||||
const std::string basedir;
|
||||
std::string binaryFile;
|
||||
const StoragePointer mappedFile;
|
||||
const uint32_t externalTexture;
|
||||
TextureLoader textureLoader;
|
||||
hfb::Descriptor::Pointer descriptor;
|
||||
std::vector<ShaderPointer> shaders;
|
||||
std::vector<ShaderPointer> programs;
|
||||
std::vector<TexturePointer> textures;
|
||||
|
@ -69,10 +63,13 @@ public:
|
|||
std::vector<QueryPointer> queries;
|
||||
json frameNode;
|
||||
FramePointer readFrame();
|
||||
void optimizeFrame(const IndexOptimizer& optimizer);
|
||||
|
||||
FramePointer deserializeFrame();
|
||||
|
||||
std::string getStringChunk(size_t chunkIndex) {
|
||||
auto storage = descriptor->getChunk((uint32_t)chunkIndex);
|
||||
return std::string{ (const char*)storage->data(), storage->size() };
|
||||
}
|
||||
|
||||
void readBuffers(const json& node);
|
||||
|
||||
|
@ -148,12 +145,11 @@ public:
|
|||
}
|
||||
|
||||
template <typename T, typename TT = T>
|
||||
static bool readBatchCacheTransformed(typename Batch::Cache<T>::Vector& dest,
|
||||
const json& node,
|
||||
const std::string& name,
|
||||
std::function<TT(const json&)> f = [](const json& node) -> TT {
|
||||
return node.get<TT>();
|
||||
}) {
|
||||
static bool readBatchCacheTransformed(
|
||||
typename Batch::Cache<T>::Vector& dest,
|
||||
const json& node,
|
||||
const std::string& name,
|
||||
std::function<TT(const json&)> f = [](const json& node) -> TT { return node.get<TT>(); }) {
|
||||
if (node.count(name)) {
|
||||
const auto& arrayNode = node[name];
|
||||
for (const auto& entry : arrayNode) {
|
||||
|
@ -230,12 +226,8 @@ public:
|
|||
static void readCommand(const json& node, Batch& batch);
|
||||
};
|
||||
|
||||
FramePointer readFrame(const std::string& filename, uint32_t externalTexture, const TextureLoader& loader) {
|
||||
return Deserializer(filename, externalTexture, loader).readFrame();
|
||||
}
|
||||
|
||||
void optimizeFrame(const std::string& filename, const IndexOptimizer& optimizer) {
|
||||
return Deserializer(filename, 0, {}).optimizeFrame(optimizer);
|
||||
FramePointer readFrame(const std::string& filename, uint32_t externalTexture) {
|
||||
return Deserializer(filename, externalTexture).readFrame();
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
|
@ -243,9 +235,9 @@ void optimizeFrame(const std::string& filename, const IndexOptimizer& optimizer)
|
|||
using namespace gpu;
|
||||
|
||||
void Deserializer::readBuffers(const json& buffersNode) {
|
||||
storage::FileStorage mappedFile(binaryFile.c_str());
|
||||
const auto mappedSize = mappedFile.size();
|
||||
const auto* mapped = mappedFile.data();
|
||||
const auto& binaryChunk = descriptor->chunks[1];
|
||||
const auto* mapped = mappedFile->data() + binaryChunk.offset;
|
||||
const auto mappedSize = binaryChunk.length;
|
||||
size_t bufferCount = buffersNode.size();
|
||||
buffers.reserve(buffersNode.size());
|
||||
size_t offset = 0;
|
||||
|
@ -311,6 +303,8 @@ Sampler Deserializer::readSampler(const json& node) {
|
|||
return result;
|
||||
}
|
||||
|
||||
constexpr uint32_t INVALID_CHUNK_INDEX{ (uint32_t)-1 };
|
||||
|
||||
TexturePointer Deserializer::readTexture(const json& node, uint32_t external) {
|
||||
if (node.is_null()) {
|
||||
return nullptr;
|
||||
|
@ -319,8 +313,17 @@ TexturePointer Deserializer::readTexture(const json& node, uint32_t external) {
|
|||
std::string source;
|
||||
readOptional(source, node, keys::source);
|
||||
|
||||
uint32_t chunkIndex = INVALID_CHUNK_INDEX;
|
||||
readOptional(chunkIndex, node, keys::chunk);
|
||||
|
||||
std::string ktxFile;
|
||||
readOptional(ktxFile, node, keys::ktxFile);
|
||||
if (!ktxFile.empty()) {
|
||||
if (!FileUtils::exists(ktxFile.c_str())) {
|
||||
qDebug() << "Warning" << ktxFile.c_str() << " not found, ignoring";
|
||||
ktxFile = {};
|
||||
}
|
||||
}
|
||||
Element ktxTexelFormat, ktxMipFormat;
|
||||
if (!ktxFile.empty()) {
|
||||
// If we get a texture that starts with ":" we need to re-route it to the resources directory
|
||||
|
@ -330,8 +333,8 @@ TexturePointer Deserializer::readTexture(const json& node, uint32_t external) {
|
|||
frameReaderPath.replace("libraries/gpu/src/gpu/framereader.cpp", "interface/resources", Qt::CaseInsensitive);
|
||||
ktxFile.replace(0, 1, frameReaderPath.toStdString());
|
||||
}
|
||||
if (QFileInfo(ktxFile.c_str()).isRelative()) {
|
||||
ktxFile = basedir + ktxFile;
|
||||
if (FileUtils::isRelative(ktxFile.c_str())) {
|
||||
ktxFile = basedir + "/" + ktxFile;
|
||||
}
|
||||
ktx::StoragePointer ktxStorage{ new storage::FileStorage(ktxFile.c_str()) };
|
||||
auto ktxObject = ktx::KTX::create(ktxStorage);
|
||||
|
@ -364,12 +367,14 @@ TexturePointer Deserializer::readTexture(const json& node, uint32_t external) {
|
|||
auto& texture = *result;
|
||||
readOptional(texture._source, node, keys::source);
|
||||
|
||||
if (!ktxFile.empty()) {
|
||||
if (QFileInfo(ktxFile.c_str()).isRelative()) {
|
||||
ktxFile = basedir + "/" + ktxFile;
|
||||
}
|
||||
|
||||
if (chunkIndex != INVALID_CHUNK_INDEX) {
|
||||
auto ktxChunk = descriptor->getChunk(chunkIndex);
|
||||
texture.setKtxBacking(ktxChunk);
|
||||
} else if (!ktxFile.empty()) {
|
||||
texture.setSource(ktxFile);
|
||||
texture.setKtxBacking(ktxFile);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -405,11 +410,11 @@ ShaderPointer Deserializer::readShader(const json& node) {
|
|||
// FIXME support procedural shaders
|
||||
Shader::Type type = node[keys::type];
|
||||
std::string name = node[keys::name];
|
||||
// Using the serialized ID is bad, because it's generated at
|
||||
// cmake time, and can change across platforms or when
|
||||
// Using the serialized ID is bad, because it's generated at
|
||||
// cmake time, and can change across platforms or when
|
||||
// shaders are added or removed
|
||||
// uint32_t id = node[keys::id];
|
||||
|
||||
|
||||
uint32_t id = shadersIdsByName[name];
|
||||
ShaderPointer result;
|
||||
switch (type) {
|
||||
|
@ -555,11 +560,15 @@ StatePointer readState(const json& node) {
|
|||
|
||||
State::Data data;
|
||||
Deserializer::readOptionalTransformed<State::Flags>(data.flags, node, keys::flags, &readStateFlags);
|
||||
Deserializer::readOptionalTransformed<State::BlendFunction>(data.blendFunction, node, keys::blendFunction, &readBlendFunction);
|
||||
Deserializer::readOptionalTransformed<State::BlendFunction>(data.blendFunction, node, keys::blendFunction,
|
||||
&readBlendFunction);
|
||||
Deserializer::readOptionalTransformed<State::DepthTest>(data.depthTest, node, keys::depthTest, &readDepthTest);
|
||||
Deserializer::readOptionalTransformed<State::StencilActivation>(data.stencilActivation, node, keys::stencilActivation, &readStencilActivation);
|
||||
Deserializer::readOptionalTransformed<State::StencilTest>(data.stencilTestFront, node, keys::stencilTestFront, &readStencilTest);
|
||||
Deserializer::readOptionalTransformed<State::StencilTest>(data.stencilTestBack, node, keys::stencilTestBack, &readStencilTest);
|
||||
Deserializer::readOptionalTransformed<State::StencilActivation>(data.stencilActivation, node, keys::stencilActivation,
|
||||
&readStencilActivation);
|
||||
Deserializer::readOptionalTransformed<State::StencilTest>(data.stencilTestFront, node, keys::stencilTestFront,
|
||||
&readStencilTest);
|
||||
Deserializer::readOptionalTransformed<State::StencilTest>(data.stencilTestBack, node, keys::stencilTestBack,
|
||||
&readStencilTest);
|
||||
Deserializer::readOptional(data.colorWriteMask, node, keys::colorWriteMask);
|
||||
Deserializer::readOptional(data.cullMode, node, keys::cullMode);
|
||||
Deserializer::readOptional(data.depthBias, node, keys::depthBias);
|
||||
|
@ -799,25 +808,15 @@ StereoState readStereoState(const json& node) {
|
|||
|
||||
|
||||
FramePointer Deserializer::deserializeFrame() {
|
||||
{
|
||||
std::string filename{ basename + ".json" };
|
||||
storage::FileStorage mappedFile(filename.c_str());
|
||||
frameNode = json::parse(std::string((const char*)mappedFile.data(), mappedFile.size()));
|
||||
if (!descriptor.operator bool()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
frameNode = json::parse(getStringChunk(0));
|
||||
|
||||
FramePointer result = std::make_shared<Frame>();
|
||||
auto& frame = *result;
|
||||
|
||||
if (frameNode[keys::binary].is_string()) {
|
||||
binaryFile = frameNode[keys::binary];
|
||||
if (QFileInfo(binaryFile.c_str()).isRelative()) {
|
||||
binaryFile = basedir + "/" + binaryFile;
|
||||
}
|
||||
} else {
|
||||
binaryFile = basename + ".bin";
|
||||
}
|
||||
|
||||
|
||||
if (frameNode.count(keys::buffers)) {
|
||||
readBuffers(frameNode[keys::buffers]);
|
||||
}
|
||||
|
@ -830,19 +829,7 @@ FramePointer Deserializer::deserializeFrame() {
|
|||
|
||||
formats = readArray<Stream::FormatPointer>(frameNode, keys::formats, [](const json& node) { return readFormat(node); });
|
||||
|
||||
auto textureReader = [this](const json& node) { return readTexture(node, externalTexture); };
|
||||
textures = readArray<TexturePointer>(frameNode, keys::textures, textureReader);
|
||||
if (textureLoader) {
|
||||
std::vector<uint32_t> capturedTextures = readNumericVector<uint32_t>(frameNode[keys::capturedTextures]);
|
||||
for (const auto& index : capturedTextures) {
|
||||
const auto& texturePointer = textures[index];
|
||||
uint16 layers = std::max<uint16>(texturePointer->getNumSlices(), 1);
|
||||
for (uint16 layer = 0; layer < layers; ++layer) {
|
||||
std::string filename = basename + "." + std::to_string(index) + "." + std::to_string(layer) + ".png";
|
||||
textureLoader(filename, texturePointer, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
textures = readArray<TexturePointer>(frameNode, keys::textures, [this](const json& node) { return readTexture(node, externalTexture); });
|
||||
|
||||
// Must come after textures
|
||||
auto textureTableReader = [this](const json& node) { return readTextureTable(node); };
|
||||
|
@ -868,87 +855,22 @@ FramePointer Deserializer::deserializeFrame() {
|
|||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < textures.size(); ++i) {
|
||||
const auto& texturePtr = textures[i];
|
||||
if (!texturePtr) {
|
||||
continue;
|
||||
}
|
||||
const auto& texture = *texturePtr;
|
||||
if (texture.getUsageType() == gpu::TextureUsageType::RESOURCE && texture.source().empty()) {
|
||||
qDebug() << "Empty source ";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FramePointer Deserializer::readFrame() {
|
||||
auto result = deserializeFrame();
|
||||
result->finish();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Deserializer::optimizeFrame(const IndexOptimizer& optimizer) {
|
||||
auto result = deserializeFrame();
|
||||
auto& frame = *result;
|
||||
|
||||
|
||||
// optimize the index buffers?
|
||||
struct CurrentIndexBuffer {
|
||||
Offset offset{ 0 };
|
||||
BufferPointer buffer;
|
||||
Type type{ gpu::Type::INT32 };
|
||||
Primitive primitve{ Primitive::TRIANGLES };
|
||||
uint32_t numIndices{ 0 };
|
||||
uint32_t startIndex{ 0 };
|
||||
};
|
||||
|
||||
std::vector<CurrentIndexBuffer> captured;
|
||||
for (auto& batch : frame.batches) {
|
||||
|
||||
CurrentIndexBuffer currentIndexBuffer;
|
||||
batch->forEachCommand([&](Batch::Command cmd, const Batch::Param* params){
|
||||
switch(cmd) {
|
||||
case Batch::Command::COMMAND_setIndexBuffer:
|
||||
currentIndexBuffer.offset = params[0]._size;
|
||||
currentIndexBuffer.buffer = batch->_buffers.get(params[1]._int);
|
||||
currentIndexBuffer.type = (Type)params[2]._int;
|
||||
break;
|
||||
|
||||
case Batch::Command::COMMAND_drawIndexed:
|
||||
currentIndexBuffer.startIndex = params[0]._int;
|
||||
currentIndexBuffer.numIndices = params[1]._int;
|
||||
currentIndexBuffer.primitve = (Primitive)params[2]._int;
|
||||
captured.emplace_back(currentIndexBuffer);
|
||||
break;
|
||||
|
||||
case Batch::Command::COMMAND_drawIndexedInstanced:
|
||||
currentIndexBuffer.startIndex = params[1]._int;
|
||||
currentIndexBuffer.numIndices = params[2]._int;
|
||||
currentIndexBuffer.primitve = (Primitive)params[3]._int;
|
||||
captured.emplace_back(currentIndexBuffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
std::string optimizedBinaryFile = basename + "_optimized.bin";
|
||||
QFile(binaryFile.c_str()).copy(optimizedBinaryFile.c_str());
|
||||
{
|
||||
storage::FileStorage mappedFile(optimizedBinaryFile.c_str());
|
||||
std::set<BufferPointer> uniqueBuffers;
|
||||
for (const auto& capturedIndexData : captured) {
|
||||
if (uniqueBuffers.count(capturedIndexData.buffer)) {
|
||||
continue;
|
||||
}
|
||||
uniqueBuffers.insert(capturedIndexData.buffer);
|
||||
auto bufferOffset = bufferOffsets[capturedIndexData.buffer];
|
||||
auto& buffer = *capturedIndexData.buffer;
|
||||
const auto& count = capturedIndexData.numIndices;
|
||||
auto indices = (uint32_t*)buffer.editData();
|
||||
optimizer(capturedIndexData.primitve, count / 3, count, indices);
|
||||
memcpy(mappedFile.mutableData() + bufferOffset, indices, sizeof(uint32_t) * count);
|
||||
}
|
||||
}
|
||||
frameNode[keys::binary] = optimizedBinaryFile;
|
||||
{
|
||||
std::string frameJson = frameNode.dump();
|
||||
std::string filename = basename + "_optimized.json";
|
||||
storage::FileStorage::create(filename.c_str(), frameJson.size(), (const uint8_t*)frameJson.data());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ using json = nlohmann::json;
|
|||
|
||||
class Serializer {
|
||||
public:
|
||||
const std::string basename;
|
||||
const std::string filename;
|
||||
const TextureCapturer textureCapturer;
|
||||
std::unordered_map<ShaderPointer, uint32_t> shaderMap;
|
||||
std::unordered_map<ShaderPointer, uint32_t> programMap;
|
||||
|
@ -32,8 +32,11 @@ public:
|
|||
std::unordered_map<FramebufferPointer, uint32_t> framebufferMap;
|
||||
std::unordered_map<SwapChainPointer, uint32_t> swapchainMap;
|
||||
std::unordered_map<QueryPointer, uint32_t> queryMap;
|
||||
std::unordered_set<TexturePointer> captureTextures;
|
||||
hfb::Buffer binaryBuffer;
|
||||
hfb::StorageBuilders ktxBuilders;
|
||||
|
||||
Serializer(const std::string& basename, const TextureCapturer& capturer) : basename(basename), textureCapturer(capturer) {}
|
||||
Serializer(const std::string& basename, const TextureCapturer& capturer) : filename(basename + hfb::EXTENSION), textureCapturer(capturer) {}
|
||||
|
||||
template <typename T>
|
||||
static uint32_t getGlobalIndex(const T& value, std::unordered_map<T, uint32_t>& map) {
|
||||
|
@ -129,7 +132,7 @@ public:
|
|||
json writeProgram(const ShaderPointer& program);
|
||||
json writeNamedBatchData(const Batch::NamedBatchData& namedData);
|
||||
|
||||
json writeCapturableTextures(const Frame& frame);
|
||||
void findCapturableTextures(const Frame& frame);
|
||||
void writeBinaryBlob();
|
||||
static std::string toBase64(const std::vector<uint8_t>& v);
|
||||
static json writeIrradiance(const SHPointer& irradiance);
|
||||
|
@ -146,7 +149,7 @@ public:
|
|||
static json writeTransform(const Transform& t) { return writeMat4(t.getMatrix()); }
|
||||
static json writeCommand(size_t index, const Batch& batch);
|
||||
static json writeSampler(const Sampler& sampler);
|
||||
static json writeTexture(const TexturePointer& texture);
|
||||
json writeTexture(const TexturePointer& texture);
|
||||
static json writeFormat(const Stream::FormatPointer& format);
|
||||
static json writeQuery(const QueryPointer& query);
|
||||
static json writeShader(const ShaderPointer& shader);
|
||||
|
@ -389,9 +392,17 @@ json Serializer::writeTexture(const TexturePointer& texturePointer) {
|
|||
const auto* storage = texture._storage.get();
|
||||
const auto* ktxStorage = dynamic_cast<const Texture::KtxStorage*>(storage);
|
||||
if (ktxStorage) {
|
||||
result[keys::ktxFile] = ktxStorage->_filename;
|
||||
} else {
|
||||
// TODO serialize the backing storage
|
||||
result[keys::chunk] = 2 + ktxBuilders.size();
|
||||
auto filename = ktxStorage->_filename;
|
||||
ktxBuilders.push_back([=] {
|
||||
return std::make_shared<storage::FileStorage>(filename.c_str());
|
||||
});
|
||||
} else if (textureCapturer && captureTextures.count(texturePointer) != 0) {
|
||||
result[keys::chunk] = 2 + ktxBuilders.size();
|
||||
auto storage = textureCapturer(texturePointer);
|
||||
ktxBuilders.push_back([=] {
|
||||
return storage;
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -673,14 +684,8 @@ json Serializer::writeQuery(const QueryPointer& queryPointer) {
|
|||
return result;
|
||||
}
|
||||
|
||||
json Serializer::writeCapturableTextures(const Frame& frame) {
|
||||
if (!textureCapturer) {
|
||||
return json::array();
|
||||
}
|
||||
|
||||
void Serializer::findCapturableTextures(const Frame& frame) {
|
||||
std::unordered_set<TexturePointer> writtenRenderbuffers;
|
||||
std::unordered_set<TexturePointer> captureTextures;
|
||||
|
||||
auto maybeCaptureTexture = [&](const TexturePointer& texture) {
|
||||
// Not a valid texture
|
||||
if (!texture) {
|
||||
|
@ -755,20 +760,6 @@ json Serializer::writeCapturableTextures(const Frame& frame) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
json result = json::array();
|
||||
for (const auto& texture : captureTextures) {
|
||||
if (textureCapturer) {
|
||||
auto index = textureMap[texture];
|
||||
auto layers = std::max<uint16>(texture->getNumSlices(), 1);
|
||||
for (uint16 layer = 0; layer < layers; ++layer) {
|
||||
std::string textureFilename = basename + "." + std::to_string(index) + "." + std::to_string(layer) + ".png";
|
||||
textureCapturer(textureFilename, texture, layer);
|
||||
}
|
||||
result.push_back(index);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Serializer::writeFrame(const Frame& frame) {
|
||||
|
@ -780,7 +771,7 @@ void Serializer::writeFrame(const Frame& frame) {
|
|||
}
|
||||
|
||||
frameNode[keys::stereo] = writeStereoState(frame.stereoState);
|
||||
frameNode[keys::capturedTextures] = writeCapturableTextures(frame);
|
||||
findCapturableTextures(frame);
|
||||
frameNode[keys::frameIndex] = frame.frameIndex;
|
||||
frameNode[keys::view] = writeMat4(frame.view);
|
||||
frameNode[keys::pose] = writeMat4(frame.pose);
|
||||
|
@ -797,35 +788,21 @@ void Serializer::writeFrame(const Frame& frame) {
|
|||
|
||||
// Serialize textures and buffers last, since the maps they use can be populated by some of the above code
|
||||
// Serialize textures
|
||||
serializeMap(frameNode, keys::textures, textureMap, writeTexture);
|
||||
serializeMap(frameNode, keys::textures, textureMap, std::bind(&Serializer::writeTexture, this, _1));
|
||||
// Serialize buffers
|
||||
serializeMap(frameNode, keys::buffers, bufferMap, writeBuffer);
|
||||
|
||||
{
|
||||
std::string frameJson = frameNode.dump();
|
||||
std::string filename = basename + ".json";
|
||||
storage::FileStorage::create(filename.c_str(), frameJson.size(), (const uint8_t*)frameJson.data());
|
||||
}
|
||||
|
||||
writeBinaryBlob();
|
||||
frameNode[keys::binary] = basename + ".bin";
|
||||
|
||||
hfb::writeFrame(filename, frameNode.dump(), binaryBuffer, ktxBuilders);
|
||||
}
|
||||
|
||||
void Serializer::writeBinaryBlob() {
|
||||
const auto buffers = mapToVector(bufferMap);
|
||||
auto accumulator = [](size_t total, const BufferPointer& buffer) { return total + (buffer ? buffer->getSize() : 0); };
|
||||
size_t totalSize = std::accumulate(buffers.begin(), buffers.end(), (size_t)0, accumulator);
|
||||
|
||||
const auto blobFilename = basename + ".bin";
|
||||
QFile file(blobFilename.c_str());
|
||||
if (!file.open(QFile::ReadWrite | QIODevice::Truncate)) {
|
||||
throw std::runtime_error("Unable to open file for writing");
|
||||
}
|
||||
if (!file.resize(totalSize)) {
|
||||
throw std::runtime_error("Unable to resize file");
|
||||
}
|
||||
|
||||
auto mapped = file.map(0, totalSize);
|
||||
binaryBuffer.resize(totalSize);
|
||||
auto mapped = binaryBuffer.data();
|
||||
size_t offset = 0;
|
||||
|
||||
for (const auto& bufferPointer : buffers) {
|
||||
|
@ -838,7 +815,4 @@ void Serializer::writeBinaryBlob() {
|
|||
memcpy(mapped + offset, bufferData, bufferSize);
|
||||
offset += bufferSize;
|
||||
}
|
||||
if (!file.unmap(mapped)) {
|
||||
throw std::runtime_error("Unable to unmap file");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,6 +343,7 @@ public:
|
|||
|
||||
class KtxStorage : public Storage {
|
||||
public:
|
||||
KtxStorage(const storage::StoragePointer& storage);
|
||||
KtxStorage(const std::string& filename);
|
||||
KtxStorage(const cache::FilePointer& file);
|
||||
PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override;
|
||||
|
@ -366,6 +367,7 @@ public:
|
|||
static std::vector<std::pair<std::shared_ptr<storage::FileStorage>, std::shared_ptr<std::mutex>>> _cachedKtxFiles;
|
||||
static std::mutex _cachedKtxFilesMutex;
|
||||
|
||||
storage::StoragePointer _storage;
|
||||
std::string _filename;
|
||||
cache::FilePointer _cacheEntry;
|
||||
std::atomic<uint8_t> _minMipLevelAvailable;
|
||||
|
@ -543,6 +545,7 @@ public:
|
|||
Size getStoredSize() const;
|
||||
|
||||
void setStorage(std::unique_ptr<Storage>& newStorage);
|
||||
void setKtxBacking(const storage::StoragePointer& storage);
|
||||
void setKtxBacking(const std::string& filename);
|
||||
void setKtxBacking(const cache::FilePointer& cacheEntry);
|
||||
|
||||
|
|
|
@ -159,7 +159,31 @@ struct IrradianceKTXPayload {
|
|||
};
|
||||
const std::string IrradianceKTXPayload::KEY{ "hifi.irradianceSH" };
|
||||
|
||||
KtxStorage::KtxStorage(const cache::FilePointer& cacheEntry) : KtxStorage(cacheEntry->getFilepath()) {
|
||||
KtxStorage::KtxStorage(const storage::StoragePointer& storage) : _storage(storage) {
|
||||
auto ktxPointer = ktx::KTX::create(storage);
|
||||
_ktxDescriptor.reset(new ktx::KTXDescriptor(ktxPointer->toDescriptor()));
|
||||
if (_ktxDescriptor->images.size() < _ktxDescriptor->header.numberOfMipmapLevels) {
|
||||
qWarning() << "Bad images found in ktx";
|
||||
}
|
||||
|
||||
_offsetToMinMipKV = _ktxDescriptor->getValueOffsetForKey(ktx::HIFI_MIN_POPULATED_MIP_KEY);
|
||||
if (_offsetToMinMipKV) {
|
||||
auto data = storage->data() + ktx::KTX_HEADER_SIZE + _offsetToMinMipKV;
|
||||
_minMipLevelAvailable = *data;
|
||||
} else {
|
||||
// Assume all mip levels are available
|
||||
_minMipLevelAvailable = 0;
|
||||
}
|
||||
|
||||
// now that we know the ktx, let's get the header info to configure this Texture::Storage:
|
||||
Format mipFormat = Format::COLOR_BGRA_32;
|
||||
Format texelFormat = Format::COLOR_SRGBA_32;
|
||||
if (Texture::evalTextureFormat(_ktxDescriptor->header, mipFormat, texelFormat)) {
|
||||
_format = mipFormat;
|
||||
}
|
||||
}
|
||||
|
||||
KtxStorage::KtxStorage(const cache::FilePointer& cacheEntry) : KtxStorage(cacheEntry->getFilepath()) {
|
||||
_cacheEntry = cacheEntry;
|
||||
}
|
||||
|
||||
|
@ -228,28 +252,31 @@ void KtxStorage::releaseOpenKtxFiles() {
|
|||
PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const {
|
||||
auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face);
|
||||
auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face);
|
||||
storage::StoragePointer storageView;
|
||||
if (faceSize != 0 && faceOffset != 0) {
|
||||
std::lock_guard<std::mutex> lock(*_cacheFileMutex);
|
||||
auto file = maybeOpenFile();
|
||||
if (file) {
|
||||
auto storageView = file->createView(faceSize, faceOffset);
|
||||
if (storageView) {
|
||||
return storageView->toMemoryStorage();
|
||||
} else {
|
||||
qWarning() << "Failed to get a valid storageView for faceSize=" << faceSize << " faceOffset=" << faceOffset << "out of valid file " << QString::fromStdString(_filename);
|
||||
}
|
||||
if (_storage) {
|
||||
storageView = _storage->createView(faceSize, faceOffset);
|
||||
} else {
|
||||
qWarning() << "Failed to get a valid file out of maybeOpenFile " << QString::fromStdString(_filename);
|
||||
std::lock_guard<std::mutex> lock(*_cacheFileMutex);
|
||||
auto file = maybeOpenFile();
|
||||
if (file) {
|
||||
storageView = file->createView(faceSize, faceOffset);
|
||||
} else {
|
||||
qWarning() << "Failed to get a valid file out of maybeOpenFile " << QString::fromStdString(_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
if (!storageView) {
|
||||
qWarning() << "Failed to get a valid storageView for faceSize=" << faceSize << " faceOffset=" << faceOffset
|
||||
<< "out of valid file " << QString::fromStdString(_filename);
|
||||
}
|
||||
return storageView->toMemoryStorage();
|
||||
}
|
||||
|
||||
Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const {
|
||||
return _ktxDescriptor->getMipFaceTexelsSize(level, face);
|
||||
}
|
||||
|
||||
|
||||
bool KtxStorage::isMipAvailable(uint16 level, uint8 face) const {
|
||||
return level >= _minMipLevelAvailable;
|
||||
}
|
||||
|
@ -271,7 +298,7 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor
|
|||
auto& imageDesc = _ktxDescriptor->images[level];
|
||||
if (storage->size() != imageDesc._imageSize) {
|
||||
qWarning() << "Invalid image size: " << storage->size() << ", expected: " << imageDesc._imageSize
|
||||
<< ", level: " << level << ", filename: " << QString::fromStdString(_filename);
|
||||
<< ", level: " << level << ", filename: " << QString::fromStdString(_filename);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -311,8 +338,7 @@ void KtxStorage::assignMipFaceData(uint16 level, uint8 face, const storage::Stor
|
|||
throw std::runtime_error("Invalid call");
|
||||
}
|
||||
|
||||
bool validKtx(const std::string& filename) {
|
||||
ktx::StoragePointer storage { new storage::FileStorage(filename.c_str()) };
|
||||
bool validKtx(const storage::StoragePointer& storage) {
|
||||
auto ktxPointer = ktx::KTX::create(storage);
|
||||
if (!ktxPointer) {
|
||||
return false;
|
||||
|
@ -320,6 +346,21 @@ bool validKtx(const std::string& filename) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool validKtx(const std::string& filename) {
|
||||
ktx::StoragePointer storage{ new storage::FileStorage(filename.c_str()) };
|
||||
return validKtx(storage);
|
||||
}
|
||||
|
||||
void Texture::setKtxBacking(const storage::StoragePointer& storage) {
|
||||
// Check the KTX file for validity before using it as backing storage
|
||||
if (!validKtx(storage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto newBacking = std::unique_ptr<Storage>(new KtxStorage(storage));
|
||||
setStorage(newBacking);
|
||||
}
|
||||
|
||||
void Texture::setKtxBacking(const std::string& filename) {
|
||||
// Check the KTX file for validity before using it as backing storage
|
||||
if (!validKtx(filename)) {
|
||||
|
@ -355,7 +396,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
|||
// Set Dimensions
|
||||
uint32_t numFaces = 1;
|
||||
switch (texture.getType()) {
|
||||
case TEX_1D: {
|
||||
case TEX_1D: {
|
||||
if (texture.isArray()) {
|
||||
header.set1DArray(texture.getWidth(), texture.getNumSlices());
|
||||
} else {
|
||||
|
@ -363,7 +404,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TEX_2D: {
|
||||
case TEX_2D: {
|
||||
if (texture.isArray()) {
|
||||
header.set2DArray(texture.getWidth(), texture.getHeight(), texture.getNumSlices());
|
||||
} else {
|
||||
|
@ -371,7 +412,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TEX_3D: {
|
||||
case TEX_3D: {
|
||||
if (texture.isArray()) {
|
||||
header.set3DArray(texture.getWidth(), texture.getHeight(), texture.getDepth(), texture.getNumSlices());
|
||||
} else {
|
||||
|
@ -379,7 +420,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TEX_CUBE: {
|
||||
case TEX_CUBE: {
|
||||
if (texture.isArray()) {
|
||||
header.setCubeArray(texture.getWidth(), texture.getHeight(), texture.getNumSlices());
|
||||
} else {
|
||||
|
@ -388,8 +429,8 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
|||
numFaces = Texture::CUBE_FACE_COUNT;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Number level of mips coming
|
||||
|
|
|
@ -20,7 +20,7 @@ size_t Image::getByteCount() const {
|
|||
if (_format == Format_RGBAF) {
|
||||
return sizeof(FloatPixels::value_type) * _floatData.size();
|
||||
} else {
|
||||
return _packedData.byteCount();
|
||||
return _packedData.sizeInBytes();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ controller::Input KeyboardMouseDevice::InputDevice::makeInput(KeyboardMouseDevic
|
|||
*
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Property</th><th>Type</th><td>Data</th><th>Description</th></tr>
|
||||
* <tr><th>Property</th><th>Type</th><th>Data</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code> – <code>9</code></td><td>number</td><td>number</td><td>A "0" – "1" key on the
|
||||
|
@ -275,13 +275,15 @@ controller::Input KeyboardMouseDevice::InputDevice::makeInput(KeyboardMouseDevic
|
|||
* <tr><td><code>MouseWheelLeft</code></td><td>number</td><td>number</td><td>The mouse wheel rotated left. The data value
|
||||
* is the number of units rotated (typically <code>1.0</code>).</td></tr>
|
||||
* <tr><td><code>MouseWheelUp</code></td><td>number</td><td>number</td><td>The mouse wheel rotated up. The data value
|
||||
* is the number of units rotated (typically <code>1.0</code>).<br />
|
||||
* <strong>Warning:</strong> The mouse wheel in an ordinary mouse generates left/right wheel events instead of
|
||||
* up/down.</td></tr>
|
||||
* is the number of units rotated (typically <code>1.0</code>).
|
||||
* <p><strong>Warning:</strong> The mouse wheel in an ordinary mouse generates left/right wheel events instead of
|
||||
* up/down.</p>
|
||||
* </td></tr>
|
||||
* <tr><td><code>MouseWheelDown</code></td><td>number</td><td>number</td><td>The mouse wheel rotated down. The data value
|
||||
* is the number of units rotated (typically <code>1.0</code>).<br />
|
||||
* <strong>Warning:</strong> The mouse wheel in an ordinary mouse generates left/right wheel events instead of
|
||||
* up/down.</td></tr>
|
||||
* is the number of units rotated (typically <code>1.0</code>).
|
||||
* <p><strong>Warning:</strong> The mouse wheel in an ordinary mouse generates left/right wheel events instead of
|
||||
* up/down.</p>
|
||||
* </td></tr>
|
||||
* <tr><td><code>TouchpadRight</code></td><td>number</td><td>number</td><td>The average touch on a touch-enabled device
|
||||
* moved right. The data value is how far the average position of all touch points moved.</td></tr>
|
||||
* <tr><td><code>TouchpadLeft</code></td><td>number</td><td>number</td><td>The average touch on a touch-enabled device
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace ktx {
|
|||
using GLBaseInternalFormat = khronos::gl::texture::BaseInternalFormat;
|
||||
|
||||
using Storage = storage::Storage;
|
||||
using StoragePointer = std::shared_ptr<Storage>;
|
||||
using StoragePointer = std::shared_ptr<const Storage>;
|
||||
|
||||
struct ImageDescriptor;
|
||||
using ImageDescriptors = std::vector<ImageDescriptor>;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
/**jsdoc
|
||||
* The <code>Midi</code> API provides the ability to connect Interface with musical instruments and other external or virtual
|
||||
* devices via the MIDI protocol. For further information and examples, see the tutorial:
|
||||
* <a href="https://docs.highfidelity.com/en/rc81/script/midi-tutorial.html">Use MIDI to Control Your Environment</a>.</p>
|
||||
* <a href="https://docs.highfidelity.com/script/midi-tutorial.html">Use MIDI to Control Your Environment</a>.
|
||||
*
|
||||
* <p><strong>Note:</strong> Only works on Windows.</p>
|
||||
*
|
||||
|
|
|
@ -188,11 +188,11 @@ public slots:
|
|||
/**jsdoc
|
||||
* Takes you to a specified metaverse address.
|
||||
* @function location.handleLookupString
|
||||
* @param {string} address - The address to go to: a <code>"hifi://"<code> address, an IP address (e.g.,
|
||||
* <code>"127.0.0.1"</code> or <code>"localhost"</code>), a domain name, a named path on a domain (starts with
|
||||
* <code>"/"</code>), a position or position and orientation, or a user (starts with <code>"@"</code>).
|
||||
* @param {string} address - The address to go to: a <code>"hifi://"</code> address, an IP address (e.g.,
|
||||
* <code>"127.0.0.1"</code> or <code>"localhost"</code>), a domain name, a named path on a domain (starts with
|
||||
* <code>"/"</code>), a position or position and orientation, or a user (starts with <code>"@"</code>).
|
||||
* @param {boolean} [fromSuggestions=false] - Set to <code>true</code> if the address is obtained from the "Goto" dialog.
|
||||
* Helps ensure that user's location history is correctly maintained.
|
||||
* Helps ensure that user's location history is correctly maintained.
|
||||
*/
|
||||
void handleLookupString(const QString& lookupString, bool fromSuggestions = false);
|
||||
|
||||
|
@ -259,7 +259,7 @@ public slots:
|
|||
/**jsdoc
|
||||
* Checks if going back to the previous location is possible.
|
||||
* @function location.canGoBack
|
||||
* @returns <code>true</code> if going back is possible, <code>false</code> if it isn't.
|
||||
* @returns {boolean} <code>true</code> if going back is possible, <code>false</code> if it isn't.
|
||||
*/
|
||||
bool canGoBack() const;
|
||||
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
|
||||
#include "NetworkLogging.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
int hifiSockAddrMetaTypeId = qRegisterMetaType<HifiSockAddr>();
|
||||
|
||||
HifiSockAddr::HifiSockAddr() :
|
||||
|
|
|
@ -15,12 +15,7 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
struct sockaddr;
|
||||
|
||||
#include <QtNetwork/QHostInfo>
|
||||
|
||||
|
|
|
@ -38,6 +38,12 @@
|
|||
#include "udt/Packet.h"
|
||||
#include "HMACAuth.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
static Setting::Handle<quint16> LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0);
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
@ -1329,7 +1335,8 @@ void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* p
|
|||
|
||||
qCDebug(networking) << "Wrote local listening port" << localPort << "to shared memory at key" << key;
|
||||
} else {
|
||||
qWarning() << "ALERT: Failed to create and attach to shared memory to share local port with assignment-client children.";
|
||||
qWarning() << "ALERT: Failed to create and attach to shared memory to share local port with assignment-client children:"
|
||||
<< sharedPortMem->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1337,7 +1344,8 @@ void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* p
|
|||
bool LimitedNodeList::getLocalServerPortFromSharedMemory(const QString key, quint16& localPort) {
|
||||
QSharedMemory sharedMem(key);
|
||||
if (!sharedMem.attach(QSharedMemory::ReadOnly)) {
|
||||
qCWarning(networking) << "Could not attach to shared memory at key" << key;
|
||||
qCWarning(networking) << "Could not attach to shared memory at key" << key
|
||||
<< ":" << sharedMem.errorString();
|
||||
return false;
|
||||
} else {
|
||||
sharedMem.lock();
|
||||
|
|
|
@ -57,10 +57,10 @@ public:
|
|||
* @param {string} channel - The channel to send the message on.
|
||||
* @param {string} message - The message to send.
|
||||
* @param {boolean} [localOnly=false] - If <code>false</code> then the message is sent to all Interface, client entity,
|
||||
* server entity, and assignment client scripts in the domain.<br />
|
||||
* If <code>true</code> then: if sent from an Interface or client entity script it is received by all Interface and
|
||||
* server entity, and assignment client scripts in the domain.
|
||||
* <p>If <code>true</code> then: if sent from an Interface or client entity script it is received by all Interface and
|
||||
* client entity scripts; if sent from a server entity script it is received by all entity server scripts; and if sent
|
||||
* from an assignment client script it is received only by that same assignment client script.
|
||||
* from an assignment client script it is received only by that same assignment client script.</p>
|
||||
* @example <caption>Send and receive a message.</caption>
|
||||
* // Receiving script.
|
||||
* var channelName = "com.highfidelity.example.messages-example";
|
||||
|
@ -105,10 +105,10 @@ public:
|
|||
* @param {object} data - The data to send. The data is handled as a byte stream, for example, as may be provided via a
|
||||
* JavaScript <code>Int8Array</code> object.
|
||||
* @param {boolean} [localOnly=false] - If <code>false</code> then the message is sent to all Interface, client entity,
|
||||
* server entity, and assignment client scripts in the domain.<br />
|
||||
* If <code>true</code> then: if sent from an Interface or client entity script it is received by all Interface and
|
||||
* server entity, and assignment client scripts in the domain.
|
||||
* <p>If <code>true</code> then: if sent from an Interface or client entity script it is received by all Interface and
|
||||
* client entity scripts; if sent from a server entity script it is received by all entity server scripts; and if sent
|
||||
* from an assignment client script it is received only by that same assignment client script.
|
||||
* from an assignment client script it is received only by that same assignment client script.</p>
|
||||
* @example <caption>Send and receive data.</caption>
|
||||
* // Receiving script.
|
||||
* var channelName = "com.highfidelity.example.messages-example";
|
||||
|
|
|
@ -31,6 +31,14 @@
|
|||
|
||||
using namespace udt;
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
|
||||
Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) :
|
||||
QObject(parent),
|
||||
_udpSocket(parent),
|
||||
|
|
|
@ -41,13 +41,16 @@ public:
|
|||
};
|
||||
|
||||
/**jsdoc
|
||||
* The <code>Steam</code> API provides facilities for working with the Steam version of Interface.
|
||||
*
|
||||
* @namespace Steam
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
*
|
||||
* @property {boolean} running - <em>Read-only.</em>
|
||||
* @property {boolean} running - <code>true</code> if Interface is running under Steam, <code>false</code> if it isn't.
|
||||
* <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
class SteamScriptingInterface : public QObject {
|
||||
|
@ -61,13 +64,22 @@ public:
|
|||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* Gets whether Interface is running under Steam.
|
||||
* @function Steam.isRunning
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if Interface is running under Steam, <code>false</code> if it isn't.
|
||||
*/
|
||||
bool isRunning() const { return _plugin && _plugin->isRunning(); }
|
||||
|
||||
/**jsdoc
|
||||
* Opens Steam's "Choose Friends to invite" dialog if Interface is running under Steam.
|
||||
* @function Steam.openInviteOverlay
|
||||
* @example <caption>Invite Steam friends to join you in High Fidelity.</caption>
|
||||
* if (Steam.running) {
|
||||
* print("Invite Steam friends to joint you...");
|
||||
* Steam.openInviteOverlay();
|
||||
* } else {
|
||||
* print("Interface isn't running under Steam.");
|
||||
* }
|
||||
*/
|
||||
void openInviteOverlay() const { if (_plugin) { _plugin->openInviteOverlay(); } }
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ void Font::read(QIODevice& in) {
|
|||
_texture = gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::SINGLE_MIP,
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR));
|
||||
_texture->setStoredMipFormat(formatMip);
|
||||
_texture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
_texture->assignStoredMip(0, image.sizeInBytes(), image.constBits());
|
||||
}
|
||||
|
||||
void Font::setupGPU() {
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include <QString>
|
||||
|
||||
/**jsdoc
|
||||
* The <code>File</code> API provides some facilities for working with the file system.
|
||||
*
|
||||
* @namespace File
|
||||
*
|
||||
* @hifi-interface
|
||||
|
@ -35,37 +37,69 @@ public:
|
|||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
* Extracts a filename from a URL, where the filename is specified in the query part of the URL as <code>filename=</code>.
|
||||
* @function File.convertUrlToPath
|
||||
* @param {string} url
|
||||
* @returns {string}
|
||||
* @param {string} url - The URL to extract the filename from.
|
||||
* @returns {string} The filename specified in the URL; an empty string if no filename is specified.
|
||||
* @example <caption>Extract a filename from a URL.</caption>
|
||||
* var url = "http://domain.tld/path/page.html?filename=file.ext";
|
||||
* print("File name: " + File.convertUrlToPath(url)); // file.ext
|
||||
*/
|
||||
QString convertUrlToPath(QUrl url);
|
||||
|
||||
/**jsdoc
|
||||
* Unzips a file in the local file system to a new, unique temporary directory.
|
||||
* @function File.runUnzip
|
||||
* @param {string} path
|
||||
* @param {string} url
|
||||
* @param {boolean} autoAdd
|
||||
* @param {boolean} isZip
|
||||
* @param {boolean} isBlocks
|
||||
* @param {string} path - The path of the zip file in the local file system. May have a leading <code>"file:///"</code>.
|
||||
* Need not have a <code>".zip"</code> extension if it is in a temporary directory (as created by
|
||||
* {@link File.getTempDir|getTempDir}).
|
||||
* @param {string} url - <em>Not used.</em>
|
||||
* @param {boolean} autoAdd - <em>Not used by user scripts.</em> The value is simply passed through to the
|
||||
* {@link File.unzipResult|unzipResult} signal.
|
||||
* @param {boolean} isZip - Set to <code>true</code> if <code>path</code> has a <code>".zip"</code> extension,
|
||||
* <code>false</code> if it doesn't (but should still be treated as a zip file).
|
||||
* @param {boolean} isBlocks - <em>Not used by user scripts.</em> The value is simply passed through to the
|
||||
* {@link File.unzipResult|unzipResult} signal.
|
||||
* @example <caption>Select and unzip a file.</caption>
|
||||
* File.unzipResult.connect(function (zipFile, unzipFiles, autoAdd, isZip, isBlocks) {
|
||||
* print("File.unzipResult()");
|
||||
* print("- zipFile: " + zipFile);
|
||||
* print("- unzipFiles(" + unzipFiles.length + "): " + unzipFiles);
|
||||
* print("- autoAdd: " + autoAdd);
|
||||
* print("- isZip: " + isZip);
|
||||
* print("- isBlocks: " + isBlocks);
|
||||
* });
|
||||
*
|
||||
* var zipFile = Window.browse("Select a Zip File", "", "*.zip");
|
||||
* if (zipFile) {
|
||||
* File.runUnzip(zipFile, "", false, true, false);
|
||||
* } else {
|
||||
* print("Zip file not selected.");
|
||||
* }
|
||||
*/
|
||||
void runUnzip(QString path, QUrl url, bool autoAdd, bool isZip, bool isBlocks);
|
||||
|
||||
/**jsdoc
|
||||
* Creates a new, unique directory for temporary use.
|
||||
* @function File.getTempDir
|
||||
* @returns {string}
|
||||
* @returns {string} The path of the newly created temporary directory.
|
||||
* @example <caption>Create a temporary directory.</caption>
|
||||
* print("New temporary directory: " + File.getTempDir());
|
||||
*/
|
||||
QString getTempDir();
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when {@link File.runUnzip|runUnzip} completes.
|
||||
* @function File.unzipResult
|
||||
* @param {string} zipFile
|
||||
* @param {string} unzipFile
|
||||
* @param {boolean} autoAdd
|
||||
* @param {boolean} isZip
|
||||
* @param {boolean} isBlocks
|
||||
* @param {string} zipFile - The file that was unzipped.
|
||||
* @param {string[]} unzipFiles - The paths of the unzipped files in a newly created temporary directory. Includes entries
|
||||
* for any subdirectories created. An empty array if the <code>zipFile</code> could not be unzipped.
|
||||
* @param {boolean} autoAdd - The value that {@link File.runUnzip|runUnzip} was called with.
|
||||
* @param {boolean} isZip - <code>true</code> if {@link File.runUnzip|runUnzip} was called with <code>isZip == true</code>,
|
||||
* unless there is no FBX or OBJ file in the unzipped file(s) in which case the value is <code>false</code>.
|
||||
* @param {boolean} isBlocks - The value that {@link File.runUnzip|runUnzip} was called with.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void unzipResult(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip, bool isBlocks);
|
||||
|
|
|
@ -223,7 +223,7 @@ public slots:
|
|||
/**jsdoc
|
||||
* Gets the "front" direction that the camera would face if its orientation was set to the quaternion value.
|
||||
* This is a synonym for {@link Quat(0).getForward|Quat.getForward}.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
|
||||
* @function Quat(0).getFront
|
||||
* @param {Quat} orientation - A quaternion representing an orientation.
|
||||
* @returns {Vec3} The negative z-axis rotated by <code>orientation</code>.
|
||||
|
@ -233,7 +233,7 @@ public slots:
|
|||
/**jsdoc
|
||||
* Gets the "forward" direction that the camera would face if its orientation was set to the quaternion value.
|
||||
* This is a synonym for {@link Quat(0).getFront|Quat.getFront}.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
|
||||
* @function Quat(0).getForward
|
||||
* @param {Quat} orientation - A quaternion representing an orientation.
|
||||
* @returns {Vec3} The negative z-axis rotated by <code>orientation</code>.
|
||||
|
@ -245,7 +245,7 @@ public slots:
|
|||
|
||||
/**jsdoc
|
||||
* Gets the "right" direction that the camera would have if its orientation was set to the quaternion value.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
|
||||
* @function Quat(0).getRight
|
||||
* @param {Quat} orientation - A quaternion representing an orientation.
|
||||
* @returns {Vec3} The x-axis rotated by <code>orientation</code>.
|
||||
|
@ -254,7 +254,7 @@ public slots:
|
|||
|
||||
/**jsdoc
|
||||
* Gets the "up" direction that the camera would have if its orientation was set to the quaternion value.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, </code>-z</code> = forward.
|
||||
* The High Fidelity camera has axes <code>x</code> = right, <code>y</code> = up, <code>-z</code> = forward.
|
||||
* @function Quat(0).getUp
|
||||
* @param {Quat} orientation - A quaternion representing an orientation.
|
||||
* @returns {Vec3} The y-axis rotated by <code>orientation</code>.
|
||||
|
@ -405,8 +405,9 @@ public slots:
|
|||
void print(const QString& label, const glm::quat& q, bool asDegrees = false);
|
||||
|
||||
/**jsdoc
|
||||
* Tests whether two quaternions are equal. <strong>Note:</strong> The quaternions must be exactly equal in order for
|
||||
* <code>true</code> to be returned; it is often better to use {@link Quat(0).dot|Quat.dot} and test for closeness to +/-1.
|
||||
* Tests whether two quaternions are equal.
|
||||
* <p><strong>Note:</strong> The quaternions must be exactly equal in order for <code>true</code> to be returned; it is
|
||||
* often better to use {@link Quat(0).dot|Quat.dot} and test for closeness to +/-1.</p>
|
||||
* @function Quat(0).equal
|
||||
* @param {Quat} q1 - The first quaternion.
|
||||
* @param {Quat} q2 - The second quaternion.
|
||||
|
|
|
@ -1027,8 +1027,8 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString&
|
|||
};
|
||||
|
||||
/**jsdoc
|
||||
* The name of an entity event. When the entity event occurs, any function that has been registered for that event via
|
||||
* {@link Script.addEventHandler} is called with parameters per the entity event.
|
||||
* <p>The name of an entity event. When the entity event occurs, any function that has been registered for that event via
|
||||
* {@link Script.addEventHandler} is called with parameters per the entity event.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Event Name</th><th>Entity Event</th></tr>
|
||||
|
|
|
@ -46,13 +46,13 @@ void MovingPercentile::updatePercentile(qint64 sample) {
|
|||
// swap new sample with neighbors in _samplesSorted until it's in sorted order
|
||||
// try swapping up first, then down. element will only be swapped one direction.
|
||||
while (newSampleIndex < _samplesSorted.size() - 1 && sample > _samplesSorted[newSampleIndex + 1]) {
|
||||
_samplesSorted.swap(newSampleIndex, newSampleIndex + 1);
|
||||
_sampleIds.swap(newSampleIndex, newSampleIndex + 1);
|
||||
std::swap(_samplesSorted[newSampleIndex], _samplesSorted[newSampleIndex + 1]);
|
||||
std::swap(_sampleIds[newSampleIndex], _sampleIds[newSampleIndex + 1]);
|
||||
newSampleIndex++;
|
||||
}
|
||||
while (newSampleIndex > 0 && sample < _samplesSorted[newSampleIndex - 1]) {
|
||||
_samplesSorted.swap(newSampleIndex, newSampleIndex - 1);
|
||||
_sampleIds.swap(newSampleIndex, newSampleIndex - 1);
|
||||
std::swap(_samplesSorted[newSampleIndex], _samplesSorted[newSampleIndex - 1]);
|
||||
std::swap(_sampleIds[newSampleIndex], _sampleIds[newSampleIndex - 1]);
|
||||
newSampleIndex--;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <unordered_map>
|
||||
#include <chrono>
|
||||
|
||||
#include <QtCore/QOperatingSystemVersion>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -793,15 +794,7 @@ void printSystemInformation() {
|
|||
qCDebug(shared).noquote() << "\tKernel Type: " << QSysInfo::kernelType();
|
||||
qCDebug(shared).noquote() << "\tKernel Version: " << QSysInfo::kernelVersion();
|
||||
|
||||
auto macVersion = QSysInfo::macVersion();
|
||||
if (macVersion != QSysInfo::MV_None) {
|
||||
qCDebug(shared) << "\tMac Version: " << macVersion;
|
||||
}
|
||||
|
||||
auto windowsVersion = QSysInfo::windowsVersion();
|
||||
if (windowsVersion != QSysInfo::WV_None) {
|
||||
qCDebug(shared) << "\tWindows Version: " << windowsVersion;
|
||||
}
|
||||
qCDebug(shared) << "\tOS Version: " << QOperatingSystemVersion::current();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
SYSTEM_INFO si;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtCore/QFileSelector>
|
||||
#include <QtGui/QDesktopServices>
|
||||
|
||||
|
||||
|
@ -176,3 +177,15 @@ bool FileUtils::canCreateFile(const QString& fullPath) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString FileUtils::getParentPath(const QString& fullPath) {
|
||||
return QFileInfo(fullPath).absoluteDir().canonicalPath();
|
||||
}
|
||||
|
||||
bool FileUtils::exists(const QString& fileName) {
|
||||
return QFileInfo(fileName).exists();
|
||||
}
|
||||
|
||||
bool FileUtils::isRelative(const QString& fileName) {
|
||||
return QFileInfo(fileName).isRelative();
|
||||
}
|
||||
|
|
|
@ -12,20 +12,23 @@
|
|||
#ifndef hifi_FileUtils_h
|
||||
#define hifi_FileUtils_h
|
||||
|
||||
#include <QString>
|
||||
#include <QtCore/QFileSelector>
|
||||
#include <QtCore/QString>
|
||||
|
||||
class FileUtils {
|
||||
|
||||
public:
|
||||
static const QStringList& getFileSelectors();
|
||||
static QString selectFile(const QString& fileName);
|
||||
static void locateFile(const QString& fileName);
|
||||
static bool exists(const QString& fileName);
|
||||
static bool isRelative(const QString& fileName);
|
||||
static QString standardPath(QString subfolder);
|
||||
static QString readFile(const QString& filename);
|
||||
static QStringList readLines(const QString& filename, QString::SplitBehavior splitBehavior = QString::KeepEmptyParts);
|
||||
static QString replaceDateTimeTokens(const QString& path);
|
||||
static QString computeDocumentPath(const QString& path);
|
||||
static bool canCreateFile(const QString& fullPath);
|
||||
static QString getParentPath(const QString& fullPath);
|
||||
};
|
||||
|
||||
#endif // hifi_FileUtils_h
|
||||
|
|
|
@ -10,15 +10,22 @@
|
|||
#ifndef hifi_Storage_h
|
||||
#define hifi_Storage_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <QFile>
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QString>
|
||||
|
||||
namespace storage {
|
||||
class Storage;
|
||||
using StoragePointer = std::shared_ptr<const Storage>;
|
||||
using Pointer = std::shared_ptr<const Storage>;
|
||||
using StoragePointer = Pointer;
|
||||
// A function that can construct storage, useful for creating a list of
|
||||
// things that can become storage without requiring that they all be instantiated at once
|
||||
using Builder = std::function<StoragePointer()>;
|
||||
using Builders = std::vector<Builder>;
|
||||
|
||||
// Abstract class to represent memory that stored _somewhere_ (in system memory or in a file, for example)
|
||||
class Storage : public std::enable_shared_from_this<Storage> {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QtCore/qjsondocument.h>
|
||||
#include <QtCore/qjsonobject.h>
|
||||
#include <QtCore/qjsonvalue.h>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <shared/JSONHelpers.h>
|
||||
|
||||
#include "SettingHandle.h"
|
||||
|
@ -189,7 +190,7 @@ public:
|
|||
* @returns {object[]}
|
||||
*/
|
||||
Q_INVOKABLE QObjectList getSubConfigs() const {
|
||||
auto list = findChildren<JobConfig*>(QRegExp(".*"), Qt::FindDirectChildrenOnly);
|
||||
auto list = findChildren<JobConfig*>(QRegularExpression(".*"), Qt::FindDirectChildrenOnly);
|
||||
QObjectList returned;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
returned.push_back(list[i]);
|
||||
|
|
|
@ -56,10 +56,10 @@ void InfoView::show(const QString& path, bool firstOrChangedOnly, QString urlQue
|
|||
const QString lastVersion = infoVersion.get();
|
||||
const QString version = fetchVersion(url);
|
||||
// If we have version information stored
|
||||
if (lastVersion != QString::null) {
|
||||
if (!lastVersion.isNull()) {
|
||||
// Check to see the document version. If it's valid and matches
|
||||
// the stored version, we're done, so exit
|
||||
if (version == QString::null || version == lastVersion) {
|
||||
if (version.isNull() || version == lastVersion) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QEvent>
|
||||
#include <QMoveEvent>
|
||||
#include <QResizeEvent>
|
||||
|
@ -22,8 +22,8 @@
|
|||
#include <QDragEnterEvent>
|
||||
#include <QDropEvent>
|
||||
#include <QMimeData>
|
||||
#include <QWindow>
|
||||
#include <QDebug>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "ui/Logging.h"
|
||||
#include "DockWidget.h"
|
||||
|
@ -60,7 +60,7 @@ QWindow* MainWindow::findMainWindow() {
|
|||
void MainWindow::restoreGeometry() {
|
||||
// Did not use setGeometry() on purpose,
|
||||
// see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
|
||||
QRect windowGeometry = qApp->desktop()->availableGeometry();
|
||||
QRect windowGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
#if defined(Q_OS_MAC)
|
||||
windowGeometry.setSize((windowGeometry.size() * 0.5f));
|
||||
#endif
|
||||
|
|
|
@ -330,7 +330,6 @@ QObject* TabletScriptingInterface::getFlags() {
|
|||
//
|
||||
|
||||
static const char* TABLET_HOME_SOURCE_URL = "hifi/tablet/TabletHome.qml";
|
||||
static const char* WEB_VIEW_SOURCE_URL = "hifi/tablet/TabletWebView.qml";
|
||||
static const char* VRMENU_SOURCE_URL = "hifi/tablet/TabletMenu.qml";
|
||||
|
||||
class TabletRootWindow : public QmlWindowClass {
|
||||
|
@ -827,58 +826,24 @@ void TabletProxy::loadWebScreenOnTop(const QVariant& url) {
|
|||
void TabletProxy::loadWebScreenOnTop(const QVariant& url, const QString& injectJavaScriptUrl) {
|
||||
bool localSafeContext = hifi::scripting::isLocalAccessSafeThread();
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "loadHTMLSourceImpl", Q_ARG(QVariant, url), Q_ARG(QString, injectJavaScriptUrl), Q_ARG(bool, localSafeContext));
|
||||
QMetaObject::invokeMethod(this, "loadHTMLSourceOnTopImpl", Q_ARG(QString, url.toString()), Q_ARG(QString, injectJavaScriptUrl), Q_ARG(bool, false), Q_ARG(bool, localSafeContext));
|
||||
return;
|
||||
}
|
||||
|
||||
loadHTMLSourceImpl(url, injectJavaScriptUrl, localSafeContext);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TabletProxy::loadHTMLSourceImpl(const QVariant& url, const QString& injectJavaScriptUrl, bool localSafeContext) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
qCWarning(uiLogging) << __FUNCTION__ << "may not be called directly by scripts";
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
QObject* root = nullptr;
|
||||
if (!_toolbarMode && _qmlTabletRoot) {
|
||||
root = _qmlTabletRoot;
|
||||
} else if (_toolbarMode && _desktopWindow) {
|
||||
root = _desktopWindow->asQuickItem();
|
||||
}
|
||||
|
||||
if (root) {
|
||||
if (localSafeContext) {
|
||||
hifi::scripting::setLocalAccessSafeThread(true);
|
||||
}
|
||||
QMetaObject::invokeMethod(root, "loadQMLOnTop", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL)));
|
||||
QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
||||
if (_toolbarMode && _desktopWindow) {
|
||||
QMetaObject::invokeMethod(root, "setResizable", Q_ARG(const QVariant&, QVariant(false)));
|
||||
}
|
||||
QMetaObject::invokeMethod(root, "loadWebOnTop", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectJavaScriptUrl)));
|
||||
hifi::scripting::setLocalAccessSafeThread(false);
|
||||
}
|
||||
_state = State::Web;
|
||||
loadHTMLSourceOnTopImpl(url.toString(), injectJavaScriptUrl, false, localSafeContext);
|
||||
}
|
||||
|
||||
void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase) {
|
||||
bool localSafeContext = hifi::scripting::isLocalAccessSafeThread();
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "loadHTMLSourceImpl", Q_ARG(QString, url), Q_ARG(QString, injectedJavaScriptUrl), Q_ARG(bool, loadOtherBase), Q_ARG(bool, localSafeContext));
|
||||
QMetaObject::invokeMethod(this, "loadHTMLSourceOnTopImpl", Q_ARG(QString, url), Q_ARG(QString, injectedJavaScriptUrl), Q_ARG(bool, loadOtherBase), Q_ARG(bool, localSafeContext));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
loadHTMLSourceImpl(url, injectedJavaScriptUrl, loadOtherBase, localSafeContext);
|
||||
loadHTMLSourceOnTopImpl(url, injectedJavaScriptUrl, loadOtherBase, localSafeContext);
|
||||
}
|
||||
|
||||
void TabletProxy::loadHTMLSourceImpl(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase, bool localSafeContext) {
|
||||
|
||||
void TabletProxy::loadHTMLSourceOnTopImpl(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase, bool localSafeContext) {
|
||||
QObject* root = nullptr;
|
||||
if (!_toolbarMode && _qmlTabletRoot) {
|
||||
root = _qmlTabletRoot;
|
||||
|
@ -911,7 +876,6 @@ void TabletProxy::loadHTMLSourceImpl(const QString& url, const QString& injected
|
|||
_initialWebPathParams.first = injectedJavaScriptUrl;
|
||||
_initialWebPathParams.second = loadOtherBase;
|
||||
_initialScreen = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class TabletScriptingInterface : public QObject, public Dependency {
|
|||
public:
|
||||
|
||||
/**jsdoc
|
||||
* Standard tablet sounds.
|
||||
* <p>Standard tablet sounds.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
|
@ -273,7 +273,9 @@ public:
|
|||
Q_INVOKABLE void gotoHomeScreen();
|
||||
|
||||
/**jsdoc
|
||||
* Opens a web page or app on the tablet.
|
||||
* Opens a web app or page in addition to any current app. In tablet mode, the app or page is displayed over the top of the
|
||||
* current app; in toolbar mode, the app is opened in a new window that replaces any current window open. If in tablet
|
||||
* mode, the app or page can be closed using {@link TabletProxy#returnToPreviousApp}.
|
||||
* @function TabletProxy#gotoWebScreen
|
||||
* @param {string} url - The URL of the web page or app.
|
||||
* @param {string} [injectedJavaScriptUrl=""] - The URL of JavaScript to inject into the web page.
|
||||
|
@ -294,29 +296,31 @@ public:
|
|||
Q_INVOKABLE void loadQMLSource(const QVariant& path, bool resizable = false);
|
||||
|
||||
/**jsdoc
|
||||
* Internal function, do not call from scripts
|
||||
* @function TabletProxy#loadQMLSourceImpl
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Internal function, do not call from scripts.
|
||||
Q_INVOKABLE void loadQMLSourceImpl(const QVariant& path, bool resizable, bool localSafeContext);
|
||||
|
||||
/**jsdoc
|
||||
* Internal function, do not call from scripts
|
||||
* @function TabletProxy#loadHTMLSourceImpl
|
||||
/**jsdoc
|
||||
* @function TabletProxy#loadHTMLSourceOnTopImpl
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void loadHTMLSourceImpl(const QVariant& url, const QString& injectJavaScriptUrl, bool localSafeContext);
|
||||
// Internal function, do not call from scripts.
|
||||
Q_INVOKABLE void loadHTMLSourceOnTopImpl(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase, bool localSafeContext);
|
||||
|
||||
/**jsdoc
|
||||
* Internal function, do not call from scripts
|
||||
* @function TabletProxy#loadHTMLSourceImpl
|
||||
*/
|
||||
Q_INVOKABLE void loadHTMLSourceImpl(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase, bool localSafeContext);
|
||||
|
||||
/**jsdoc
|
||||
* Internal function, do not call from scripts
|
||||
/**jsdoc
|
||||
* @function TabletProxy#returnToPreviousAppImpl
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Internal function, do not call from scripts.
|
||||
Q_INVOKABLE void returnToPreviousAppImpl(bool localSafeContext);
|
||||
|
||||
/**jsdoc
|
||||
*@function TabletProxy#loadQMLOnTopImpl
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// Internal function, do not call from scripts.
|
||||
Q_INVOKABLE void loadQMLOnTopImpl(const QVariant& path, bool localSafeContext);
|
||||
|
||||
// FIXME: This currently relies on a script initializing the tablet (hence the bool denoting success);
|
||||
|
@ -355,8 +359,8 @@ public:
|
|||
|
||||
/**jsdoc
|
||||
* Opens a web app or page in addition to any current app. In tablet mode, the app or page is displayed over the top of the
|
||||
* current app; in toolbar mode, the app is opened in a new window. If in tablet mode, the app or page can be closed using
|
||||
* {@link TabletProxy#returnToPreviousApp}.
|
||||
* current app; in toolbar mode, the app is opened in a new window that replaces any current window open. If in tablet
|
||||
* mode, the app or page can be closed using {@link TabletProxy#returnToPreviousApp}.
|
||||
* @function TabletProxy#loadWebScreenOnTop
|
||||
* @param {string} path - The URL of the web page or HTML app.
|
||||
* @param {string} [injectedJavaScriptURL=""] - The URL of JavaScript to inject into the web page.
|
||||
|
|
|
@ -50,13 +50,13 @@ QString OculusControllerManager::configurationLayout() {
|
|||
|
||||
void OculusControllerManager::setConfigurationSettings(const QJsonObject configurationSettings) {
|
||||
if (configurationSettings.contains("trackControllersInOculusHome")) {
|
||||
_touch->_trackControllersInOculusHome.set(configurationSettings["trackControllersInOculusHome"].toBool());
|
||||
_trackControllersInOculusHome.set(configurationSettings["trackControllersInOculusHome"].toBool());
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject OculusControllerManager::configurationSettings() {
|
||||
QJsonObject configurationSettings;
|
||||
configurationSettings["trackControllersInOculusHome"] = _touch->_trackControllersInOculusHome.get();
|
||||
configurationSettings["trackControllersInOculusHome"] = _trackControllersInOculusHome.get();
|
||||
return configurationSettings;
|
||||
}
|
||||
|
||||
|
@ -232,7 +232,7 @@ void OculusControllerManager::TouchDevice::update(float deltaTime,
|
|||
quint64 currentTime = usecTimestampNow();
|
||||
static const auto REQUIRED_HAND_STATUS = ovrStatus_OrientationTracked | ovrStatus_PositionTracked;
|
||||
bool hasInputFocus = ovr::hasInputFocus();
|
||||
bool trackControllersInOculusHome = _trackControllersInOculusHome.get();
|
||||
bool trackControllersInOculusHome = _parent._trackControllersInOculusHome.get();
|
||||
auto tracking = ovr::getTrackingState(); // ovr_GetTrackingState(_parent._session, 0, false);
|
||||
ovr::for_each_hand([&](ovrHandType hand) {
|
||||
++numTrackedControllers;
|
||||
|
|
|
@ -98,7 +98,6 @@ private:
|
|||
float _leftHapticStrength { 0.0f };
|
||||
float _rightHapticDuration { 0.0f };
|
||||
float _rightHapticStrength { 0.0f };
|
||||
Setting::Handle<bool> _trackControllersInOculusHome { "trackControllersInOculusHome", false };
|
||||
mutable std::recursive_mutex _lock;
|
||||
std::map<int, bool> _lostTracking;
|
||||
std::map<int, quint64> _regainTrackingDeadline;
|
||||
|
@ -109,6 +108,7 @@ private:
|
|||
|
||||
void checkForConnectedDevices();
|
||||
|
||||
Setting::Handle<bool> _trackControllersInOculusHome { "trackControllersInOculusHome", false };
|
||||
ovrInputState _remoteInputState {};
|
||||
ovrInputState _touchInputState {};
|
||||
RemoteDevice::Pointer _remote;
|
||||
|
|
|
@ -127,3 +127,8 @@ Script.scriptEnding.connect(function() {
|
|||
});
|
||||
|
||||
Menu.menuItemEvent.connect(menuItemEvent);
|
||||
|
||||
var ANDROID_UI_AUTO_LOD_ADJUST = false;
|
||||
var ANDROID_UI_LOD_ANGLE_DEG = 0.248;
|
||||
LODManager.automaticLODAdjust = ANDROID_UI_AUTO_LOD_ADJUST;
|
||||
LODManager.lodAngleDeg = ANDROID_UI_LOD_ANGLE_DEG;
|
||||
|
|
|
@ -71,23 +71,63 @@ if (Menu.menuExists(MENU_CATEGORY) && !Menu.menuItemExists(MENU_CATEGORY, MENU_I
|
|||
}
|
||||
|
||||
function loadSeparateDefaults() {
|
||||
var currentlyRunningScripts = ScriptDiscoveryService.getRunning();
|
||||
|
||||
for (var i in DEFAULT_SCRIPTS_SEPARATE) {
|
||||
Script.load(DEFAULT_SCRIPTS_SEPARATE[i]);
|
||||
var shouldLoadCurrentDefaultScript = true;
|
||||
|
||||
for (var j = 0; j < currentlyRunningScripts.length; j++) {
|
||||
var currentRunningScriptObject = currentlyRunningScripts[j];
|
||||
var currentDefaultScriptName = DEFAULT_SCRIPTS_SEPARATE[i].substr((DEFAULT_SCRIPTS_SEPARATE[i].lastIndexOf("/") + 1), DEFAULT_SCRIPTS_SEPARATE[i].length);
|
||||
if (currentDefaultScriptName === currentRunningScriptObject.name) {
|
||||
shouldLoadCurrentDefaultScript = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldLoadCurrentDefaultScript) {
|
||||
Script.load(DEFAULT_SCRIPTS_SEPARATE[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runDefaultsTogether() {
|
||||
for (var i in DEFAULT_SCRIPTS_COMBINED) {
|
||||
Script.include(DEFAULT_SCRIPTS_COMBINED[i]);
|
||||
var currentlyRunningScripts = ScriptDiscoveryService.getRunning();
|
||||
|
||||
for (var i = 0; i < DEFAULT_SCRIPTS_COMBINED.length; i++) {
|
||||
var shouldIncludeCurrentDefaultScript = true;
|
||||
|
||||
for (var j = 0; j < currentlyRunningScripts.length; j++) {
|
||||
var currentRunningScriptObject = currentlyRunningScripts[j];
|
||||
var currentDefaultScriptName = DEFAULT_SCRIPTS_COMBINED[i].substr((DEFAULT_SCRIPTS_COMBINED[i].lastIndexOf("/") + 1), DEFAULT_SCRIPTS_COMBINED[i].length);
|
||||
if (currentDefaultScriptName === currentRunningScriptObject.name) {
|
||||
shouldIncludeCurrentDefaultScript = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldIncludeCurrentDefaultScript) {
|
||||
Script.include(DEFAULT_SCRIPTS_COMBINED[i]);
|
||||
}
|
||||
}
|
||||
loadSeparateDefaults();
|
||||
}
|
||||
|
||||
function runDefaultsSeparately() {
|
||||
var currentlyRunningScripts = ScriptDiscoveryService.getRunning();
|
||||
|
||||
for (var i in DEFAULT_SCRIPTS_COMBINED) {
|
||||
Script.load(DEFAULT_SCRIPTS_COMBINED[i]);
|
||||
var shouldLoadCurrentDefaultScript = true;
|
||||
|
||||
for (var j = 0; j < currentlyRunningScripts.length; j++) {
|
||||
var currentRunningScriptObject = currentlyRunningScripts[j];
|
||||
var currentDefaultScriptName = DEFAULT_SCRIPTS_COMBINED[i].substr((DEFAULT_SCRIPTS_COMBINED[i].lastIndexOf("/") + 1), DEFAULT_SCRIPTS_COMBINED[i].length);
|
||||
if (currentDefaultScriptName === currentRunningScriptObject.name) {
|
||||
shouldLoadCurrentDefaultScript = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldLoadCurrentDefaultScript) {
|
||||
Script.load(DEFAULT_SCRIPTS_COMBINED[i]);
|
||||
}
|
||||
}
|
||||
loadSeparateDefaults();
|
||||
}
|
||||
|
||||
// start all scripts
|
||||
|
@ -99,6 +139,7 @@ if (Menu.isOptionChecked(MENU_ITEM)) {
|
|||
// include all default scripts into this ScriptEngine
|
||||
runDefaultsTogether();
|
||||
}
|
||||
loadSeparateDefaults();
|
||||
|
||||
function menuItemEvent(menuItem) {
|
||||
if (menuItem === MENU_ITEM) {
|
||||
|
|
|
@ -22,6 +22,31 @@ var SECONDS_IN_MINUTE = 60;
|
|||
// Delete after 5 minutes in case a nametag is hanging around in on mode
|
||||
var ALWAYS_ON_MAX_LIFETIME_IN_SECONDS = 5 * SECONDS_IN_MINUTE;
|
||||
|
||||
// *************************************
|
||||
// START STARTUP/SHUTDOWN
|
||||
// *************************************
|
||||
// #region STARTUP/SHUTDOWN
|
||||
|
||||
|
||||
// Connect the camera mode updated signal on startup
|
||||
function startup() {
|
||||
Camera.modeUpdated.connect(handleCameraModeChanged);
|
||||
cameraModeUpdatedSignalConnected = true;
|
||||
|
||||
Script.scriptEnding.connect(shutdown);
|
||||
}
|
||||
|
||||
startup();
|
||||
|
||||
function shutdown() {
|
||||
maybeDisconnectCameraModeUpdatedSignal();
|
||||
}
|
||||
|
||||
|
||||
// *************************************
|
||||
// END STARTUP/SHUTDOWN
|
||||
// *************************************
|
||||
|
||||
// *************************************
|
||||
// START UTILTY
|
||||
// *************************************
|
||||
|
@ -197,6 +222,27 @@ function toggleInterval() {
|
|||
}
|
||||
|
||||
|
||||
// Disconnect the camera mode updated signal if we have one connected for the selfie mode
|
||||
var cameraModeUpdatedSignalConnected = false;
|
||||
function maybeDisconnectCameraModeUpdatedSignal() {
|
||||
if (cameraModeUpdatedSignalConnected) {
|
||||
Camera.modeUpdated.disconnect(handleCameraModeChanged);
|
||||
cameraModeUpdatedSignalConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Turn on the nametag for yourself if you are in selfie mode, other wise delete it
|
||||
function handleCameraModeChanged(mode) {
|
||||
if (mode === "selfie") {
|
||||
if (avatarNametagMode === "alwaysOn") {
|
||||
add(MyAvatar.sessionUUID);
|
||||
}
|
||||
} else {
|
||||
maybeRemove(MyAvatar.sessionUUID);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle checking to see if we should add or delete nametags in persistent mode
|
||||
var alwaysOnAvatarDistanceCheck = false;
|
||||
var DISTANCE_CHECK_INTERVAL_MS = 1000;
|
||||
|
@ -215,6 +261,10 @@ function handleAlwaysOnMode(shouldTurnOnAlwaysOnMode) {
|
|||
});
|
||||
maybeClearAlwaysOnAvatarDistanceCheck();
|
||||
alwaysOnAvatarDistanceCheck = Script.setInterval(maybeAddOrRemoveIntervalCheck, DISTANCE_CHECK_INTERVAL_MS);
|
||||
|
||||
if (Camera.mode === "selfie") {
|
||||
add(MyAvatar.sessionUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -595,6 +595,10 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
Controller.disableMapping(MAPPING_NAME);
|
||||
_this.pointerManager.removePointers();
|
||||
Pointers.removePointer(this.mouseRayPointer);
|
||||
Overlays.mouseReleaseOnOverlay.disconnect(mouseReleaseOnOverlay);
|
||||
Overlays.mousePressOnOverlay.disconnect(mousePress);
|
||||
Entities.mousePressOnEntity.disconnect(mousePress);
|
||||
Messages.messageReceived.disconnect(controllerDispatcher.handleMessage);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -19,41 +19,31 @@ function(check_test name)
|
|||
endfunction()
|
||||
|
||||
if (BUILD_TOOLS)
|
||||
set(ALL_TOOLS
|
||||
udt-test
|
||||
vhacd-util
|
||||
gpu-frame-player
|
||||
ice-client
|
||||
ktx-tool
|
||||
ac-client
|
||||
skeleton-dump
|
||||
atp-client
|
||||
oven
|
||||
)
|
||||
|
||||
# Allow different tools for stable builds
|
||||
if (STABLE_BUILD)
|
||||
set(ALL_TOOLS
|
||||
udt-test
|
||||
vhacd-util
|
||||
frame-optimizer
|
||||
gpu-frame-player
|
||||
ice-client
|
||||
ktx-tool
|
||||
ac-client
|
||||
skeleton-dump
|
||||
atp-client
|
||||
oven
|
||||
)
|
||||
else()
|
||||
set(ALL_TOOLS
|
||||
udt-test
|
||||
vhacd-util
|
||||
frame-optimizer
|
||||
gpu-frame-player
|
||||
ice-client
|
||||
ktx-tool
|
||||
ac-client
|
||||
skeleton-dump
|
||||
atp-client
|
||||
oven
|
||||
nitpick
|
||||
)
|
||||
list(APPEND ALL_TOOLS nitpick)
|
||||
endif()
|
||||
|
||||
foreach(TOOL ${ALL_TOOLS})
|
||||
check_test(${TOOL})
|
||||
if (${BUILD_TOOL_RESULT})
|
||||
add_subdirectory(${TOOL})
|
||||
set_target_properties(${TOOL} PROPERTIES FOLDER "Tools")
|
||||
if (TARGET ${TOOL})
|
||||
set_target_properties(${TOOL} PROPERTIES FOLDER "Tools")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
|
|
@ -17,14 +17,12 @@ WIPE_PATHS = []
|
|||
|
||||
if sys.platform == "win32":
|
||||
WIPE_PATHS = [
|
||||
'jsdoc',
|
||||
'resources/serverless'
|
||||
'jsdoc'
|
||||
]
|
||||
elif sys.platform == "darwin":
|
||||
INTERFACE_BUILD_PATH = os.path.join(INTERFACE_BUILD_PATH, "Interface.app", "Contents", "Resources")
|
||||
WIPE_PATHS = [
|
||||
'jsdoc',
|
||||
'serverless'
|
||||
'jsdoc'
|
||||
]
|
||||
|
||||
|
||||
|
@ -81,9 +79,6 @@ def fixupMacZip(filename):
|
|||
# ignore the nitpick app
|
||||
if newFilename.startswith('nitpick.app'):
|
||||
continue
|
||||
# ignore the serverless content
|
||||
if newFilename.startswith('interface.app/Contents/Resources/serverless'):
|
||||
continue
|
||||
# if we made it here, include the file in the output
|
||||
buffer = inzip.read(entry.filename)
|
||||
entry.filename = newFilename
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
set(TARGET_NAME frame-optimizer)
|
||||
|
||||
setup_memory_debugger()
|
||||
setup_hifi_project(Gui Widgets)
|
||||
link_hifi_libraries(shared ktx shaders gpu )
|
||||
package_libraries_for_deployment()
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2018/10/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 <QtCore/QCoreApplication>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <gpu/FrameIO.h>
|
||||
#include <gpu/Texture.h>
|
||||
|
||||
|
||||
gpu::IndexOptimizer optimizer= [](gpu::Primitive primitive, uint32_t faceCount, uint32_t indexCount, uint32_t* indices ) {
|
||||
// FIXME add a triangle index optimizer here
|
||||
};
|
||||
|
||||
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext &, const QString & message) {
|
||||
auto messageStr = message.toStdString();
|
||||
#ifdef Q_OS_WIN
|
||||
OutputDebugStringA(messageStr.c_str());
|
||||
OutputDebugStringA("\n");
|
||||
#endif
|
||||
std::cerr << messageStr << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
QCoreApplication app(argc, argv);
|
||||
qInstallMessageHandler(messageHandler);
|
||||
gpu::optimizeFrame("D:/Frames/20190112_1647.json", optimizer);
|
||||
return 0;
|
||||
}
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "PlayerWindow.h"
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtGui/QResizeEvent>
|
||||
#include <QtGui/QImageReader>
|
||||
#include <QtGui/QScreen>
|
||||
|
@ -55,7 +57,7 @@ void PlayerWindow::loadFrame() {
|
|||
}
|
||||
}
|
||||
|
||||
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"), openDir, tr("GPU Frames (*.json)"));
|
||||
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"), openDir, tr("GPU Frames (*.hfb)"));
|
||||
if (fileName.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
@ -104,17 +106,8 @@ void PlayerWindow::resizeEvent(QResizeEvent* ev) {
|
|||
_renderThread.resize(ev->size());
|
||||
}
|
||||
|
||||
void PlayerWindow::textureLoader(const std::string& filename, const gpu::TexturePointer& texture, uint16_t layer) {
|
||||
QImage image;
|
||||
QImageReader(filename.c_str()).read(&image);
|
||||
if (layer > 0) {
|
||||
return;
|
||||
}
|
||||
texture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
}
|
||||
|
||||
void PlayerWindow::loadFrame(const QString& path) {
|
||||
auto frame = gpu::readFrame(path.toStdString(), _renderThread._externalTexture, &PlayerWindow::textureLoader);
|
||||
auto frame = gpu::readFrame(path.toStdString(), _renderThread._externalTexture);
|
||||
if (frame) {
|
||||
_renderThread.submitFrame(frame);
|
||||
if (!_renderThread.isThreaded()) {
|
||||
|
|
|
@ -28,7 +28,7 @@ protected:
|
|||
void loadFrame(const QString& path);
|
||||
|
||||
private:
|
||||
static void textureLoader(const std::string& filename, const gpu::TexturePointer& texture, uint16_t layer);
|
||||
static void textureLoader(const std::vector<uint8_t>& filename, const gpu::TexturePointer& texture, uint16_t layer);
|
||||
QSettings _settings;
|
||||
RenderThread _renderThread;
|
||||
};
|
||||
|
|
|
@ -96,7 +96,7 @@ h6
|
|||
|
||||
.paramHeading, .typeDef h3.propsHeading, h3.subHeading
|
||||
{
|
||||
font-size: .9rem;
|
||||
font-size: 1rem;
|
||||
font-family: "Proxima Nova";
|
||||
font-weight: bold;
|
||||
border-bottom: solid 1px #ddd;
|
||||
|
@ -108,9 +108,9 @@ h4.name
|
|||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
h5, .container-overview .subsection-title
|
||||
{
|
||||
font-size: 13px;
|
||||
h5, .container-overview .subsection-title {
|
||||
font-size: 1rem;
|
||||
font-family: "Proxima Nova";
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
@ -143,6 +143,14 @@ td {
|
|||
border: solid #c7cccb 1px;
|
||||
}
|
||||
|
||||
td > p:first-child, td > ul:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
td > p:last-child, td > ul:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
article table thead tr th, article table tbody tr td, article table tbody tr td p {
|
||||
font-size: .89rem;
|
||||
line-height: 20px;
|
||||
|
@ -538,7 +546,7 @@ header {
|
|||
|
||||
.prettyprint code
|
||||
{
|
||||
font-size: 0.9em;
|
||||
font-size: .95em;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
padding: 4px 12px;
|
||||
|
@ -596,11 +604,6 @@ header {
|
|||
font-size: 100%;
|
||||
}
|
||||
|
||||
.params td.description > p:first-child, .props td.description > p:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
span.param-type, .params td .param-type, .param-type dd {
|
||||
color: #606;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace
|
||||
|
|
|
@ -63,11 +63,13 @@
|
|||
|
||||
<section>
|
||||
<article>
|
||||
|
||||
<div class="container-overview">
|
||||
<?js if (doc.kind === 'module' && doc.modules) { ?>
|
||||
<?js if (isGlobalPage) { ?>
|
||||
<?js } else if (doc.kind === 'module' && doc.modules) { ?>
|
||||
<?js if (doc.description) { ?>
|
||||
<h3>Description</h3>
|
||||
<p><?js= doc.description ?></p>
|
||||
<div><?js= doc.description ?></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js doc.modules.forEach(function(module) { ?>
|
||||
|
@ -75,7 +77,8 @@
|
|||
<?js }) ?>
|
||||
<?js } else if (doc.kind === 'class' || (doc.kind === 'namespace' && doc.signature)) { ?>
|
||||
<h3>Description</h3>
|
||||
<p><?js= doc.description ?></p>
|
||||
<div><?js= doc.description ?></div>
|
||||
<?js= self.partial('details.tmpl', doc) ?>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -84,15 +87,15 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code><?js= (doc.kind === 'class' ? 'new ' : '') + doc.name + (doc.signature || '') ?></code><p />
|
||||
<td><code><?js= (doc.kind === 'class' ? 'new ' : '') + doc.name + (doc.signature || '') ?></code>
|
||||
<?js if (doc.params) { ?>
|
||||
<h3 class="paramHeading">Parameters</h3>
|
||||
<?js= self.partial('params.tmpl', doc.params) ?>
|
||||
<?js } ?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?js= self.partial('details.tmpl', doc) ?>
|
||||
|
||||
<?js if (doc.examples && doc.examples.length) { ?>
|
||||
<h3>Example<?js= doc.examples.length > 1? 's':'' ?></h3>
|
||||
|
@ -101,7 +104,7 @@
|
|||
<?js } else { ?>
|
||||
<h3>Description</h3>
|
||||
<?js if (doc.description) { ?>
|
||||
<p><?js= doc.description ?></p>
|
||||
<div><?js= doc.description ?></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (doc.examples && doc.examples.length) { ?>
|
||||
|
@ -264,6 +267,7 @@
|
|||
<?js methods.forEach(function(m) { ?>
|
||||
<?js= self.partial('method.tmpl', m) ?>
|
||||
<?js }); ?>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
<?js
|
||||
|
@ -276,12 +280,10 @@
|
|||
<?js signals.forEach(function(s) { ?>
|
||||
<?js= self.partial('signal.tmpl', s) ?>
|
||||
<?js }); ?>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
</article>
|
||||
</section>
|
||||
<?js } ?>
|
||||
<?js }); ?>
|
||||
|
|
15
tools/jsdoc/hifi-jsdoc-template/tmpl/description.tmpl
Normal file
15
tools/jsdoc/hifi-jsdoc-template/tmpl/description.tmpl
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?js
|
||||
var description = obj;
|
||||
var self = this;
|
||||
var descriptionRegExp = new RegExp('<(p|ul|div|table)[^>]*>', 'i');
|
||||
var descriptionIndex = description.search(descriptionRegExp);
|
||||
?>
|
||||
|
||||
<?js if (descriptionIndex === -1) { ?>
|
||||
<p><?js= description ?></p>
|
||||
<?js } else if (descriptionIndex !== 0) { ?>
|
||||
<p><?js= description.slice(0, descriptionIndex) ?></p>
|
||||
<?js= description.slice(descriptionIndex) ?>
|
||||
<?js } else { ?>
|
||||
<?js= description ?>
|
||||
<?js } ?>
|
|
@ -31,113 +31,113 @@ if (data.defaultvalue && (data.defaultvaluetype === 'object' || data.defaultvalu
|
|||
|
||||
<?js if (data.version) {?>
|
||||
<p>Version:</p>
|
||||
<p><ul class="dummy"><li><?js= version ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= version ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.since) {?>
|
||||
<p>Since:</p>
|
||||
<p><ul class="dummy"><li><?js= since ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= since ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.inherited && data.inherits && !data.overrides) { ?>
|
||||
<p>Inherited From:</p>
|
||||
<p><ul class="dummy"><li>
|
||||
<div><ul class="dummy"><li>
|
||||
<?js= this.linkto(data.inherits, this.htmlsafe(data.inherits)) ?>
|
||||
</li></ul></p>
|
||||
</li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.overrides) { ?>
|
||||
<p>Overrides:</p>
|
||||
<p><ul class="dummy"><li>
|
||||
<div><ul class="dummy"><li>
|
||||
<?js= this.linkto(data.overrides, this.htmlsafe(data.overrides)) ?>
|
||||
</li></ul></p>
|
||||
</li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.implementations && data.implementations.length) { ?>
|
||||
<p>Implementations:</p>
|
||||
<p><ul>
|
||||
<div><ul>
|
||||
<?js data.implementations.forEach(function(impl) { ?>
|
||||
<li><?js= self.linkto(impl, self.htmlsafe(impl)) ?></li>
|
||||
<?js }); ?>
|
||||
</ul></p>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.implements && data.implements.length) { ?>
|
||||
<p>Implements:</p>
|
||||
<p><ul>
|
||||
<div><ul>
|
||||
<?js data.implements.forEach(function(impl) { ?>
|
||||
<li><?js= self.linkto(impl, self.htmlsafe(impl)) ?></li>
|
||||
<?js }); ?>
|
||||
</ul></p>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.mixes && data.mixes.length) { ?>
|
||||
<p>Mixes In:</p>
|
||||
|
||||
<p><ul>
|
||||
<div><ul>
|
||||
<?js data.mixes.forEach(function(a) { ?>
|
||||
<li><?js= self.linkto(a, a) ?></li>
|
||||
<?js }); ?>
|
||||
</ul></p>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
|
||||
<?js if (data.author && author.length) {?>
|
||||
<p>Author:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js author.forEach(function(a) { ?>
|
||||
<li><?js= self.resolveAuthorLinks(a) ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.copyright) {?>
|
||||
<p>Copyright:</p>
|
||||
<p><ul class="dummy"><li><?js= copyright ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= copyright ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.license) {?>
|
||||
<p>License:</p>
|
||||
<p><ul class="dummy"><li><?js= license ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= license ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.defaultvalue) {?>
|
||||
<p>Default Value:</p>
|
||||
<p><ul class="dummy">
|
||||
<li<?js= defaultObjectClass ?>><?js= data.defaultvalue ?></li>
|
||||
</ul></p>
|
||||
<div><ul class="dummy">
|
||||
<li><?js= defaultObjectClass ?>><?js= data.defaultvalue ?></li>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.meta && self.outputSourceFiles) {?>
|
||||
<p>Source:</p>
|
||||
<p><ul class="dummy"><li>
|
||||
<div><ul class="dummy"><li>
|
||||
<?js= self.linkto(meta.shortpath) ?>, <?js= self.linkto(meta.shortpath, 'line ' + meta.lineno, null, 'line' + meta.lineno) ?>
|
||||
</li></ul></p>
|
||||
</li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.tutorials && tutorials.length) {?>
|
||||
<p>Tutorials:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js tutorials.forEach(function(t) { ?>
|
||||
<li><?js= self.tutoriallink(t) ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.see && see.length) {?>
|
||||
<p class="see">See:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js see.forEach(function(s) { ?>
|
||||
<li><?js= self.linkto(s) ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.todo && todo.length) {?>
|
||||
<p>To Do:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js todo.forEach(function(t) { ?>
|
||||
<li><?js= t ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
|
|
@ -29,113 +29,113 @@ if (data.defaultvalue && (data.defaultvaluetype === 'object' || data.defaultvalu
|
|||
|
||||
<?js if (data.version) {?>
|
||||
<p>Version:</p>
|
||||
<p><ul class="dummy"><li><?js= version ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= version ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.since) {?>
|
||||
<p>Since:</p>
|
||||
<p><ul class="dummy"><li><?js= since ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= since ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.inherited && data.inherits && !data.overrides) { ?>
|
||||
<p>Inherited From:</p>
|
||||
<p><ul class="dummy"><li>
|
||||
<div><ul class="dummy"><li>
|
||||
<?js= this.linkto(data.inherits, this.htmlsafe(data.inherits)) ?>
|
||||
</li></ul></p>
|
||||
</li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.overrides) { ?>
|
||||
<p>Overrides:</p>
|
||||
<p><ul class="dummy"><li>
|
||||
<div><ul class="dummy"><li>
|
||||
<?js= this.linkto(data.overrides, this.htmlsafe(data.overrides)) ?>
|
||||
</li></ul></p>
|
||||
</li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.implementations && data.implementations.length) { ?>
|
||||
<p>Implementations:</p>
|
||||
<p><ul>
|
||||
<div><ul>
|
||||
<?js data.implementations.forEach(function(impl) { ?>
|
||||
<li><?js= self.linkto(impl, self.htmlsafe(impl)) ?></li>
|
||||
<?js }); ?>
|
||||
</ul></p>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.implements && data.implements.length) { ?>
|
||||
<p>Implements:</p>
|
||||
<p><ul>
|
||||
<div><ul>
|
||||
<?js data.implements.forEach(function(impl) { ?>
|
||||
<li><?js= self.linkto(impl, self.htmlsafe(impl)) ?></li>
|
||||
<?js }); ?>
|
||||
</ul></p>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.mixes && data.mixes.length) { ?>
|
||||
<p>Mixes In:</p>
|
||||
|
||||
<p><ul>
|
||||
<div><ul>
|
||||
<?js data.mixes.forEach(function(a) { ?>
|
||||
<li><?js= self.linkto(a, a) ?></li>
|
||||
<?js }); ?>
|
||||
</ul></p>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
|
||||
<?js if (data.author && author.length) {?>
|
||||
<p>Author:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js author.forEach(function(a) { ?>
|
||||
<li><?js= self.resolveAuthorLinks(a) ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.copyright) {?>
|
||||
<p>Copyright:</p>
|
||||
<p><ul class="dummy"><li><?js= copyright ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= copyright ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.license) {?>
|
||||
<p>License:</p>
|
||||
<p><ul class="dummy"><li><?js= license ?></li></ul></p>
|
||||
<div><ul class="dummy"><li><?js= license ?></li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.defaultvalue) {?>
|
||||
<p>Default Value:</p>
|
||||
<p><ul class="dummy">
|
||||
<li<?js= defaultObjectClass ?>><?js= data.defaultvalue ?></li>
|
||||
</ul></p>
|
||||
<div><ul class="dummy">
|
||||
<li><?js= defaultObjectClass ?>><?js= data.defaultvalue ?></li>
|
||||
</ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.meta && self.outputSourceFiles) {?>
|
||||
<p>Source:</p>
|
||||
<p><ul class="dummy"><li>
|
||||
<div><ul class="dummy"><li>
|
||||
<?js= self.linkto(meta.shortpath) ?>, <?js= self.linkto(meta.shortpath, 'line ' + meta.lineno, null, 'line' + meta.lineno) ?>
|
||||
</li></ul></p>
|
||||
</li></ul></div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.tutorials && tutorials.length) {?>
|
||||
<p>Tutorials:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js tutorials.forEach(function(t) { ?>
|
||||
<li><?js= self.tutoriallink(t) ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.see && see.length) {?>
|
||||
<p class="see">See:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js see.forEach(function(s) { ?>
|
||||
<li><?js= self.linkto(s) ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.todo && todo.length) {?>
|
||||
<p>To Do:</p>
|
||||
<p>
|
||||
<div>
|
||||
<ul><?js todo.forEach(function(t) { ?>
|
||||
<li><?js= t ?></li>
|
||||
<?js }); ?></ul>
|
||||
</p>
|
||||
</div>
|
||||
<?js } ?>
|
||||
|
|
|
@ -16,7 +16,7 @@ var self = this;
|
|||
<tr>
|
||||
<td>
|
||||
<?js if (data.description) { ?>
|
||||
<p><?js= data.description ?></p>
|
||||
<?js= self.partial('description.tmpl', data.description) ?>
|
||||
<?js } else { ?>
|
||||
<p style="color:red;"> </p>
|
||||
<?js } ?>
|
||||
|
|
|
@ -12,8 +12,9 @@ var self = this;
|
|||
Returns: <span style="font-weight: normal;">
|
||||
<?js returns.forEach(function(r) { ?>
|
||||
<?js= self.partial('returns.tmpl', r) ?>
|
||||
<?js });
|
||||
} ?></span>
|
||||
<?js }); ?>
|
||||
</span>
|
||||
<?js } ?>
|
||||
<?js if (data.kind === 'typedef' && data.type && data.type.names) { ?>
|
||||
<br />Type: <?js= self.partial('type.tmpl', data.type.names) ?>
|
||||
<?js } ?>
|
||||
|
@ -24,23 +25,23 @@ var self = this;
|
|||
<tr>
|
||||
<td>
|
||||
<?js if (data.kind !== 'module' && !data.hideconstructor) { ?>
|
||||
<p>
|
||||
<?js= data.description ?>
|
||||
<?js= this.partial('details.tmpl', data) ?>
|
||||
</p>
|
||||
<?js if (data.description) { ?>
|
||||
<?js= self.partial('description.tmpl', data.description) ?>
|
||||
<?js } ?>
|
||||
<?js= this.partial('details.tmpl', data) ?>
|
||||
<?js } else { ?>
|
||||
<p style="color:red;"> </p>
|
||||
<?js } ?>
|
||||
|
||||
<?js if (data.exceptions && exceptions.length) { ?>
|
||||
<h3 class="subHeading">Throws:</h3>
|
||||
<h3 class="subHeading">Throws</h3>
|
||||
<?js if (exceptions.length > 1) { ?><ul><?js
|
||||
exceptions.forEach(function(r) { ?>
|
||||
<li><?js= self.partial('exceptions.tmpl', r) ?></li>
|
||||
<?js });
|
||||
?></ul><?js } else {
|
||||
exceptions.forEach(function(r) { ?>
|
||||
<p><?js= self.partial('exceptions.tmpl', r) ?></p>
|
||||
<?js= self.partial('exceptions.tmpl', r) ?>
|
||||
<?js });
|
||||
} } ?>
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue