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

This commit is contained in:
Sam Gateau 2019-08-07 16:39:11 -07:00
commit c01ab954e3
105 changed files with 7212 additions and 3410 deletions

View file

@ -97,8 +97,10 @@ public:
/**jsdoc
* Starts playing an animation on the avatar.
* @function Avatar.startAnimation
* @param {string} url - The animation file's URL. Animation files need to be in the FBX format but only need to contain
* the avatar skeleton and animation data.
* @param {string} url - The animation file's URL. Animation files need to be in glTF or FBX format but only need to
* contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
* respectively).
* <p><strong>Warning:</strong> glTF animations currently do not always animate correctly.</p>
* @param {number} [fps=30] - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {number} [priority=1] - <em>Not used.</em>
* @param {boolean} [loop=false] - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.

View file

@ -160,6 +160,11 @@ bool EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
if (sendComplete && nodeData->wantReportInitialCompletion() && _traversal.finished()) {
// Dealt with all nearby entities.
nodeData->setReportInitialCompletion(false);
// initial stats and entity packets are reliable until the initial query is complete
// to guarantee all entity data is available for safe landing/physics start. Afterwards
// the packets are unreliable for performance.
nodeData->stats.getStatsMessage().setReliable(false);
nodeData->getPacket().setReliable(false);
// Send EntityQueryInitialResultsComplete reliable packet ...
auto initialCompletion = NLPacket::create(PacketType::EntityQueryInitialResultsComplete,

View file

@ -194,13 +194,13 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
// actually send it
OctreeServer::didCallWriteDatagram(this);
DependencyManager::get<NodeList>()->sendUnreliablePacket(statsPacket, *node);
DependencyManager::get<NodeList>()->sendPacket(NLPacket::createCopy(statsPacket), *node);
} else {
// not enough room in the packet, send two packets
// first packet
OctreeServer::didCallWriteDatagram(this);
DependencyManager::get<NodeList>()->sendUnreliablePacket(statsPacket, *node);
DependencyManager::get<NodeList>()->sendPacket(NLPacket::createCopy(statsPacket), *node);
int numBytes = statsPacket.getDataSize();
_totalBytes += numBytes;
@ -230,7 +230,7 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
// second packet
OctreeServer::didCallWriteDatagram(this);
DependencyManager::get<NodeList>()->sendUnreliablePacket(sentPacket, *node);
DependencyManager::get<NodeList>()->sendPacket(NLPacket::createCopy(sentPacket), *node);
numBytes = sentPacket.getDataSize();
_totalBytes += numBytes;
@ -263,7 +263,8 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
// just send the octree packet
OctreeServer::didCallWriteDatagram(this);
NLPacket& sentPacket = nodeData->getPacket();
DependencyManager::get<NodeList>()->sendUnreliablePacket(sentPacket, *node);
DependencyManager::get<NodeList>()->sendPacket(NLPacket::createCopy(sentPacket), *node);
int numBytes = sentPacket.getDataSize();
_totalBytes += numBytes;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -184,7 +184,7 @@ Flickable {
wrapMode: Text.Wrap
Component.onCompleted: {
var gpu = JSON.parse(PlatformInfo.getGPU(0));
var gpu = JSON.parse(PlatformInfo.getGPU(PlatformInfo.getMasterGPU()));
var gpuModel = gpu.model;
if (gpuModel.length === 0) {
gpuModel = "Unknown";
@ -313,7 +313,7 @@ Flickable {
textToCopy += "# CPU Cores: " + PlatformInfo.getNumLogicalCores() + "\n";
textToCopy += "RAM: " + PlatformInfo.getTotalSystemMemoryMB() + " MB\n";
var gpu = JSON.parse(PlatformInfo.getGPU(0));
var gpu = JSON.parse(PlatformInfo.getGPU(PlatformInfo.getMasterGPU()));
var gpuModel = gpu.model;
if (gpuModel.length === 0) {
gpuModel = "Unknown";

View file

@ -125,16 +125,25 @@ QString userRecenterModelToString(MyAvatar::SitStandModelType model) {
}
}
static const QStringList REACTION_NAMES = {
static const QStringList TRIGGER_REACTION_NAMES = {
QString("positive"),
QString("negative"),
QString("negative")
};
static const QStringList BEGIN_END_REACTION_NAMES = {
QString("raiseHand"),
QString("applaud"),
QString("point")
};
static int reactionNameToIndex(const QString& reactionName) {
return REACTION_NAMES.indexOf(reactionName);
static int triggerReactionNameToIndex(const QString& reactionName) {
assert(NUM_AVATAR_TRIGGER_REACTIONS == TRIGGER_REACTION_NAMES.size());
return TRIGGER_REACTION_NAMES.indexOf(reactionName);
}
static int beginEndReactionNameToIndex(const QString& reactionName) {
assert(NUM_AVATAR_BEGIN_END_REACTIONS == TRIGGER_REACTION_NAMES.size());
return BEGIN_END_REACTION_NAMES.indexOf(reactionName);
}
MyAvatar::MyAvatar(QThread* thread) :
@ -5824,13 +5833,17 @@ void MyAvatar::setModelScale(float scale) {
}
}
QStringList MyAvatar::getReactions() const {
return REACTION_NAMES;
QStringList MyAvatar::getBeginEndReactions() const {
return BEGIN_END_REACTION_NAMES;
}
QStringList MyAvatar::getTriggerReactions() const {
return TRIGGER_REACTION_NAMES;
}
bool MyAvatar::triggerReaction(QString reactionName) {
int reactionIndex = reactionNameToIndex(reactionName);
if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_REACTIONS) {
int reactionIndex = triggerReactionNameToIndex(reactionName);
if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_TRIGGER_REACTIONS) {
std::lock_guard<std::mutex> guard(_reactionLock);
_reactionTriggers[reactionIndex] = true;
return true;
@ -5839,8 +5852,8 @@ bool MyAvatar::triggerReaction(QString reactionName) {
}
bool MyAvatar::beginReaction(QString reactionName) {
int reactionIndex = reactionNameToIndex(reactionName);
if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_REACTIONS) {
int reactionIndex = beginEndReactionNameToIndex(reactionName);
if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_BEGIN_END_REACTIONS) {
std::lock_guard<std::mutex> guard(_reactionLock);
_reactionEnabledRefCounts[reactionIndex]++;
return true;
@ -5849,8 +5862,8 @@ bool MyAvatar::beginReaction(QString reactionName) {
}
bool MyAvatar::endReaction(QString reactionName) {
int reactionIndex = reactionNameToIndex(reactionName);
if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_REACTIONS) {
int reactionIndex = beginEndReactionNameToIndex(reactionName);
if (reactionIndex >= 0 && reactionIndex < (int)NUM_AVATAR_BEGIN_END_REACTIONS) {
std::lock_guard<std::mutex> guard(_reactionLock);
_reactionEnabledRefCounts[reactionIndex]--;
return true;
@ -5860,12 +5873,17 @@ bool MyAvatar::endReaction(QString reactionName) {
void MyAvatar::updateRigControllerParameters(Rig::ControllerParameters& params) {
std::lock_guard<std::mutex> guard(_reactionLock);
for (int i = 0; i < NUM_AVATAR_REACTIONS; i++) {
for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) {
params.reactionTriggers[i] = _reactionTriggers[i];
}
for (int i = 0; i < BEGIN_END_REACTION_NAMES.size(); i++) {
// copy current state into params.
params.reactionEnabledFlags[i] = _reactionEnabledRefCounts[i] > 0;
params.reactionTriggers[i] = _reactionTriggers[i];
}
for (int i = 0; i < TRIGGER_REACTION_NAMES.size(); i++) {
// clear reaction triggers here as well
_reactionTriggers[i] = false;
}

View file

@ -609,8 +609,10 @@ public:
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* <a href="https://docs.highfidelity.com/create/avatars/avatar-standards">Avatar Standards</a>.</p>
* @function MyAvatar.overrideAnimation
* @param {string} url - The URL to the animation file. Animation files need to be FBX format, but only need to contain the
* avatar skeleton and animation data.
* @param {string} url - The URL to the animation file. Animation files may be in glTF or FBX format, but only need to
* contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
* respectively).
* <p><strong>Warning:</strong> glTF animations currently do not always animate correctly.</p>
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
* @param {number} firstFrame - The frame to start the animation at.
@ -630,8 +632,10 @@ public:
* Use {@link MyAvatar.restoreHandAnimation} to restore the default poses.
* @function MyAvatar.overrideHandAnimation
* @param isLeft {boolean} <code>true</code> to override the left hand, <code>false</code> to override the right hand.
* @param {string} url - The URL of the animation file. Animation files need to be FBX format, but only need to contain the
* avatar skeleton and animation data.
* @param {string} url - The URL of the animation file. Animation files need to be in glTF or FBX format, but only need to
* contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
* respectively).
* <p><strong>Warning:</strong> glTF animations currently do not always animate correctly.</p>
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
* @param {number} firstFrame - The frame to start the animation at.
@ -702,19 +706,22 @@ public:
* <p>Each avatar has an avatar-animation.json file that defines a set of animation roles. Animation roles map to easily
* understandable actions that the avatar can perform, such as <code>"idleStand"</code>, <code>"idleTalk"</code>, or
* <code>"walkFwd"</code>. To get the full list of roles, use {@ link MyAvatar.getAnimationRoles}.
* For each role, the avatar-animation.json defines when the animation is used, the animation clip (FBX) used, and how
* animations are blended together with procedural data (such as look at vectors, hand sensors etc.).
* <code>overrideRoleAnimation()</code> is used to change the animation clip (FBX) associated with a specified animation
* role. To end the role animation and restore the default, use {@link MyAvatar.restoreRoleAnimation}.</p>
* <p>Note: Hand roles only affect the hand. Other 'main' roles, like 'idleStand', 'idleTalk', 'takeoffStand' are full body.</p>
* For each role, the avatar-animation.json defines when the animation is used, the animation clip (glTF or FBX) used, and
* how animations are blended together with procedural data (such as look at vectors, hand sensors etc.).
* <code>overrideRoleAnimation()</code> is used to change the animation clip (glTF or FBX) associated with a specified
* animation role. To end the role animation and restore the default, use {@link MyAvatar.restoreRoleAnimation}.</p>
* <p>Note: Hand roles only affect the hand. Other "main" roles, like "idleStand", "idleTalk", and "takeoffStand", are full
* body.</p>
* <p>Note: When using pre-built animation data, it's critical that the joint orientation of the source animation and target
* rig are equivalent, since the animation data applies absolute values onto the joints. If the orientations are different,
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* <a href="https://docs.highfidelity.com/create/avatars/avatar-standards">Avatar Standards</a>.
* @function MyAvatar.overrideRoleAnimation
* @param {string} role - The animation role to override
* @param {string} url - The URL to the animation file. Animation files need to be in FBX format, but only need to contain
* the avatar skeleton and animation data.
* @param {string} url - The URL to the animation file. Animation files need to be in glTF or FBX format, but only need to
* contain the avatar skeleton and animation data. glTF models may be in JSON or binary format (".gltf" or ".glb" URLs
* respectively).
* <p><strong>Warning:</strong> glTF animations currently do not always animate correctly.</p>
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
* @param {number} firstFrame - The frame the animation should start at.
@ -739,9 +746,9 @@ public:
* <p>Each avatar has an avatar-animation.json file that defines a set of animation roles. Animation roles map to easily
* understandable actions that the avatar can perform, such as <code>"idleStand"</code>, <code>"idleTalk"</code>, or
* <code>"walkFwd"</code>. To get the full list of roles, use {@link MyAvatar.getAnimationRoles}. For each role,
* the avatar-animation.json defines when the animation is used, the animation clip (FBX) used, and how animations are
* blended together with procedural data (such as look-at vectors, hand sensors etc.). You can change the animation clip
* (FBX) associated with a specified animation role using {@link MyAvatar.overrideRoleAnimation}.
* the avatar-animation.json defines when the animation is used, the animation clip (glTF or FBX) used, and how animations
* are blended together with procedural data (such as look-at vectors, hand sensors etc.). You can change the animation
* clip (glTF or FBX) associated with a specified animation role using {@link MyAvatar.overrideRoleAnimation}.
* <code>restoreRoleAnimation()</code> is used to restore a specified animation role's default animation clip. If you have
* not specified an override animation for the specified role, this function has no effect.
* @function MyAvatar.restoreRoleAnimation
@ -2042,17 +2049,19 @@ public slots:
void setEnableDebugDrawDefaultPose(bool isEnabled);
/**jsdoc
* Displays animation debug graphics. By default it shows the animation poses used for rendering.
* However, the property MyAvatar.setDebugDrawAnimPoseName can be used to draw a specific animation node.
* Displays animation debug graphics. By default, the animation poses used for rendering are displayed. However,
* {@link MyAvatar.setDebugDrawAnimPoseName} can be used to set a specific animation node to display.
* @function MyAvatar.setEnableDebugDrawAnimPose
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/
void setEnableDebugDrawAnimPose(bool isEnabled);
/**jsdoc
* If set it determines which animation debug graphics to draw, when MyAvatar.setEnableDebugDrawAnimPose is set to true.
* Sets the animation node to display when animation debug graphics are enabled with
* {@link MyAvatar.setEnableDebugDrawAnimPose}.
* @function MyAvatar.setDebugDrawAnimPoseName
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
* @param {string} poseName - The name of the animation node to display debug graphics for. Use <code>""</code> to reset to
* default.
*/
void setDebugDrawAnimPoseName(QString poseName);
@ -2213,13 +2222,23 @@ public slots:
virtual void setModelScale(float scale) override;
/**jsdoc
* MyAvatar.getReactions
* MyAvatar.getTriggerReactions
* Returns a list of reactions names that can be triggered using MyAvatar.triggerReaction().
* @returns {string[]} Array of reaction names.
*/
QStringList getReactions() const;
QStringList getTriggerReactions() const;
/**jsdoc
* MyAvatar.getBeginReactions
* Returns a list of reactions names that can be enabled using MyAvatar.beginReaction() and MyAvatar.endReaction().
* @returns {string[]} Array of reaction names.
*/
QStringList getBeginEndReactions() const;
/**jsdoc
* MyAvatar.triggerReaction
* Plays the given reaction on the avatar, once the reaction is complete it will automatically complete. Only reaction names returned from MyAvatar.getTriggerReactions() are available.
* @param {string} reactionName - reaction name
* @returns {bool} false if the given reaction is not supported.
*/
@ -2227,6 +2246,9 @@ public slots:
/**jsdoc
* MyAvatar.beginReaction
* Plays the given reaction on the avatar. The avatar will continue to play the reaction until stopped via the MyAvatar.endReaction() call or superseeded by another reaction.
* Only reaction names returned from MyAvatar.getBeginEndReactions() are available.
* NOTE: the caller is responsible for calling the corresponding MyAvatar.endReaction(), otherwise the avatar might become stuck in the reaction forever.
* @param {string} reactionName - reaction name
* @returns {bool} false if the given reaction is not supported.
*/
@ -2234,6 +2256,7 @@ public slots:
/**jsdoc
* MyAvatar.endReaction
* Used to stop a given reaction that was started via MyAvatar.beginReaction().
* @param {string} reactionName - reaction name
* @returns {bool} false if the given reaction is not supported.
*/
@ -2872,8 +2895,9 @@ private:
QScriptEngine* _scriptEngine { nullptr };
bool _needToSaveAvatarEntitySettings { false };
int _reactionEnabledRefCounts[NUM_AVATAR_REACTIONS] { 0, 0, 0, 0, 0 };
bool _reactionTriggers[NUM_AVATAR_REACTIONS] { false, false, false, false, false };
bool _reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS] { false, false };
int _reactionEnabledRefCounts[NUM_AVATAR_BEGIN_END_REACTIONS] { 0, 0, 0 };
mutable std::mutex _reactionLock;
};

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/14/2018
// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -21,4 +21,10 @@ Transform MyAvatarHeadTransformNode::getTransform() {
glm::quat ori = headOri * glm::angleAxis(-PI / 2.0f, Vectors::RIGHT);
return Transform(ori, scale, pos);
}
}
QVariantMap MyAvatarHeadTransformNode::toVariantMap() const {
QVariantMap map;
map["joint"] = "Avatar";
return map;
}

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/14/2018
// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -14,6 +14,7 @@ class MyAvatarHeadTransformNode : public TransformNode {
public:
MyAvatarHeadTransformNode() { }
Transform getTransform() override;
QVariantMap toVariantMap() const override;
};
#endif // hifi_MyAvatarHeadTransformNode_h
#endif // hifi_MyAvatarHeadTransformNode_h

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 7/16/2018
// Created by Sabrina Shanman 2018/07/16
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -460,4 +460,4 @@ Transform CollisionPick::getResultTransform() const {
Transform transform;
transform.setTranslation(_mathPick.transform.getTranslation());
return transform;
}
}

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 7/11/2018
// Created by Sabrina Shanman 2018/07/11
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -49,6 +49,7 @@ class CollisionPick : public Pick<CollisionRegion> {
public:
CollisionPick(const PickFilter& filter, float maxDistance, bool enabled, bool scaleWithParent, CollisionRegion collisionRegion, PhysicsEnginePointer physicsEngine);
PickType getType() const override { return PickType::Collision; }
CollisionRegion getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override {
return std::make_shared<CollisionPickResult>(pickVariant, std::vector<ContactTestResult>(), std::vector<ContactTestResult>());

View file

@ -27,6 +27,10 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende
{
}
PickQuery::PickType LaserPointer::getType() const {
return PickQuery::PickType::Ray;
}
void LaserPointer::editRenderStatePath(const std::string& state, const QVariant& pathProps) {
auto renderState = std::static_pointer_cast<RenderState>(_renderStates[state]);
if (renderState) {
@ -47,7 +51,7 @@ PickResultPointer LaserPointer::getPickResultCopy(const PickResultPointer& pickR
}
QVariantMap LaserPointer::toVariantMap() const {
QVariantMap qVariantMap;
QVariantMap qVariantMap = Parent::toVariantMap();
QVariantMap qRenderStates;
for (auto iter = _renderStates.cbegin(); iter != _renderStates.cend(); iter++) {

View file

@ -42,6 +42,8 @@ public:
LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers,
bool faceAvatar, bool followNormal, float followNormalStrength, bool centerEndY, bool lockEnd, bool distanceScaleEnd, bool scaleWithParent, bool enabled);
PickQuery::PickType getType() const override;
QVariantMap toVariantMap() const override;
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap);

View file

@ -23,7 +23,7 @@ void LaserPointerScriptingInterface::setIncludeItems(unsigned int uid, const QSc
}
unsigned int LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
return DependencyManager::get<PointerScriptingInterface>()->createLaserPointer(properties);
return DependencyManager::get<PointerScriptingInterface>()->createPointer(PickQuery::PickType::Ray, properties);
}
void LaserPointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const {

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/14/2018
// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -24,4 +24,10 @@ Transform MouseTransformNode::getTransform() {
}
return Transform();
}
}
QVariantMap MouseTransformNode::toVariantMap() const {
QVariantMap map;
map["joint"] = "Mouse";
return map;
}

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/14/2018
// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -13,6 +13,7 @@
class MouseTransformNode : public TransformNode {
public:
Transform getTransform() override;
QVariantMap toVariantMap() const override;
};
#endif // hifi_MouseTransformNode_h
#endif // hifi_MouseTransformNode_h

View file

@ -92,6 +92,8 @@ class ParabolaPick : public Pick<PickParabola> {
public:
ParabolaPick(const glm::vec3& position, const glm::vec3& direction, float speed, const glm::vec3& acceleration, bool rotateAccelerationWithAvatar, bool rotateAccelerationWithParent, bool scaleWithParent, const PickFilter& filter, float maxDistance, bool enabled);
PickType getType() const override { return PickType::Parabola; }
PickParabola getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared<ParabolaPickResult>(pickVariant); }

View file

@ -30,6 +30,10 @@ ParabolaPointer::ParabolaPointer(const QVariant& rayProps, const RenderStateMap&
{
}
PickQuery::PickType ParabolaPointer::getType() const {
return PickQuery::PickType::Parabola;
}
PickResultPointer ParabolaPointer::getPickResultCopy(const PickResultPointer& pickResult) const {
auto parabolaPickResult = std::dynamic_pointer_cast<ParabolaPickResult>(pickResult);
if (!parabolaPickResult) {
@ -72,7 +76,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria
}
QVariantMap ParabolaPointer::toVariantMap() const {
QVariantMap qVariantMap;
QVariantMap qVariantMap = Parent::toVariantMap();
QVariantMap qRenderStates;
for (auto iter = _renderStates.cbegin(); iter != _renderStates.cend(); iter++) {

View file

@ -101,6 +101,8 @@ public:
ParabolaPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers,
bool faceAvatar, bool followNormal, float followNormalStrength, bool centerEndY, bool lockEnd, bool distanceScaleEnd, bool scaleWithAvatar, bool enabled);
PickQuery::PickType getType() const override;
QVariantMap toVariantMap() const override;
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap);

View file

@ -34,18 +34,35 @@ static const float WEB_TOUCH_Y_OFFSET = 0.105f; // how far forward (or back wit
static const glm::vec3 TIP_OFFSET = glm::vec3(0.0f, StylusPick::WEB_STYLUS_LENGTH - WEB_TOUCH_Y_OFFSET, 0.0f);
unsigned int PickScriptingInterface::createPick(const PickQuery::PickType type, const QVariant& properties) {
std::shared_ptr<PickQuery> pick;
QVariantMap propMap = properties.toMap();
switch (type) {
case PickQuery::PickType::Ray:
return createRayPick(properties);
pick = buildRayPick(propMap);
break;
case PickQuery::PickType::Stylus:
return createStylusPick(properties);
pick = buildStylusPick(propMap);
break;
case PickQuery::PickType::Parabola:
return createParabolaPick(properties);
pick = buildParabolaPick(propMap);
break;
case PickQuery::PickType::Collision:
return createCollisionPick(properties);
pick = buildCollisionPick(propMap);
break;
default:
return PickManager::INVALID_PICK_ID;
break;
}
if (!pick) {
return PickManager::INVALID_PICK_ID;
}
propMap["pickType"] = (int)type;
pick->setScriptParameters(propMap);
return DependencyManager::get<PickManager>()->addPick(type, pick);
}
PickFilter getPickFilter(unsigned int filter) {
@ -82,17 +99,18 @@ PickFilter getPickFilter(unsigned int filter) {
* @property {Vec3} [dirOffset] - Synonym for <code>direction</code>.
* @property {Quat} [orientation] - Alternative property for specifying <code>direction</code>. The value is applied to the
* default <code>direction</code> value.
* @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A ray pick's type is {@link PickType.Ray}.
* @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 scale the pointer which owns this pick, if any.
*/
unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
std::shared_ptr<PickQuery> PickScriptingInterface::buildRayPick(const QVariantMap& propMap) {
#if defined (Q_OS_ANDROID)
QString jointName { "" };
if (propMap["joint"].isValid()) {
QString jointName = propMap["joint"].toString();
const QString MOUSE_JOINT = "Mouse";
if (jointName == MOUSE_JOINT) {
return PointerEvent::INVALID_POINTER_ID;
return nullptr;
}
}
#endif
@ -134,7 +152,7 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
auto rayPick = std::make_shared<RayPick>(position, direction, filter, maxDistance, enabled);
setParentTransform(rayPick, propMap);
return DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, rayPick);
return rayPick;
}
/**jsdoc
@ -152,10 +170,9 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
* means no maximum.
* @property {Vec3} [tipOffset=0,0.095,0] - The position of the stylus tip relative to the hand position at default avatar
* scale.
* @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A stylus pick's type is {@link PickType.Stylus}.
*/
unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
std::shared_ptr<PickQuery> PickScriptingInterface::buildStylusPick(const QVariantMap& propMap) {
bilateral::Side side = bilateral::Side::Invalid;
{
QVariant handVar = propMap["hand"];
@ -184,7 +201,7 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties
tipOffset = vec3FromVariant(propMap["tipOffset"]);
}
return DependencyManager::get<PickManager>()->addPick(PickQuery::Stylus, std::make_shared<StylusPick>(side, filter, maxDistance, enabled, tipOffset));
return std::make_shared<StylusPick>(side, filter, maxDistance, enabled, tipOffset);
}
// NOTE: Laser pointer still uses scaleWithAvatar. Until scaleWithAvatar is also deprecated for pointers, scaleWithAvatar should not be removed from the pick API.
@ -228,10 +245,11 @@ unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties
* with the avatar or other parent.
* @property {boolean} [scaleWithAvatar=true] - Synonym for <code>scalewithParent</code>.
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
* @property {PickType} pickType - The type of pick when getting these properties from {@link Picks.getPickProperties} or {@link Picks.getPickScriptParameters}. A parabola pick's type is {@link PickType.Parabola}.
* @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.
*/
unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
std::shared_ptr<PickQuery> PickScriptingInterface::buildParabolaPick(const QVariantMap& propMap) {
bool enabled = false;
if (propMap["enabled"].isValid()) {
enabled = propMap["enabled"].toBool();
@ -292,7 +310,7 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
auto parabolaPick = std::make_shared<ParabolaPick>(position, direction, speed, accelerationAxis,
rotateAccelerationWithAvatar, rotateAccelerationWithParent, scaleWithParent, filter, maxDistance, enabled);
setParentTransform(parabolaPick, propMap);
return DependencyManager::get<PickManager>()->addPick(PickQuery::Parabola, parabolaPick);
return parabolaPick;
}
@ -326,10 +344,11 @@ unsigned int PickScriptingInterface::createParabolaPick(const QVariant& properti
* 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.
*/
unsigned int PickScriptingInterface::createCollisionPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
std::shared_ptr<PickQuery> PickScriptingInterface::buildCollisionPick(const QVariantMap& propMap) {
bool enabled = false;
if (propMap["enabled"].isValid()) {
enabled = propMap["enabled"].toBool();
@ -354,7 +373,7 @@ unsigned int PickScriptingInterface::createCollisionPick(const QVariant& propert
auto collisionPick = std::make_shared<CollisionPick>(filter, maxDistance, enabled, scaleWithParent, collisionRegion, qApp->getPhysicsEngine());
setParentTransform(collisionPick, propMap);
return DependencyManager::get<PickManager>()->addPick(PickQuery::Collision, collisionPick);
return collisionPick;
}
void PickScriptingInterface::enablePick(unsigned int uid) {
@ -365,10 +384,26 @@ void PickScriptingInterface::disablePick(unsigned int uid) {
DependencyManager::get<PickManager>()->disablePick(uid);
}
bool PickScriptingInterface::isPickEnabled(unsigned int uid) const {
return DependencyManager::get<PickManager>()->isPickEnabled(uid);
}
void PickScriptingInterface::removePick(unsigned int uid) {
DependencyManager::get<PickManager>()->removePick(uid);
}
QVariantMap PickScriptingInterface::getPickProperties(unsigned int uid) const {
return DependencyManager::get<PickManager>()->getPickProperties(uid);
}
QVariantMap PickScriptingInterface::getPickScriptParameters(unsigned int uid) const {
return DependencyManager::get<PickManager>()->getPickScriptParameters(uid);
}
QVector<unsigned int> PickScriptingInterface::getPicks() const {
return DependencyManager::get<PickManager>()->getPicks();
}
QVariantMap PickScriptingInterface::getPrevPickResult(unsigned int uid) {
QVariantMap result;
auto pickResult = DependencyManager::get<PickManager>()->getPrevPickResult(uid);

View file

@ -10,7 +10,6 @@
#include <QtCore/QObject>
#include <RegisteredMetaTypes.h>
#include <DependencyManager.h>
#include <PhysicsEngine.h>
#include <Pick.h>
@ -98,11 +97,6 @@ class PickScriptingInterface : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
unsigned int createRayPick(const QVariant& properties);
unsigned int createStylusPick(const QVariant& properties);
unsigned int createCollisionPick(const QVariant& properties);
unsigned int createParabolaPick(const QVariant& properties);
void registerMetaTypes(QScriptEngine* engine);
/**jsdoc
@ -134,6 +128,14 @@ public:
*/
Q_INVOKABLE void disablePick(unsigned int uid);
/**jsdoc
* Get the enabled status of a pick. Enabled picks update their pick results.
* @function Picks.isPickEnabled
* @param {number} id - The ID of the pick.
* @returns {boolean} enabled - Whether or not the pick is enabled.
*/
Q_INVOKABLE bool isPickEnabled(unsigned int uid) const;
/**jsdoc
* Removes (deletes) a pick.
* @function Picks.removePick
@ -141,6 +143,32 @@ public:
*/
Q_INVOKABLE void removePick(unsigned int uid);
/**jsdoc
* Gets the current properties of the pick.
* @function Picks.getPickProperties
* @param {number} id - The ID of the pick.
* @returns {Picks.RayPickProperties|Picks.ParabolaPickProperties|Picks.StylusPickProperties|Picks.CollisionPickProperties} Properties of the pick, per the pick <code>type</code>.
*/
Q_INVOKABLE QVariantMap getPickProperties(unsigned int uid) const;
/**jsdoc
* Gets the parameters that were passed in to {@link Picks.createPick} to create the pick,
* if the pick was created through a script.
* Note that these properties do not reflect the current state of the pick.
* See {@link Picks.getPickProperties}.
* @function Picks.getPickScriptParameters
* @param {number} id - The ID of the pick.
* @returns {Picks.RayPickProperties|Picks.ParabolaPickProperties|Picks.StylusPickProperties|Picks.CollisionPickProperties} User-provided properties, per the pick <code>type</code>.
*/
Q_INVOKABLE QVariantMap getPickScriptParameters(unsigned int uid) const;
/**jsdoc
* Gets all picks which currently exist, including disabled picks.
* @function Picks.getPicks
* @returns {number[]} picks - The IDs of the picks.
*/
Q_INVOKABLE QVector<unsigned int> getPicks() const;
/**jsdoc
* Gets the most recent result from a pick. A pick continues to be updated ready to return a result, as long as it is
* enabled.
@ -419,6 +447,11 @@ public slots:
static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
protected:
static std::shared_ptr<PickQuery> buildRayPick(const QVariantMap& properties);
static std::shared_ptr<PickQuery> buildStylusPick(const QVariantMap& properties);
static std::shared_ptr<PickQuery> buildCollisionPick(const QVariantMap& properties);
static std::shared_ptr<PickQuery> buildParabolaPick(const QVariantMap& properties);
static void setParentTransform(std::shared_ptr<PickQuery> pick, const QVariantMap& propMap);
};

View file

@ -13,6 +13,7 @@
#include <shared/QtHelpers.h>
#include "Application.h"
#include "PickManager.h"
#include "LaserPointer.h"
#include "StylusPointer.h"
#include "ParabolaPointer.h"
@ -38,16 +39,48 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
return result;
}
QVariantMap propertyMap = properties.toMap();
std::shared_ptr<Pointer> pointer;
switch (type) {
case PickQuery::PickType::Ray:
return createLaserPointer(properties);
pointer = buildLaserPointer(propertyMap);
break;
case PickQuery::PickType::Stylus:
return createStylus(properties);
pointer = buildStylus(propertyMap);
break;
case PickQuery::PickType::Parabola:
return createParabolaPointer(properties);
pointer = buildParabolaPointer(propertyMap);
break;
default:
return PointerEvent::INVALID_POINTER_ID;
break;
}
if (!pointer) {
return PointerEvent::INVALID_POINTER_ID;
}
propertyMap["pointerType"] = (int)type;
pointer->setScriptParameters(propertyMap);
return DependencyManager::get<PointerManager>()->addPointer(pointer);
}
bool PointerScriptingInterface::isPointerEnabled(unsigned int uid) const {
return DependencyManager::get<PointerManager>()->isPointerEnabled(uid);
}
QVector<unsigned int> PointerScriptingInterface::getPointers() const {
return DependencyManager::get<PointerManager>()->getPointers();
}
QVariantMap PointerScriptingInterface::getPointerProperties(unsigned int uid) const {
return DependencyManager::get<PointerManager>()->getPointerProperties(uid);
}
QVariantMap PointerScriptingInterface::getPointerScriptParameters(unsigned int uid) const {
return DependencyManager::get<PointerManager>()->getPointerScriptParameters(uid);
}
/**jsdoc
@ -56,6 +89,8 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
* @property {Pointers.StylusPointerModel} [model] - Override some or all of the default stylus model properties.
* @property {boolean} [hover=false] - <code>true</code> if the pointer generates {@link Entities} hover events,
* <code>false</code> if it doesn't.
* @property {PickType} pointerType - The type of pointer when getting these properties from {@link Pointers.getPointerProperties} or {@link Pointers.getPointerScriptParameters}. A stylus pointer's type is {@link PickType.Stylus}.
* @property {number} [pickID] - Returned from {@link Pointers.getPointerProperties}. The ID of the pick created alongside this pointer.
* @see {@link Picks.StylusPickProperties} for additional properties from the underlying stylus pick.
*/
/**jsdoc
@ -67,7 +102,7 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
* offset.
* @property {Quat} [rotationOffset] - The rotation offset of the model from the hand, to override the default rotation offset.
*/
unsigned int PointerScriptingInterface::createStylus(const QVariant& properties) const {
std::shared_ptr<Pointer> PointerScriptingInterface::buildStylus(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
bool hover = false;
@ -100,8 +135,7 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
}
}
return DependencyManager::get<PointerManager>()->addPointer(std::make_shared<StylusPointer>(properties, StylusPointer::buildStylus(propertyMap), hover, enabled, modelPositionOffset,
modelRotationOffset, modelDimensions));
return std::make_shared<StylusPointer>(properties, StylusPointer::buildStylus(propertyMap), hover, enabled, modelPositionOffset, modelRotationOffset, modelDimensions);
}
/**jsdoc
@ -174,9 +208,11 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
* <code>false</code> if it doesn't.
* @property {Pointers.Trigger[]} [triggers=[]] - A list of ways that a {@link Controller} action or function should trigger
* events on the entity or overlay currently intersected.
* @property {PickType} pointerType - The type of pointer when getting these properties from {@link Pointers.getPointerProperties} or {@link Pointers.getPointerScriptParameters}. A laser pointer's type is {@link PickType.Ray}.
* @property {number} [pickID] - Returned from {@link Pointers.getPointerProperties}. The ID of the pick created alongside this pointer.
* @see {@link Picks.RayPickProperties} for additional properties from the underlying ray pick.
*/
unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
std::shared_ptr<Pointer> PointerScriptingInterface::buildLaserPointer(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
#if defined (Q_OS_ANDROID)
@ -185,7 +221,7 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
QString jointName = propertyMap["joint"].toString();
const QString MOUSE_JOINT = "Mouse";
if (jointName == MOUSE_JOINT) {
return PointerEvent::INVALID_POINTER_ID;
return nullptr;
}
}
#endif
@ -283,9 +319,9 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
}
}
return DependencyManager::get<PointerManager>()->addPointer(std::make_shared<LaserPointer>(properties, renderStates, defaultRenderStates, hover, triggers,
faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd,
distanceScaleEnd, scaleWithParent, enabled));
return std::make_shared<LaserPointer>(properties, renderStates, defaultRenderStates, hover, triggers,
faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd,
distanceScaleEnd, scaleWithParent, enabled);
}
/**jsdoc
@ -365,9 +401,11 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
* <code>false</code> if it doesn't.
* @property {Pointers.Trigger[]} [triggers=[]] - A list of ways that a {@link Controller} action or function should trigger
* events on the entity or overlay currently intersected.
* @property {PickType} pointerType - The type of pointer when getting these properties from {@link Pointers.getPointerProperties} or {@link Pointers.getPointerScriptParameters}. A parabola pointer's type is {@link PickType.Parabola}.
* @property {number} [pickID] - Returned from {@link Pointers.getPointerProperties}. The ID of the pick created alongside this pointer.
* @see {@link Picks.ParabolaPickProperties} for additional properties from the underlying parabola pick.
*/
unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& properties) const {
std::shared_ptr<Pointer> PointerScriptingInterface::buildParabolaPointer(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
bool faceAvatar = false;
@ -463,9 +501,9 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr
}
}
return DependencyManager::get<PointerManager>()->addPointer(std::make_shared<ParabolaPointer>(properties, renderStates, defaultRenderStates, hover, triggers,
faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd, distanceScaleEnd,
scaleWithParent, enabled));
return std::make_shared<ParabolaPointer>(properties, renderStates, defaultRenderStates, hover, triggers,
faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd, distanceScaleEnd,
scaleWithParent, enabled);
}
void PointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const {
@ -497,7 +535,3 @@ QVariantMap PointerScriptingInterface::getPrevPickResult(unsigned int uid) const
}
return result;
}
QVariantMap PointerScriptingInterface::getPointerProperties(unsigned int uid) const {
return DependencyManager::get<PointerManager>()->getPointerProperties(uid);
}

View file

@ -11,6 +11,7 @@
#include <QtCore/QObject>
#include "DependencyManager.h"
#include "RegisteredMetaTypes.h"
#include <PointerManager.h>
#include <Pick.h>
@ -31,9 +32,6 @@ class PointerScriptingInterface : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
unsigned int createLaserPointer(const QVariant& properties) const;
unsigned int createStylus(const QVariant& properties) const;
unsigned int createParabolaPointer(const QVariant& properties) const;
/**jsdoc
* Specifies that a {@link Controller} action or function should trigger events on the entity or overlay currently
@ -147,6 +145,14 @@ public:
*/
Q_INVOKABLE void disablePointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->disablePointer(uid); }
/**jsdoc
* Gets the enabled status of a pointer. Enabled pointers update their pick results and generate events.
* @function Pointers.isPointerEnabled
* @param {number} id - The ID of the pointer.
* @returns {boolean} enabled - Whether or not the pointer is enabled.
*/
Q_INVOKABLE bool isPointerEnabled(unsigned int uid) const;
/**jsdoc
* Removes (deletes) a pointer.
* @function Pointers.removePointer
@ -154,6 +160,24 @@ public:
*/
Q_INVOKABLE void removePointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->removePointer(uid); }
/**jsdoc
* Gets the parameters that were passed in to {@link Pointers.createPointer} to create the pointer,
* if the pointer was created through a script.
* Note that these properties do not reflect the current state of the pointer.
* See {@link Pointers.getPointerProperties}.
* @function Pointers.getPointerScriptParameters
* @param {number} id - The ID of the pointer.
* @returns {Pointers.RayPointerProperties|Picks.ParabolaPointerProperties|Picks.StylusPointerProperties} User-provided properties, per the pointer <code>type</code>.
*/
Q_INVOKABLE QVariantMap getPointerScriptParameters(unsigned int uid) const;
/**jsdoc
* Gets all pointers which currently exist, including disabled pointers.
* @function Pointers.getPointers
* @returns {number[]} pointers - The IDs of the pointers.
*/
Q_INVOKABLE QVector<unsigned int> getPointers() const;
/**jsdoc
* Edits a render state of a {@link Pointers.RayPointerProperties|ray} or
* {@link Pointers.ParabolaPointerProperties|parabola} pointer, to change its visual appearance for the state when the
@ -448,6 +472,11 @@ public:
* });
*/
Q_INVOKABLE QVariantMap getPointerProperties(unsigned int uid) const;
protected:
static std::shared_ptr<Pointer> buildLaserPointer(const QVariant& properties);
static std::shared_ptr<Pointer> buildStylus(const QVariant& properties);
static std::shared_ptr<Pointer> buildParabolaPointer(const QVariant& properties);
};
#endif // hifi_PointerScriptingInterface_h

View file

@ -88,6 +88,8 @@ public:
Pick(PickRay(position, direction), filter, maxDistance, enabled) {
}
PickType getType() const override { return PickType::Ray; }
PickRay getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared<RayPickResult>(pickVariant); }

View file

@ -17,7 +17,7 @@
#include <PickManager.h>
unsigned int RayPickScriptingInterface::createRayPick(const QVariant& properties) {
return DependencyManager::get<PickScriptingInterface>()->createRayPick(properties);
return DependencyManager::get<PickScriptingInterface>()->createPick(PickQuery::PickType::Ray, properties);
}
void RayPickScriptingInterface::enableRayPick(unsigned int uid) {

View file

@ -72,6 +72,7 @@ class StylusPick : public Pick<StylusTip> {
public:
StylusPick(Side side, const PickFilter& filter, float maxDistance, bool enabled, const glm::vec3& tipOffset);
PickType getType() const override { return PickType::Stylus; }
StylusTip getMathematicalPick() const override;
PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override;
PickResultPointer getEntityIntersection(const StylusTip& pick) override;

View file

@ -29,7 +29,7 @@ static const QString DEFAULT_STYLUS_MODEL_URL = PathUtils::resourcesUrl() + "/me
StylusPointer::StylusPointer(const QVariant& props, const QUuid& stylus, bool hover, bool enabled,
const glm::vec3& modelPositionOffset, const glm::quat& modelRotationOffset, const glm::vec3& modelDimensions) :
Pointer(DependencyManager::get<PickScriptingInterface>()->createStylusPick(props), enabled, hover),
Pointer(DependencyManager::get<PickScriptingInterface>()->createPick(PickQuery::PickType::Stylus, props), enabled, hover),
_stylus(stylus),
_modelPositionOffset(modelPositionOffset),
_modelDimensions(modelDimensions),
@ -43,6 +43,10 @@ StylusPointer::~StylusPointer() {
}
}
PickQuery::PickType StylusPointer::getType() const {
return PickQuery::PickType::Stylus;
}
QUuid StylusPointer::buildStylus(const QVariantMap& properties) {
// FIXME: we have to keep using the Overlays interface here, because existing scripts use overlay properties to define pointers
QVariantMap propertiesMap;
@ -229,7 +233,7 @@ void StylusPointer::setRenderState(const std::string& state) {
}
QVariantMap StylusPointer::toVariantMap() const {
return QVariantMap();
return Parent::toVariantMap();
}
glm::vec3 StylusPointer::findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& direction) {

View file

@ -23,6 +23,8 @@ public:
const glm::vec3& modelPositionOffset, const glm::quat& modelRotationOffset, const glm::vec3& modelDimensions);
~StylusPointer();
PickQuery::PickType getType() const override;
void updateVisuals(const PickResultPointer& pickResult) override;
// Styluses have three render states:

View file

@ -66,15 +66,19 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
* @property {boolean} pushToTalkHMD - <code>true</code> if HMD push-to-talk is enabled, otherwise <code>false</code>.
* @property {boolean} pushingToTalk - <code>true</code> if the user is currently pushing-to-talk, otherwise
* <code>false</code>.
* @property {number} avatarGain - The gain (relative volume) that avatars' voices are played at. This gain is used at the server.
* @property {number} localInjectorGain - The gain (relative volume) that local injectors (local environment sounds) are played at.
* @property {number} serverInjectorGain - The gain (relative volume) that server injectors (server environment sounds) are played at. This gain is used at the server.
* @property {number} systemInjectorGain - The gain (relative volume) that system sounds are played at.
* @property {number} pushingToTalkOutputGainDesktop - The gain (relative volume) that all sounds are played at when the user is holding
* the push-to-talk key in Desktop mode.
* @property {boolean} acousticEchoCancellation - <code>true</code> if audio-echo-cancellation is enabled, otherwise
* <code>false</code>. When enabled, sound from the audio output will be suppressed when it echos back to the
* input audio signal.
* @property {number} avatarGain - The gain (relative volume in dB) that avatars' voices are played at. This gain is used
* at the server.
* @property {number} localInjectorGain - The gain (relative volume in dB) that local injectors (local environment sounds)
* are played at.
* @property {number} serverInjectorGain - The gain (relative volume in dB) that server injectors (server environment
* sounds) are played at. This gain is used at the server.
* @property {number} systemInjectorGain - The gain (relative volume in dB) that system sounds are played at.
* @property {number} pushingToTalkOutputGainDesktop - The gain (relative volume in dB) that all sounds are played at when
* the user is holding the push-to-talk key in desktop mode.
* @property {boolean} acousticEchoCancellation - <code>true</code> if acoustic echo cancellation is enabled, otherwise
* <code>false</code>. When enabled, sound from the audio output is suppressed when it echos back to the input audio
* signal.
*
* @comment The following properties are from AudioScriptingInterface.h.
* @property {boolean} isStereoInput - <code>true</code> if the input audio is being used in stereo, otherwise
@ -301,18 +305,18 @@ public:
Q_INVOKABLE bool getRecording();
/**jsdoc
* Sets the output volume gain that will be used when the user is holding the Push to Talk key.
* Sets the output volume gain that will be used when the user is holding the push-to-talk key.
* Should be negative.
* @function Audio.setPushingToTalkOutputGainDesktop
* @param {number} gain - The output volume gain (dB) while using PTT.
* @param {number} gain - The output volume gain (dB) while using push-to-talk.
*/
Q_INVOKABLE void setPushingToTalkOutputGainDesktop(float gain);
/**jsdoc
* Gets the output volume gain that is used when the user is holding the Push to Talk key.
* Gets the output volume gain that is used when the user is holding the push-to-talk key.
* Should be negative.
* @function Audio.getPushingToTalkOutputGainDesktop
* @returns {number} gain - The output volume gain (dB) while using PTT.
* @returns {number} gain - The output volume gain (dB) while using push-to-talk.
*/
Q_INVOKABLE float getPushingToTalkOutputGainDesktop();
@ -457,7 +461,7 @@ signals:
/**jsdoc
* Triggered when the avatar gain changes.
* @function Audio.avatarGainChanged
* @param {number} gain - The new avatar gain value.
* @param {number} gain - The new avatar gain value (dB).
* @returns {Signal}
*/
void avatarGainChanged(float gain);
@ -465,7 +469,7 @@ signals:
/**jsdoc
* Triggered when the local injector gain changes.
* @function Audio.localInjectorGainChanged
* @param {number} gain - The new local injector gain value.
* @param {number} gain - The new local injector gain value (dB).
* @returns {Signal}
*/
void localInjectorGainChanged(float gain);
@ -473,7 +477,7 @@ signals:
/**jsdoc
* Triggered when the server injector gain changes.
* @function Audio.serverInjectorGainChanged
* @param {number} gain - The new server injector gain value.
* @param {number} gain - The new server injector gain value (dB).
* @returns {Signal}
*/
void serverInjectorGainChanged(float gain);
@ -481,7 +485,7 @@ signals:
/**jsdoc
* Triggered when the system injector gain changes.
* @function Audio.systemInjectorGainChanged
* @param {number} gain - The new system injector gain value.
* @param {number} gain - The new system injector gain value (dB).
* @returns {Signal}
*/
void systemInjectorGainChanged(float gain);
@ -489,7 +493,7 @@ signals:
/**jsdoc
* Triggered when the push to talk gain changes.
* @function Audio.pushingToTalkOutputGainDesktopChanged
* @param {number} gain - The new output gain value.
* @param {number} gain - The new output gain value (dB).
* @returns {Signal}
*/
void pushingToTalkOutputGainDesktopChanged(float gain);

View file

@ -15,7 +15,7 @@
class QScriptValue;
/**jsdoc
* The <code>PlatformInfo</code> API provides information about the computer and controllers being used.
* The <code>PlatformInfo</code> API provides information about the hardware platform being used.
*
* @namespace PlatformInfo
*
@ -31,6 +31,21 @@ public:
PlatformInfoScriptingInterface();
virtual ~PlatformInfoScriptingInterface();
/**jsdoc
* <p>The platform tier of a computer is an indication of its rendering capability.</p>
* <table>
* <thead>
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
* </thead>
* <tbody>
* <tr><td><code>0</code></td><td>UNKNOWN</td><td>Unknown rendering capability.</td></tr>
* <tr><td><code>1</code></td><td>LOW</td><td>Low-end PC, capable of rendering low-quality graphics.</td></tr>
* <tr><td><code>2</code></td><td>MID</td><td>Business-class PC, capable of rendering medium-quality graphics.</td></tr>
* <tr><td><code>3</code></td><td>HIGH</td><td>High-end PC, capable of rendering high-quality graphics.</td></tr>
* </tbody>
* </table>
* @typedef {number} PlatformInfo.PlatformTier
*/
// Platform tier enum type
enum PlatformTier {
UNKNOWN = platform::Profiler::Tier::UNKNOWN,
@ -50,23 +65,18 @@ public slots:
/**jsdoc
* Gets the operating system type.
* @function PlatformInfo.getOperatingSystemType
* @returns {string} <code>"WINDOWS"</code>, <code>"MACOS"</code>, or <code>"UNKNOWN"</code>.
* @returns {string} The operating system type: <code>"WINDOWS"</code>, <code>"MACOS"</code>, or <code>"UNKNOWN"</code>.
* @deprecated This function is deprecated and will be removed.
* use getComputer()["OS"] instead
* Use <code>JSON.parse({@link PlatformInfo.getComputer|PlatformInfo.getComputer()}).OS</code> instead.
*/
QString getOperatingSystemType();
/**jsdoc
* Gets information on the CPU.
* Gets information on the CPU model.
* @function PlatformInfo.getCPUBrand
* @returns {string} Information on the CPU.
* @example <caption>Report the CPU being used.</caption>
* print("CPU: " + PlatformInfo.getCPUBrand());
* // Example: Intel(R) Core(TM) i7-7820HK CPU @ 2.90GHz
* @deprecated This function is deprecated and will be removed.
* use getNumCPUs() to know the number of CPUs in the hardware, at least one is expected
* use getCPU(0)["vendor"] to get the brand of the vendor
* use getCPU(0)["model"] to get the model name of the cpu
* Use <code>JSON.parse({@link PlatformInfo.getCPU|PlatformInfo.getCPU(0)}).model</code> instead.
*/
QString getCPUBrand();
@ -75,27 +85,27 @@ public slots:
* @function PlatformInfo.getNumLogicalCores
* @returns {number} The number of logical CPU cores.
* @deprecated This function is deprecated and will be removed.
* use getCPU(0)["numCores"] instead
* Use <code>JSON.parse({@link PlatformInfo.getCPU|PlatformInfo.getCPU(0)}).numCores</code> instead.
*/
unsigned int getNumLogicalCores();
/**jsdoc
* Returns the total system memory in megabytes.
* Gets the total amount of usable physical memory, in MB.
* @function PlatformInfo.getTotalSystemMemoryMB
* @returns {number} The total system memory in megabytes.
* @deprecated This function is deprecated and will be removed.
* use getMemory()["memTotal"] instead
* Use <code>JSON.parse({@link PlatformInfo.getMemory|PlatformInfo.getMemory()}).memTotal</code> instead.
*/
int getTotalSystemMemoryMB();
/**jsdoc
* Gets the graphics card type.
* Gets the model of the graphics card currently being used.
* @function PlatformInfo.getGraphicsCardType
* @returns {string} The graphics card type.
* @returns {string} The model of the graphics card currently being used.
* @deprecated This function is deprecated and will be removed.
* use getNumGPUs() to know the number of GPUs in the hardware, at least one is expected
* use getGPU(getMasterGPU())["vendor"] to get the brand of the vendor
* use getGPU(getMasterGPU())["model"] to get the model name of the gpu
* Use <code>JSON.parse({@link PlatformInfo.getGPU|PlatformInfo.getGPU(}
* {@link PlatformInfo.getMasterGPU|PlatformInfo.getMasterGPU() )}).model</code>
* instead.
*/
QString getGraphicsCardType();
@ -117,139 +127,150 @@ public slots:
* Checks whether HTML on 3D surfaces (e.g., Web entities) is supported.
* @function PlatformInfo.has3DHTML
* @returns {boolean} <code>true</code> if the current display supports HTML on 3D surfaces, <code>false</code> if it
* doesn't.
* doesn't.
*/
bool has3DHTML();
/**jsdoc
* Checks whether Interface is running on a stand-alone HMD device (CPU incorporated into the HMD display).
* @function PlatformInfo.isStandalone
* @returns {boolean} <code>true</code> if Interface is running on a stand-alone device, <code>false</code> if it isn't.
* @returns {boolean} <code>true</code> if Interface is running on a stand-alone HMD device, <code>false</code> if it isn't.
*/
bool isStandalone();
/**jsdoc
* Get the number of CPUs.
* @function PlatformInfo.getNumCPUs
* @returns {number} The number of CPUs detected on the hardware platform.
*/
* Gets the number of CPUs.
* @function PlatformInfo.getNumCPUs
* @returns {number} The number of CPUs.
*/
int getNumCPUs();
/**jsdoc
* Get the index of the master CPU.
* @function PlatformInfo.getMasterCPU
* @returns {number} The index of the master CPU detected on the hardware platform.
*/
* Gets the index number of the master CPU.
* @function PlatformInfo.getMasterCPU
* @returns {number} The index of the master CPU.
*/
int getMasterCPU();
/**jsdoc
* Get the description of the CPU at the index parameter
* expected fields are:
* - cpuVendor...
* @param index The index of the CPU of the platform
* @function PlatformInfo.getCPU
* @returns {string} The CPU description json field
*/
* Gets the platform description of a CPU.
* @function PlatformInfo.getCPU
* @param {number} index - The index number of the CPU.
* @returns {string} The CPU's {@link PlatformInfo.CPUDescription|CPUDescription} information as a JSON string.
* @example <caption>Report details of the computer's CPUs.</caption>
* var numCPUs = PlatformInfo.getNumCPUs();
* print("Number of CPUs: " + numCPUs);
* for (var i = 0; i < numCPUs; i++) {
* var cpuDescription = PlatformInfo.getCPU(i);
* print("CPU " + i + ": " + cpuDescription);
* }
*/
QString getCPU(int index);
/**jsdoc
* Get the number of GPUs.
* Gets the number of GPUs.
* @function PlatformInfo.getNumGPUs
* @returns {number} The number of GPUs detected on the hardware platform.
* @returns {number} The number of GPUs.
*/
int getNumGPUs();
/**jsdoc
* Get the index of the master GPU.
* @function PlatformInfo.getMasterGPU
* @returns {number} The index of the master GPU detected on the hardware platform.
*/
* Gets the index number of the master GPU.
* @function PlatformInfo.getMasterGPU
* @returns {number} The index of the master GPU.
*/
int getMasterGPU();
/**jsdoc
* Get the description of the GPU at the index parameter
* expected fields are:
* - vendor, model...
* @param index The index of the GPU of the platform
* Gets the platform description of a GPU.
* @param {number} index - The index number of the GPU.
* @function PlatformInfo.getGPU
* @returns {string} The GPU description json field
* @returns {string} The GPU's {@link PlatformInfo.GPUDescription|GPUDescription} information as a JSON string.
* @example <caption>Report details of the computer's GPUs.</caption>
* var numGPUs = PlatformInfo.getNumGPUs();
* print("Number of GPUs: " + numGPUs);
* for (var i = 0; i < numGPUs; i++) {
* var gpuDescription = PlatformInfo.getGPU(i);
* print("GPU " + i + ": " + gpuDescription);
* }
*/
QString getGPU(int index);
/**jsdoc
* Get the number of Displays.
* @function PlatformInfo.getNumDisplays
* @returns {number} The number of Displays detected on the hardware platform.
*/
* Gets the number of displays.
* @function PlatformInfo.getNumDisplays
* @returns {number} The number of displays.
*/
int getNumDisplays();
/**jsdoc
* Get the index of the master Display.
* @function PlatformInfo.getMasterDisplay
* @returns {number} The index of the master Display detected on the hardware platform.
*/
* Gets the index number of the master display.
* @function PlatformInfo.getMasterDisplay
* @returns {number} The index of the master display.
*/
int getMasterDisplay();
/**jsdoc
* Get the description of the Display at the index parameter
* expected fields are:
* - DisplayVendor...
* @param index The index of the Display of the platform
* @function PlatformInfo.getDisplay
* @returns {string} The Display description json field
*/
* Gets the platform description of a display.
* @param {number} index - The index number of the display.
* @function PlatformInfo.getDisplay
* @returns {string} The display's {@link PlatformInfo.DisplayDescription|DisplayDescription} information as a JSON string.
* @example <caption>Report details of the systems's displays.</caption>
* var numDisplays = PlatformInfo.getNumDisplays();
* print("Number of displays: " + numDisplays);
* for (var i = 0; i < numDisplays; i++) {
* var displayDescription = PlatformInfo.getDisplay(i);
* print("Display " + i + ": " + displayDescription);
* }
*/
QString getDisplay(int index);
/**jsdoc
* Get the description of the Memory
* expected fields are:
* - MemoryVendor...
* @function PlatformInfo.getMemory
* @returns {string} The Memory description json field
*/
* Gets the platform description of computer memory.
* @function PlatformInfo.getMemory
* @returns {string} The computer's {@link PlatformInfo.MemoryDescription|MemoryDescription} information as a JSON string.
* @example <caption>Report details of the computer's memory.</caption>
* print("Memory: " + PlatformInfo.getMemory());
*/
QString getMemory();
/**jsdoc
* Get the description of the Computer
* expected fields are:
* - ComputerVendor...
* @function PlatformInfo.getComputer
* @returns {string} The Computer description json field
*/
* Gets the platform description of the computer.
* @function PlatformInfo.getComputer
* @returns {string} The {@link PlatformInfo.ComputerDescription|ComputerDescription} information as a JSON string.
*/
QString getComputer();
/**jsdoc
* Get the complete description of the Platform as an aggregated Json
* The expected object description is:
* { "computer": {...}, "memory": {...}, "cpus": [{...}, ...], "gpus": [{...}, ...], "displays": [{...}, ...] }
* @function PlatformInfo.getPlatform
* @returns {string} The Platform description json field
*/
* Gets the complete description of the computer as a whole.
* @function PlatformInfo.getPlatform
* @returns {string} The {@link PlatformInfo.PlatformDescription|PlatformDescription} information as a JSON string.
*/
QString getPlatform();
/**jsdoc
* Get the Platform TIer profiled on startup of the Computer
* Platform Tier is an integer/enum value:
* UNKNOWN = 0, LOW = 1, MID = 2, HIGH = 3
* @function PlatformInfo.getTierProfiled
* @returns {number} The Platform Tier profiled on startup.
*/
* Gets the platform tier of the computer, profiled at Interface start-up.
* @function PlatformInfo.getTierProfiled
* @returns {PlatformInfo.PlatformTier} The platform tier of the computer.
* @example <caption>Report the platform tier of the computer.</caption>
* var platformTier = PlatformInfo.getTierProfiled();
* var platformTierName = PlatformInfo.getPlatformTierNames()[platformTier];
* print("Platform tier: " + platformTier + ", " + platformTierName);
*/
PlatformTier getTierProfiled();
/**jsdoc
* Get the Platform Tier possible Names as an array of strings
* Platform Tier names are:
* [ "UNKNOWN", "LOW", "MID", "HIGH" ]
* @function PlatformInfo.getPlatformTierNames
* @returns {string} The array of names matching the number returned from PlatformInfo.getTierProfiled
*/
* Gets the names of the possible platform tiers, per {@link PlatformInfo.PlatformTier}.
* @function PlatformInfo.getPlatformTierNames
* @returns {string[]} The names of the possible platform tiers.
*/
QStringList getPlatformTierNames();
/**jsdoc
* Gets whether the current hardware can render using the Deferred method.
* @function PlatformInfo.isRenderMethodDeferredCapable
* @returns {bool} <code>true</code> if the current hardware can render using the Deferred method; <code>false</code> otherwise.
*/
* Gets whether the current hardware can use deferred rendering.
* @function PlatformInfo.isRenderMethodDeferredCapable
* @returns {boolean} <code>true</code> if the current hardware can use deferred rendering, <code>false</code> if it can't.
*/
bool isRenderMethodDeferredCapable();
};

View file

@ -15,13 +15,20 @@
#include "RenderForward.h"
/**jsdoc
* The <code>Render</code> API allows you to configure the graphics engine
* The <code>Render</code> API enables you to configure the graphics engine.
*
* @namespace Render
*
* @hifi-interface
* @hifi-client-entity
* @hifi-avatar
*
* @property {Render.RenderMethod} renderMethod - The render method being used.
* @property {boolean} shadowsEnabled - <code>true</code> if shadows are enabled, <code>false</code> if they're disabled.
* @property {boolean} ambientOcclusionEnabled - <code>true</code> if ambient occlusion is enabled, <code>false</code> if it's
* disabled.
* @property {boolean} antialiasingEnabled - <code>true</code> if anti-aliasing is enabled, <code>false</code> if it's disabled.
* @property {number} viewportResolutionScale - The view port resolution scale, <code>&gt; 0.0</code>.
*/
class RenderScriptingInterface : public QObject {
Q_OBJECT
@ -36,6 +43,21 @@ public:
static RenderScriptingInterface* getInstance();
/**jsdoc
* <p>The rendering method is specified by the following values:</p>
* <table>
* <thead>
* <tr><th>Value</th><th>Name</th><th>Description</th>
* </thead>
* <tbody>
* <tr><td><code>0</code></td><td>DEFERRED</td><td>More complex rendering pipeline where lighting is applied to the
* scene as a whole after all objects have been rendered.</td></tr>
* <tr><td><code>1</code></td><td>FORWARD</td><td>Simpler rendering pipeline where each object in the scene, in turn,
* is rendered and has lighting applied.</td></tr>
* </tbody>
* </table>
* @typedef {number} Render.RenderMethod
*/
// RenderMethod enum type
enum class RenderMethod {
DEFERRED = render::Args::RenderMethod::DEFERRED,
@ -52,95 +74,114 @@ public:
public slots:
/**jsdoc
* Get a config for a job by name
* Gets the configuration for a rendering job by name.
* <p><strong>Warning:</strong> For internal, debugging purposes. Subject to change.</p>
* @function Render.getConfig
* @param {string} name - Can be:
* - <job_name>: Search for the first job named job_name traversing the the sub graph of task and jobs (from this task as root)
* - <parent_name>.[<sub_parent_names>.]<job_name>: Allows you to first look for the parent_name job (from this task as root) and then search from there for the
* optional sub_parent_names and finally from there looking for the job_name (assuming every job in the path is found)
* @returns {object} The sub job config.
* @param {string} name - The name of the rendering job.
* @returns {object} The configuration for the rendering job.
*/
QObject* getConfig(const QString& name) { return qApp->getRenderEngine()->getConfiguration()->getConfig(name); }
/**jsdoc
* Gets the current render method
* Gets the render method being used.
* @function Render.getRenderMethod
* @returns {number} <code>"DEFERRED"</code> or <code>"FORWARD"</code>
* @returns {Render.RenderMethod} The render method being used.
* @example <caption>Report the current render method.</caption>
* var renderMethod = Render.getRenderMethod();
* print("Current render method: " + Render.getRenderMethodNames()[renderMethod]);
*/
RenderMethod getRenderMethod() const;
/**jsdoc
* Sets the current render method
* Sets the render method to use.
* @function Render.setRenderMethod
* @param {number} renderMethod - <code>"DEFERRED"</code> or <code>"FORWARD"</code>
* @param {Render.RenderMethod} renderMethod - The render method to use.
*/
void setRenderMethod(RenderMethod renderMethod);
/**jsdoc
* Gets the possible enum names of the RenderMethod type
* @function Render.getRenderMethodNames
* @returns [string] [ <code>"DEFERRED"</code>, <code>"FORWARD"</code> ]
*/
* Gets the names of the possible render methods, per {@link Render.RenderMethod}.
* @function Render.getRenderMethodNames
* @returns {string[]} The names of the possible render methods.
* @example <caption>Report the names of the possible render methods.</caption>
* var renderMethods = Render.getRenderMethodNames();
* print("Render methods:");
* for (var i = 0; i < renderMethods.length; i++) {
* print("- " + renderMethods[i]);
* }
*/
QStringList getRenderMethodNames() const;
/**jsdoc
* Whether or not shadows are enabled
* Gets whether or not shadows are enabled.
* @function Render.getShadowsEnabled
* @returns {bool} <code>true</code> if shadows are enabled, otherwise <code>false</code>
* @returns {boolean} <code>true</code> if shadows are enabled, <code>false</code> if they're disabled.
*/
bool getShadowsEnabled() const;
/**jsdoc
* Enables or disables shadows
* Sets whether or not shadows are enabled.
* @function Render.setShadowsEnabled
* @param {bool} enabled - <code>true</code> to enable shadows, <code>false</code> to disable them
* @param {boolean} enabled - <code>true</code> to enable shadows, <code>false</code> to disable.
*/
void setShadowsEnabled(bool enabled);
/**jsdoc
* Whether or not ambient occlusion is enabled
* Gets whether or not ambient occlusion is enabled.
* @function Render.getAmbientOcclusionEnabled
* @returns {bool} <code>true</code> if ambient occlusion is enabled, otherwise <code>false</code>
* @returns {boolean} <code>true</code> if ambient occlusion is enabled, <code>false</code> if it's disabled.
*/
bool getAmbientOcclusionEnabled() const;
/**jsdoc
* Enables or disables ambient occlusion
* Sets whether or not ambient occlusion is enabled.
* @function Render.setAmbientOcclusionEnabled
* @param {bool} enabled - <code>true</code> to enable ambient occlusion, <code>false</code> to disable it
* @param {boolean} enabled - <code>true</code> to enable ambient occlusion, <code>false</code> to disable.
*/
void setAmbientOcclusionEnabled(bool enabled);
/**jsdoc
* Whether or not anti-aliasing is enabled
* Gets whether or not anti-aliasing is enabled.
* @function Render.getAntialiasingEnabled
* @returns {bool} <code>true</code> if anti-aliasing is enabled, otherwise <code>false</code>
* @returns {boolean} <code>true</code> if anti-aliasing is enabled, <code>false</code> if it's disabled.
*/
bool getAntialiasingEnabled() const;
/**jsdoc
* Enables or disables anti-aliasing
* Sets whether or not anti-aliasing is enabled.
* @function Render.setAntialiasingEnabled
* @param {bool} enabled - <code>true</code> to enable anti-aliasing, <code>false</code> to disable it
* @param {boolean} enabled - <code>true</code> to enable anti-aliasing, <code>false</code> to disable.
*/
void setAntialiasingEnabled(bool enabled);
/**jsdoc
* Gets the current viewport resolution scale
* Gets the view port resolution scale.
* @function Render.getViewportResolutionScale
* @returns {number}
* @returns {number} The view port resolution scale, <code>&gt; 0.0</code>.
*/
float getViewportResolutionScale() const;
/**jsdoc
* Sets the current viewport resolution scale
* Sets the view port resolution scale.
* @function Render.setViewportResolutionScale
* @param {number} resolutionScale - between epsilon and 1.0
* @param {number} resolutionScale - The view port resolution scale to set, <code>&gt; 0.0</code>.
*/
void setViewportResolutionScale(float resolutionScale);
signals:
/**jsdoc
* Triggered when one of the <code>Render</code> API's properties changes.
* @function Render.settingsChanged
* @returns {Signal}
* @example <caption>Report when a render setting changes.</caption>
* Render.settingsChanged.connect(function () {
* print("Render setting changed");
* });
* // Toggle Developer > Render > Shadows or similar to trigger.
*/
void settingsChanged();
private:

View file

@ -1740,7 +1740,9 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
* 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 {string} url - The URL of the FBX or OBJ model used for the overlay.
* @property {string} url - The URL of the glTF, FBX, or OBJ model used for the overlay. glTF models may be in JSON or binary
* format (".gltf" or ".glb" URLs respectively). Baked models' URLs have ".baked" before the file type. Model files may
* also be compressed in GZ format, in which case the URL ends in ".gz".
* @property {number} loadPriority=0.0 - The priority for loading and displaying the overlay. Overlays with higher values load
* first. <em>Currently not used.</em>
* @property {Object.<string, string>|string} textures - Texture name, URL pairs used when rendering the model in place of the

View file

@ -47,7 +47,7 @@
return;
}
NSLog(@"extracting Launcher file");
BOOL extractionSuccessful = [sharedLauncher extractZipFileAtDestination:[sharedLauncher getDownloadPathForContentAndScripts] :[[sharedLauncher getDownloadPathForContentAndScripts] stringByAppendingString:@"HQ Launcher.zip"]];
BOOL extractionSuccessful = [sharedLauncher extractZipFileAtDestination:[sharedLauncher getDownloadPathForContentAndScripts] :[[sharedLauncher getDownloadPathForContentAndScripts] stringByAppendingString:destinationFileName]];
if (!extractionSuccessful) {
[sharedLauncher displayErrorPage];

View file

@ -72,9 +72,7 @@ BOOL CLauncherApp::InitInstance() {
} else {
_manager.init(!noUpdate, continueAction);
}
if (!_manager.hasFailed() && !_manager.installLauncher()) {
return FALSE;
}
_manager.tryToInstallLauncher();
installFont(IDR_FONT_REGULAR);
installFont(IDR_FONT_BOLD);
CWinApp::InitInstance();

View file

@ -656,7 +656,6 @@ BOOL CLauncherDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
if (theApp._manager.hasFailed() && _drawStep != DrawStep::DrawError) {
theApp._manager.saveErrorLog();
prepareProcess(DrawStep::DrawError);
@ -757,6 +756,9 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
_applicationWND = theApp._manager.launchApplication();
}
}
if (theApp._manager.needsToSelfInstall()) {
theApp._manager.tryToInstallLauncher(TRUE);
}
}
void CLauncherDlg::setVerticalElement(CWnd* element, int verticalOffset, int heightOffset, bool fromMainWindowBottom) {

View file

@ -108,7 +108,7 @@ void LauncherManager::saveErrorLog() {
}
}
BOOL LauncherManager::installLauncher() {
void LauncherManager::tryToInstallLauncher(BOOL retry) {
CString appPath;
BOOL result = getAndCreatePaths(PathType::Running_Path, appPath);
if (!result) {
@ -126,26 +126,49 @@ BOOL LauncherManager::installLauncher() {
if (!_shouldUninstall) {
// The installer is not running on the desired location and has to be installed
// Kill of running before self-copy
addToLog(_T("Installing Launcher."));
addToLog(_T("Trying to install launcher."));
int launcherPID = -1;
if (LauncherUtils::isProcessRunning(LAUNCHER_EXE_FILENAME, launcherPID)) {
if (!LauncherUtils::shutdownProcess(launcherPID, 0)) {
addToLog(_T("Error shutting down the Launcher"));
}
}
CopyFile(appPath, instalationPath, FALSE);
const int LAUNCHER_INSTALL_RETRYS = 10;
const int WAIT_BETWEEN_RETRYS_MS = 10;
int installTrys = retry ? LAUNCHER_INSTALL_RETRYS : 0;
for (int i = 0; i <= installTrys; i++) {
_retryLauncherInstall = !CopyFile(appPath, instalationPath, FALSE);
if (!_retryLauncherInstall) {
addToLog(_T("Launcher installed successfully."));
break;
} else if (i < installTrys) {
CString msg;
msg.Format(_T("Installing launcher try: %d"), i);
addToLog(msg);
Sleep(WAIT_BETWEEN_RETRYS_MS);
} else if (installTrys > 0) {
addToLog(_T("Error installing launcher."));
_retryLauncherInstall = false;
_hasFailed = true;
} else {
addToLog(_T("Old launcher is still running. Install could not be completed."));
}
}
}
} else if (_shouldUninstall) {
addToLog(_T("Launching Uninstall mode."));
CString tempPath;
if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) {
tempPath += _T("\\HQ_uninstaller_tmp.exe");
CopyFile(instalationPath, tempPath, false);
LauncherUtils::launchApplication(tempPath, _T(" --uninstall"));
exit(0);
if (!CopyFile(instalationPath, tempPath, false)) {
addToLog(_T("Error copying uninstaller to tmp directory."));
_hasFailed = true;
} else {
LauncherUtils::launchApplication(tempPath, _T(" --uninstall"));
exit(0);
}
}
}
return TRUE;
}
BOOL LauncherManager::restartLauncher() {

View file

@ -92,7 +92,7 @@ public:
BOOL deleteShortcuts();
HWND launchApplication();
BOOL uninstallApplication();
BOOL installLauncher();
void tryToInstallLauncher(BOOL retry = FALSE);
BOOL restartLauncher();
// getters
@ -108,6 +108,7 @@ public:
BOOL needsInstall() const { return _shouldInstall; }
BOOL needsToWait() const { return _shouldWait; }
BOOL needsRestartNewLauncher() const { return _shouldRestartNewLauncher; }
BOOL needsToSelfInstall() const { return _retryLauncherInstall; }
BOOL willContinueUpdating() const { return _keepUpdating; }
ContinueActionOnStart getContinueAction() { return _continueAction; }
void setDisplayName(const CString& displayName) { _displayName = displayName; }
@ -164,6 +165,7 @@ private:
BOOL _shouldRestartNewLauncher { FALSE };
BOOL _keepLoggingIn { FALSE };
BOOL _keepUpdating { FALSE };
BOOL _retryLauncherInstall { FALSE };
ContinueActionOnStart _continueAction;
float _progressOffset { 0.0f };
float _progress { 0.0f };

View file

@ -29,6 +29,7 @@
#include "AnimTwoBoneIK.h"
#include "AnimSplineIK.h"
#include "AnimPoleVectorConstraint.h"
#include "AnimUtil.h"
using NodeLoaderFunc = AnimNode::Pointer (*)(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
using NodeProcessFunc = bool (*)(AnimNode::Pointer node, const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl);
@ -91,6 +92,8 @@ static AnimStateMachine::InterpType stringToInterpType(const QString& str) {
return AnimStateMachine::InterpType::SnapshotBoth;
} else if (str == "snapshotPrev") {
return AnimStateMachine::InterpType::SnapshotPrev;
} else if (str == "evaluateBoth") {
return AnimStateMachine::InterpType::EvaluateBoth;
} else {
return AnimStateMachine::InterpType::NumTypes;
}
@ -101,11 +104,63 @@ static AnimRandomSwitch::InterpType stringToRandomInterpType(const QString& str)
return AnimRandomSwitch::InterpType::SnapshotBoth;
} else if (str == "snapshotPrev") {
return AnimRandomSwitch::InterpType::SnapshotPrev;
} else if (str == "evaluateBoth") {
return AnimRandomSwitch::InterpType::EvaluateBoth;
} else {
return AnimRandomSwitch::InterpType::NumTypes;
}
}
static EasingType stringToEasingType(const QString& str) {
if (str == "linear") {
return EasingType_Linear;
} else if (str == "easeInSine") {
return EasingType_EaseInSine;
} else if (str == "easeOutSine") {
return EasingType_EaseOutSine;
} else if (str == "easeInOutSine") {
return EasingType_EaseInOutSine;
} else if (str == "easeInQuad") {
return EasingType_EaseInQuad;
} else if (str == "easeOutQuad") {
return EasingType_EaseOutQuad;
} else if (str == "easeInOutQuad") {
return EasingType_EaseInOutQuad;
} else if (str == "easeInCubic") {
return EasingType_EaseInCubic;
} else if (str == "easeOutCubic") {
return EasingType_EaseOutCubic;
} else if (str == "easeInOutCubic") {
return EasingType_EaseInOutCubic;
} else if (str == "easeInQuart") {
return EasingType_EaseInQuart;
} else if (str == "easeOutQuart") {
return EasingType_EaseOutQuart;
} else if (str == "easeInOutQuart") {
return EasingType_EaseInOutQuart;
} else if (str == "easeInQuint") {
return EasingType_EaseInQuint;
} else if (str == "easeOutQuint") {
return EasingType_EaseOutQuint;
} else if (str == "easeInOutQuint") {
return EasingType_EaseInOutQuint;
} else if (str == "easeInExpo") {
return EasingType_EaseInExpo;
} else if (str == "easeOutExpo") {
return EasingType_EaseOutExpo;
} else if (str == "easeInOutExpo") {
return EasingType_EaseInOutExpo;
} else if (str == "easeInCirc") {
return EasingType_EaseInCirc;
} else if (str == "easeOutCirc") {
return EasingType_EaseOutCirc;
} else if (str == "easeInOutCirc") {
return EasingType_EaseInOutCirc;
} else {
return EasingType_NumTypes;
}
}
static const char* animManipulatorJointVarTypeToString(AnimManipulator::JointVar::Type type) {
switch (type) {
case AnimManipulator::JointVar::Type::Absolute: return "absolute";
@ -723,6 +778,7 @@ bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj,
READ_FLOAT(interpTarget, stateObj, nodeId, jsonUrl, false);
READ_FLOAT(interpDuration, stateObj, nodeId, jsonUrl, false);
READ_OPTIONAL_STRING(interpType, stateObj);
READ_OPTIONAL_STRING(easingType, stateObj);
READ_OPTIONAL_STRING(interpTargetVar, stateObj);
READ_OPTIONAL_STRING(interpDurationVar, stateObj);
@ -743,7 +799,16 @@ bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj,
}
}
auto statePtr = std::make_shared<AnimStateMachine::State>(id, iter->second, interpTarget, interpDuration, interpTypeEnum);
EasingType easingTypeEnum = EasingType_Linear; // default value
if (!easingType.isEmpty()) {
easingTypeEnum = stringToEasingType(easingType);
if (easingTypeEnum == EasingType_NumTypes) {
qCCritical(animation) << "AnimNodeLoader, bad easingType on stateMachine state, nodeId = " << nodeId << "stateId =" << id;
return false;
}
}
auto statePtr = std::make_shared<AnimStateMachine::State>(id, iter->second, interpTarget, interpDuration, interpTypeEnum, easingTypeEnum);
assert(statePtr);
if (!interpTargetVar.isEmpty()) {
@ -845,6 +910,7 @@ bool processRandomSwitchStateMachineNode(AnimNode::Pointer node, const QJsonObje
READ_FLOAT(interpTarget, stateObj, nodeId, jsonUrl, false);
READ_FLOAT(interpDuration, stateObj, nodeId, jsonUrl, false);
READ_OPTIONAL_STRING(interpType, stateObj);
READ_OPTIONAL_STRING(easingType, stateObj);
READ_FLOAT(priority, stateObj, nodeId, jsonUrl, false);
READ_BOOL(resume, stateObj, nodeId, jsonUrl, false);
@ -867,7 +933,16 @@ bool processRandomSwitchStateMachineNode(AnimNode::Pointer node, const QJsonObje
}
}
auto randomStatePtr = std::make_shared<AnimRandomSwitch::RandomSwitchState>(id, iter->second, interpTarget, interpDuration, interpTypeEnum, priority, resume);
EasingType easingTypeEnum = EasingType_Linear; // default value
if (!easingType.isEmpty()) {
easingTypeEnum = stringToEasingType(easingType);
if (easingTypeEnum == EasingType_NumTypes) {
qCCritical(animation) << "AnimNodeLoader, bad easingType on randomSwitch state, nodeId = " << nodeId << "stateId =" << id;
return false;
}
}
auto randomStatePtr = std::make_shared<AnimRandomSwitch::RandomSwitchState>(id, iter->second, interpTarget, interpDuration, interpTypeEnum, easingTypeEnum, priority, resume);
if (priority > 0.0f) {
smNode->addToPrioritySum(priority);
}

View file

@ -54,15 +54,20 @@ const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, const A
if (_children.size() >= 2) {
auto& underPoses = _children[1]->evaluate(animVars, context, dt, triggersOut);
auto& overPoses = _children[0]->overlay(animVars, context, dt, triggersOut, underPoses);
if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) {
_poses.resize(underPoses.size());
assert(_boneSetVec.size() == _poses.size());
if (_alpha == 0.0f) {
_poses = underPoses;
} else {
auto& overPoses = _children[0]->overlay(animVars, context, dt, triggersOut, underPoses);
for (size_t i = 0; i < _poses.size(); i++) {
float alpha = _boneSetVec[i] * _alpha;
::blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]);
if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) {
_poses.resize(underPoses.size());
assert(_boneSetVec.size() == _poses.size());
for (size_t i = 0; i < _poses.size(); i++) {
float alpha = _boneSetVec[i] * _alpha;
::blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]);
}
}
}
}

View file

@ -89,6 +89,7 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
assert(_currentState);
auto currentStateNode = _children[_currentState->getChildIndex()];
auto previousStateNode = _children[_previousState->getChildIndex()];
assert(currentStateNode);
if (_duringInterp) {
@ -97,6 +98,7 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
AnimPoseVec* nextPoses = nullptr;
AnimPoseVec* prevPoses = nullptr;
AnimPoseVec localNextPoses;
AnimPoseVec localPrevPoses;
if (_interpType == InterpType::SnapshotBoth) {
// interp between both snapshots
prevPoses = &_prevPoses;
@ -107,13 +109,18 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
prevPoses = &_prevPoses;
nextPoses = &localNextPoses;
} else if (_interpType == InterpType::EvaluateBoth) {
localPrevPoses = previousStateNode->evaluate(animVars, context, dt, triggersOut);
localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
prevPoses = &localPrevPoses;
nextPoses = &localNextPoses;
} else {
assert(false);
}
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), easingFunc(_alpha, _easingType), &_poses[0]);
}
context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
context.setDebugAlpha(_currentState->getID(), easingFunc(_alpha, _easingType) * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
} else {
_duringInterp = false;
_prevPoses.clear();
@ -160,6 +167,7 @@ void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const A
float duration = std::max(0.001f, animVars.lookup(desiredState->_interpDurationVar, desiredState->_interpDuration));
_alphaVel = FRAMES_PER_SECOND / duration;
_interpType = (InterpType)animVars.lookup(desiredState->_interpTypeVar, (int)desiredState->_interpType);
_easingType = desiredState->_easingType;
// because dt is 0, we should not encounter any triggers
const float dt = 0.0f;

View file

@ -14,6 +14,7 @@
#include <string>
#include <vector>
#include "AnimNode.h"
#include "AnimUtil.h"
// Random Switch State Machine for random transitioning between children AnimNodes
//
@ -51,6 +52,7 @@ public:
enum class InterpType {
SnapshotBoth = 0,
SnapshotPrev,
EvaluateBoth,
NumTypes
};
@ -73,12 +75,13 @@ protected:
RandomSwitchState::Pointer _randomSwitchState;
};
RandomSwitchState(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType, float priority, bool resume) :
RandomSwitchState(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType, EasingType easingType, float priority, bool resume) :
_id(id),
_childIndex(childIndex),
_interpTarget(interpTarget),
_interpDuration(interpDuration),
_interpType(interpType),
_easingType(easingType),
_priority(priority),
_resume(resume){
}
@ -106,6 +109,7 @@ protected:
float _interpTarget; // frames
float _interpDuration; // frames
InterpType _interpType;
EasingType _easingType;
float _priority {0.0f};
bool _resume {false};
@ -154,7 +158,8 @@ protected:
int _randomSwitchEvaluationCount { 0 };
// interpolation state
bool _duringInterp = false;
InterpType _interpType{ InterpType::SnapshotPrev };
InterpType _interpType { InterpType::SnapshotPrev };
EasingType _easingType { EasingType_Linear };
float _alphaVel = 0.0f;
float _alpha = 0.0f;
AnimPoseVec _prevPoses;

View file

@ -48,6 +48,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
assert(_currentState);
auto currentStateNode = _children[_currentState->getChildIndex()];
auto previousStateNode = _children[_previousState->getChildIndex()];
assert(currentStateNode);
if (_duringInterp) {
@ -56,6 +57,8 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
AnimPoseVec* nextPoses = nullptr;
AnimPoseVec* prevPoses = nullptr;
AnimPoseVec localNextPoses;
AnimPoseVec localPrevPoses;
if (_interpType == InterpType::SnapshotBoth) {
// interp between both snapshots
prevPoses = &_prevPoses;
@ -66,13 +69,18 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
prevPoses = &_prevPoses;
nextPoses = &localNextPoses;
} else if (_interpType == InterpType::EvaluateBoth) {
localPrevPoses = previousStateNode->evaluate(animVars, context, dt, triggersOut);
localNextPoses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
prevPoses = &localPrevPoses;
nextPoses = &localNextPoses;
} else {
assert(false);
}
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), easingFunc(_alpha, _easingType), &_poses[0]);
}
context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
context.setDebugAlpha(_currentState->getID(), easingFunc(_alpha, _easingType) * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType());
} else {
_duringInterp = false;
_prevPoses.clear();
@ -95,6 +103,15 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
return _poses;
}
const QString& AnimStateMachine::getCurrentStateID() const {
if (_currentState) {
return _currentState->getID();
} else {
static QString emptyString;
return emptyString;
}
}
void AnimStateMachine::setCurrentState(State::Pointer state) {
_previousState = _currentState ? _currentState : state;
_currentState = state;
@ -116,6 +133,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon
float duration = std::max(0.001f, animVars.lookup(desiredState->_interpDurationVar, desiredState->_interpDuration));
_alphaVel = FRAMES_PER_SECOND / duration;
_interpType = (InterpType)animVars.lookup(desiredState->_interpTypeVar, (int)desiredState->_interpType);
_easingType = desiredState->_easingType;
// because dt is 0, we should not encounter any triggers
const float dt = 0.0f;

View file

@ -14,6 +14,7 @@
#include <string>
#include <vector>
#include "AnimNode.h"
#include "AnimUtil.h"
// State Machine for transitioning between children AnimNodes
//
@ -47,6 +48,7 @@ public:
enum class InterpType {
SnapshotBoth = 0,
SnapshotPrev,
EvaluateBoth,
NumTypes
};
@ -69,12 +71,13 @@ protected:
State::Pointer _state;
};
State(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType) :
State(const QString& id, int childIndex, float interpTarget, float interpDuration, InterpType interpType, EasingType easingType) :
_id(id),
_childIndex(childIndex),
_interpTarget(interpTarget),
_interpDuration(interpDuration),
_interpType(interpType) {}
_interpType(interpType),
_easingType(easingType) {}
void setInterpTargetVar(const QString& interpTargetVar) { _interpTargetVar = interpTargetVar; }
void setInterpDurationVar(const QString& interpDurationVar) { _interpDurationVar = interpDurationVar; }
@ -95,6 +98,7 @@ protected:
float _interpTarget; // frames
float _interpDuration; // frames
InterpType _interpType;
EasingType _easingType;
QString _interpTargetVar;
QString _interpDurationVar;
@ -116,6 +120,7 @@ public:
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override;
void setCurrentStateVar(QString& currentStateVar) { _currentStateVar = currentStateVar; }
const QString& getCurrentStateID() const;
protected:
@ -134,6 +139,7 @@ protected:
// interpolation state
bool _duringInterp = false;
InterpType _interpType { InterpType::SnapshotPrev };
EasingType _easingType { EasingType_Linear };
float _alphaVel = 0.0f;
float _alpha = 0.0f;
AnimPoseVec _prevPoses;

View file

@ -211,3 +211,86 @@ bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& shapePose
return true;
}
}
// See https://easings.net/en# for a graphical visualiztion of easing types.
float easingFunc(float alpha, EasingType type) {
switch (type) {
case EasingType_Linear:
return alpha;
case EasingType_EaseInSine:
return sinf((alpha - 1.0f) * PI_OVER_TWO) + 1.0f;
case EasingType_EaseOutSine:
return sinf(alpha * PI_OVER_TWO);
case EasingType_EaseInOutSine:
return 0.5f * (1.0f - cosf(alpha * PI));
case EasingType_EaseInQuad:
return alpha * alpha;
case EasingType_EaseOutQuad:
return -(alpha * (alpha - 2.0f));
case EasingType_EaseInOutQuad:
return (alpha < 0.5f) ? (2.0f * alpha * alpha) : ((-2.0f * alpha * alpha) + (4.0f * alpha) - 1.0f);
case EasingType_EaseInCubic:
return alpha * alpha * alpha;
case EasingType_EaseOutCubic: {
float temp = alpha - 1.0f;
return temp * temp * temp + 1.0f;
}
case EasingType_EaseInOutCubic:
if (alpha < 0.5f) {
return 4.0f * alpha * alpha * alpha;
} else {
float temp = ((2.0f * alpha) - 2.0f);
return 0.5f * temp * temp * temp + 1.0f;
}
case EasingType_EaseInQuart:
return alpha * alpha * alpha * alpha;
case EasingType_EaseOutQuart: {
float temp = alpha - 1.0f;
return temp * temp * temp * (1.0f - alpha) + 1.0f;
}
case EasingType_EaseInOutQuart:
if (alpha < 0.5f) {
return 8.0f * alpha * alpha * alpha * alpha;
} else {
float temp = alpha - 1.0f;
return -8.0f * temp * temp * temp * temp + 1.0f;
}
case EasingType_EaseInQuint:
return alpha * alpha * alpha * alpha * alpha;
case EasingType_EaseOutQuint: {
float temp = (alpha - 1.0f);
return temp * temp * temp * temp * temp + 1.0f;
}
case EasingType_EaseInOutQuint:
if (alpha < 0.5f) {
return 16.0f * alpha * alpha * alpha * alpha * alpha;
} else {
float temp = ((2.0f * alpha) - 2.0f);
return 0.5f * temp * temp * temp * temp * temp + 1.0f;
}
case EasingType_EaseInExpo:
return (alpha == 0.0f) ? alpha : powf(2.0f, 10.0f * (alpha - 1.0f));
case EasingType_EaseOutExpo:
return (alpha == 1.0f) ? alpha : 1.0f - powf(2.0f, -10.0f * alpha);
case EasingType_EaseInOutExpo:
if (alpha == 0.0f || alpha == 1.0f)
return alpha;
else if (alpha < 0.5f) {
return 0.5f * powf(2.0f, (20.0f * alpha) - 10.0f);
} else {
return -0.5f * powf(2.0f, (-20.0f * alpha) + 10.0f) + 1.0f;
}
case EasingType_EaseInCirc:
return 1.0f - sqrtf(1.0f - (alpha * alpha));
case EasingType_EaseOutCirc:
return sqrtf((2.0f - alpha) * alpha);
case EasingType_EaseInOutCirc:
if (alpha < 0.5f) {
return 0.5f * (1.0f - sqrtf(1.0f - 4.0f * (alpha * alpha)));
} else {
return 0.5f * (sqrtf(-((2.0f * alpha) - 3.0f) * ((2.0f * alpha) - 1.0f)) + 1.0f);
}
default:
return alpha;
}
}

View file

@ -128,10 +128,37 @@ protected:
bool _snapshotValid { false };
};
// returns true if the given point lies inside of the k-dop, specified by shapeInfo & shapePose.
// if the given point does lie within the k-dop, it also returns the amount of displacement necessary to push that point outward
// such that it lies on the surface of the kdop.
bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& shapePose, const HFMJointShapeInfo& shapeInfo, glm::vec3& displacementOut);
enum EasingType {
EasingType_Linear,
EasingType_EaseInSine,
EasingType_EaseOutSine,
EasingType_EaseInOutSine,
EasingType_EaseInQuad,
EasingType_EaseOutQuad,
EasingType_EaseInOutQuad,
EasingType_EaseInCubic,
EasingType_EaseOutCubic,
EasingType_EaseInOutCubic,
EasingType_EaseInQuart,
EasingType_EaseOutQuart,
EasingType_EaseInOutQuart,
EasingType_EaseInQuint,
EasingType_EaseOutQuint,
EasingType_EaseInOutQuint,
EasingType_EaseInExpo,
EasingType_EaseOutExpo,
EasingType_EaseInOutExpo,
EasingType_EaseInCirc,
EasingType_EaseOutCirc,
EasingType_EaseInOutCirc,
EasingType_NumTypes
};
float easingFunc(float alpha, EasingType type);
#endif

View file

@ -29,6 +29,7 @@
#include "AnimInverseKinematics.h"
#include "AnimOverlay.h"
#include "AnimSkeleton.h"
#include "AnimStateMachine.h"
#include "AnimUtil.h"
#include "AvatarConstants.h"
#include "IKTarget.h"
@ -1906,28 +1907,7 @@ void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabl
void Rig::updateReactions(const ControllerParameters& params) {
// enable/disable animVars
bool enabled = params.reactionEnabledFlags[AVATAR_REACTION_POSITIVE];
_animVars.set("reactionPositiveEnabled", enabled);
_animVars.set("reactionPositiveDisabled", !enabled);
enabled = params.reactionEnabledFlags[AVATAR_REACTION_NEGATIVE];
_animVars.set("reactionNegativeEnabled", enabled);
_animVars.set("reactionNegativeDisabled", !enabled);
enabled = params.reactionEnabledFlags[AVATAR_REACTION_RAISE_HAND];
_animVars.set("reactionRaiseHandEnabled", enabled);
_animVars.set("reactionRaiseHandDisabled", !enabled);
enabled = params.reactionEnabledFlags[AVATAR_REACTION_APPLAUD];
_animVars.set("reactionApplaudEnabled", enabled);
_animVars.set("reactionApplaudDisabled", !enabled);
enabled = params.reactionEnabledFlags[AVATAR_REACTION_POINT];
_animVars.set("reactionPointEnabled", enabled);
_animVars.set("reactionPointDisabled", !enabled);
// trigger animVars
// trigger reactions
if (params.reactionTriggers[AVATAR_REACTION_POSITIVE]) {
_animVars.set("reactionPositiveTrigger", true);
} else {
@ -1940,22 +1920,38 @@ void Rig::updateReactions(const ControllerParameters& params) {
_animVars.set("reactionNegativeTrigger", false);
}
if (params.reactionTriggers[AVATAR_REACTION_RAISE_HAND]) {
_animVars.set("reactionRaiseHandTrigger", true);
} else {
_animVars.set("reactionRaiseHandTrigger", false);
}
// begin end reactions
bool enabled = params.reactionEnabledFlags[AVATAR_REACTION_RAISE_HAND];
_animVars.set("reactionRaiseHandEnabled", enabled);
_animVars.set("reactionRaiseHandDisabled", !enabled);
if (params.reactionTriggers[AVATAR_REACTION_APPLAUD]) {
_animVars.set("reactionApplaudTrigger", true);
} else {
_animVars.set("reactionApplaudTrigger", false);
}
enabled = params.reactionEnabledFlags[AVATAR_REACTION_APPLAUD];
_animVars.set("reactionApplaudEnabled", enabled);
_animVars.set("reactionApplaudDisabled", !enabled);
if (params.reactionTriggers[AVATAR_REACTION_POINT]) {
_animVars.set("reactionPointTrigger", true);
} else {
_animVars.set("reactionPointTrigger", false);
enabled = params.reactionEnabledFlags[AVATAR_REACTION_POINT];
_animVars.set("reactionPointEnabled", enabled);
_animVars.set("reactionPointDisabled", !enabled);
// determine if we should ramp off IK
if (_enableInverseKinematics) {
bool reactionPlaying = false;
std::shared_ptr<AnimStateMachine> mainStateMachine = std::dynamic_pointer_cast<AnimStateMachine>(_animNode->findByName("mainStateMachine"));
std::shared_ptr<AnimStateMachine> idleStateMachine = std::dynamic_pointer_cast<AnimStateMachine>(_animNode->findByName("idle"));
if (mainStateMachine && mainStateMachine->getCurrentStateID() == "idle" && idleStateMachine) {
reactionPlaying = idleStateMachine->getCurrentStateID().startsWith("reaction");
}
bool isSeated = _state == RigRole::Seated;
bool hipsEnabled = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Enabled;
bool hipsEstimated = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Estimated;
bool hmdMode = hipsEnabled && !hipsEstimated;
if ((reactionPlaying || isSeated) && !hmdMode) {
// TODO: make this smooth.
// disable head IK while reaction is playing, but only in "desktop" mode.
_animVars.set("headType", (int)IKTarget::Type::Unknown);
}
}
}
@ -2115,9 +2111,9 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
_talkIdleInterpTime = 1.0f;
}
float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
_animVars.set("idleOverlayAlpha", easeOutInValue);
_animVars.set("talkOverlayAlpha", easeOutInValue);
} else {
_animVars.set("idleOverlayAlpha", 1.0f);
_animVars.set("talkOverlayAlpha", 1.0f);
}
} else {
if (_talkIdleInterpTime < 1.0f) {
@ -2127,9 +2123,9 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
}
float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
float talkAlpha = 1.0f - easeOutInValue;
_animVars.set("idleOverlayAlpha", talkAlpha);
_animVars.set("talkOverlayAlpha", talkAlpha);
} else {
_animVars.set("idleOverlayAlpha", 0.0f);
_animVars.set("talkOverlayAlpha", 0.0f);
}
}

View file

@ -88,8 +88,8 @@ public:
AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space
uint8_t secondaryControllerFlags[NumSecondaryControllerTypes];
bool isTalking;
bool reactionEnabledFlags[NUM_AVATAR_REACTIONS];
bool reactionTriggers[NUM_AVATAR_REACTIONS];
bool reactionEnabledFlags[NUM_AVATAR_BEGIN_END_REACTIONS];
bool reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS];
HFMJointShapeInfo hipsShapeInfo;
HFMJointShapeInfo spineShapeInfo;
HFMJointShapeInfo spine1ShapeInfo;

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 9/5/2018
// Created by Sabrina Shanman 2018/09/05
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -10,4 +10,4 @@
template<>
glm::vec3 BaseNestableTransformNode<Avatar>::getActualScale(const std::shared_ptr<Avatar>& nestablePointer) const {
return nestablePointer->scaleForChildren();
}
}

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 9/5/2018
// Created by Sabrina Shanman 2018/09/05
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -17,4 +17,4 @@ public:
AvatarTransformNode(std::weak_ptr<Avatar> spatiallyNestable, int jointIndex) : BaseNestableTransformNode(spatiallyNestable, jointIndex) {};
};
#endif // hifi_AvatarTransformNode_h
#endif // hifi_AvatarTransformNode_h

View file

@ -2860,7 +2860,8 @@ glm::vec3 AvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const
/**jsdoc
* Information on an attachment worn by the avatar.
* @typedef {object} AttachmentData
* @property {string} modelUrl - The URL of the model file. Models can be FBX or OBJ format.
* @property {string} modelUrl - The URL of the glTF, FBX, or OBJ model file. glTF models may be in JSON or binary format
* (".gltf" or ".glb" URLs respectively).
* @property {string} jointName - The name of the joint that the attachment is parented to.
* @property {Vec3} translation - The offset from the joint that the attachment is positioned at.
* @property {Vec3} rotation - The rotation applied to the model relative to the joint orientation.

View file

@ -117,8 +117,7 @@ const int COLLIDE_WITH_OTHER_AVATARS = 11; // 12th bit
const int HAS_HERO_PRIORITY = 12; // 13th bit (be scared)
/**jsdoc
* <p>The pointing state of the hands is specified by the following values:
</p>
* <p>The pointing state of the hands is specified by the following values:</p>
* <table>
* <thead>
* <tr><th>Value</th><th>Description</th>
@ -1268,12 +1267,11 @@ public:
/**jsdoc
* Attaches a model to your avatar. For example, you can give your avatar a hat to wear, a guitar to hold, or a surfboard to
* stand on.
* <p>Note: Attached models are models only; they are not entities and can not be manipulated using the {@link Entities} API.
* Nor can you use this function to attach an entity (such as a sphere or a box) to your avatar.</p>
* @function Avatar.attach
* @param {string} modelURL - The URL of the model to attach. Models can be .FBX or .OBJ format.
* @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames} or {@link Avatar.getJointNames}) to attach the model
* to.
* @param {string} modelURL - The URL of the glTF, FBX, or OBJ model to attach. glTF models may be in JSON or binary format
* (".gltf" or ".glb" URLs respectively).
* @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames} or
* {@link Avatar.getJointNames}) to attach the model to.
* @param {Vec3} [translation=Vec3.ZERO] - The offset to apply to the model relative to the joint position.
* @param {Quat} [rotation=Quat.IDENTITY] - The rotation to apply to the model relative to the joint orientation.
* @param {number} [scale=1.0] - The scale to apply to the model.

View file

@ -1027,6 +1027,10 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
void EntityTreeRenderer::entityScriptChanging(const EntityItemID& entityID, bool reload) {
checkAndCallPreload(entityID, reload, true);
// Force "re-checking" entities so that the logic inside `checkEnterLeaveEntities()` is run.
// This will ensure that the `enterEntity()` signal is emitted on clients whose avatars
// are inside an entity when the script is reloaded.
forceRecheckEntities();
}
void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool reload, bool unloadFirst) {

View file

@ -50,8 +50,10 @@ bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b
/**jsdoc
* An animation is configured by the following properties:
* @typedef {object} Entities.AnimationProperties
* @property {string} url="" - The URL of the FBX file that has the animation.
* @property {boolean} allowTranslation=true - <code>true</code> to enable translations contained in the animation to be
* @property {string} url="" - The URL of the glTF or FBX file that has the animation. glTF files may be in JSON or binary
* format (".gltf" or ".glb" URLs respectively).
* <p><strong>Warning:</strong> glTF animations currently do not always animate correctly.</p>
* @property {boolean} allowTranslation=true - <code>true</code> to enable translations contained in the animation to be
* played, <code>false</code> to disable translations.
* @property {number} fps=30 - The speed in frames/s that the animation is played at.
* @property {number} firstFrame=0 - The first frame to play in the animation.

View file

@ -980,8 +980,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
* value is specified then the model is automatically sized to its
* <code>{@link Entities.EntityProperties|naturalDimensions}</code>.
* @property {string} modelURL="" - The URL of the glTF, FBX, or OBJ model. glTF models may be in JSON or binary format
* (".gltf" or ".glb" URLs respectively). Baked FBX models' URLs end in ".baked.fbx". Model files may also be compressed in GZ
* format, in which case the URL ends in ".gz".
* (".gltf" or ".glb" URLs respectively). Baked models' URLs have ".baked" before the file type. Model files may also be
* compressed in GZ format, in which case the URL ends in ".gz".
* @property {Vec3} modelScale - The scale factor applied to the model's dimensions.
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
* @property {string} textures="" - A JSON string of texture name, URL pairs used when rendering the model in place of the
@ -1307,11 +1307,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
* @property {number} rightMargin=0.0 - The right margin, in meters.
* @property {number} topMargin=0.0 - The top margin, in meters.
* @property {number} bottomMargin=0.0 - The bottom margin, in meters.
* @property {boolean} unlit=false - <code>true</code> if the entity should be unaffected by lighting. Otherwise, the text
* is lit by the keylight and local lights.
* @property {string} font="" - The text is rendered with this font. 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 {TextEffect} textEffect="none" - The effect that is applied to the text.
* @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,
* <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.
* @property {number} textEffectThickness=0.2 - The magnitude of the text effect, range <code>0.0</code> &ndash; <code>0.5</code>.
* @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera.

View file

@ -59,7 +59,7 @@ public:
* <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>.
* <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>
* <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>
* <tr><td><code>"Text"</code></td><td>A pane of text oriented in space.</td>
* <td>{@link Entities.EntityProperties-Text|EntityProperties-Text}</td></tr>

View file

@ -37,10 +37,10 @@ class ReadBitstreamToTreeParams;
* are cast by avatars, plus {@link Entities.EntityProperties-Model|Model} and
* {@link Entities.EntityProperties-Shape|Shape} entities that have their
* <code>{@link Entities.EntityProperties|canCastShadow}</code> property set to <code>true</code>.
* @property {number} shadowBias=0.5 - The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene
* to prevent shadow acne and peter panning. In the range <code>0.0</code> &ndash; <code>1.0</code>.
* @property {number} shadowMaxDistance=40.0 - The max distance from your view at which shadows will be computed. Higher values will
* cover more of your scene, but with less precision. In the range <code>1.0</code> &ndash; <code>250.0</code>.
* @property {number} shadowBias=0.5 - The bias of the shadows cast by the light, range <code>0.0</code> &ndash;
* <code>1.0</code>. This fine-tunes shadows cast by the light, to prevent shadow acne and peter panning.
* @property {number} shadowMaxDistance=40.0 - The maximum distance from the camera position at which shadows will be computed,
* range <code>1.0</code> &ndash; <code>250.0</code>. Higher values cover more of the scene but with less precision.
*/
class KeyLightPropertyGroup : public PropertyGroup {
public:

View file

@ -297,10 +297,6 @@ MeshPointer GraphicsScriptingInterface::getMeshPointer(scriptable::ScriptableMes
namespace {
QVector<int> metaTypeIds{
qRegisterMetaType<glm::uint32>("uint32"),
qRegisterMetaType<glm::uint32>("glm::uint32"),
qRegisterMetaType<QVector<glm::uint32>>(),
qRegisterMetaType<QVector<glm::uint32>>("QVector<uint32>"),
qRegisterMetaType<scriptable::ScriptableMeshes>(),
qRegisterMetaType<scriptable::ScriptableMeshes>("ScriptableMeshes"),
qRegisterMetaType<scriptable::ScriptableMeshes>("scriptable::ScriptableMeshes"),
@ -532,7 +528,6 @@ namespace scriptable {
}
void GraphicsScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
qScriptRegisterSequenceMetaType<QVector<glm::uint32>>(engine);
qScriptRegisterSequenceMetaType<QVector<scriptable::ScriptableMaterialLayer>>(engine);
scriptable::registerQPointerMetaType<scriptable::ScriptableModel>(engine);

View file

@ -19,6 +19,7 @@
#include "ScriptableMesh.h"
#include <DependencyManager.h>
#include "RegisteredMetaTypes.h"
/**jsdoc
@ -107,8 +108,6 @@ namespace scriptable {
QScriptValue scriptableMaterialToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterial &material);
};
Q_DECLARE_METATYPE(glm::uint32)
Q_DECLARE_METATYPE(QVector<glm::uint32>)
Q_DECLARE_METATYPE(NestableType)
#endif // hifi_GraphicsScriptingInterface_h

View file

@ -120,7 +120,8 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
* @property {number|string} opacity=1.0 - The opacity, range <code>0.0</code> &ndash; <code>1.0</code>.
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
* @property {boolean|string} unlit=false - <code>true</code> if the material is not lit, <code>false</code> if it is.
* @property {boolean|string} unlit=false - <code>true</code> if the material is unaffected by lighting, <code>false</code> if
* it is lit by the key light and local lights.
* Set to <code>"fallthrough"</code> to fall through to the material below. <code>"hifi_pbr"</code> model only.
* @property {ColorFloat|RGBS|string} albedo - The albedo color. A {@link ColorFloat} value is treated as sRGB and must have
* component values in the range <code>0.0</code> &ndash; <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.

View file

@ -83,6 +83,7 @@ public:
bool isPartOfMessage() const { return _isPartOfMessage; }
bool isReliable() const { return _isReliable; }
void setReliable(bool reliable) { _isReliable = reliable; }
ObfuscationLevel getObfuscationLevel() const { return _obfuscationLevel; }
SequenceNumber getSequenceNumber() const { return _sequenceNumber; }

View file

@ -82,7 +82,7 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
void OctreeQueryNode::init() {
_myPacketType = getMyPacketType();
_octreePacket = NLPacket::create(getMyPacketType());
_octreePacket = NLPacket::create(getMyPacketType(), -1, true);
resetOctreePacket(); // don't bump sequence
}

View file

@ -169,7 +169,7 @@ private:
bool _isReadyToSend;
std::unique_ptr<NLPacket> _statsPacket = NLPacket::create(PacketType::OctreeStats);
std::unique_ptr<NLPacket> _statsPacket = NLPacket::create(PacketType::OctreeStats, -1, true);
// scene timing data in usecs
bool _isStarted;

View file

@ -10,19 +10,52 @@
#include "../Platform.h"
#include "../PlatformKeys.h"
/**jsdoc
* Information on the computer platform as a whole.
* @typedef {object} PlatformInfo.PlatformDescription
* @property {PlatformInfo.ComputerDescription} computer - Information on the computer.
* @property {PlatformInfo.CPUDescription[]} cpus - Information on the computer's CPUs.
* @property {PlatformInfo.DisplayDescription[]} displays - Information on the computer's displays.
* @property {PlatformInfo.GPUDescription[]} gpus - Information on the computer's GPUs.
* @property {PlatformInfo.GraphicsAPIDescription[]} graphicsAPIs - Information on the computer's graphics APIs.
* @property {PlatformInfo.MemoryDescription} memory - Information on the computer's memory.
* @property {PlatformInfo.NICDescription} nics - Information on the computer's network cards.
*/
namespace platform { namespace keys {
const char* UNKNOWN = "UNKNOWN";
/**jsdoc
* Information on a CPU.
* @typedef {object} PlatformInfo.CPUDescription
* @property {string} vendor - The CPU vendor (e.g., <code>"Intel"</code> or <code>"AMD"</code>).
* @property {string} model - The CPU model.
* @property {number} numCores - The number of logical cores.
* @property {boolean} isMaster - <code>true</code> if the CPU is the "master" or primary CPU, <code>false</code> or
* <code>undefined</code> if it isn't.
*/
namespace cpu {
const char* vendor = "vendor";
const char* vendor_Intel = "Intel";
const char* vendor_AMD = "AMD";
const char* model = "model";
const char* clockSpeed = "clockSpeed";
const char* clockSpeed = "clockSpeed"; // FIXME: Not used.
const char* numCores = "numCores";
const char* isMaster = "isMaster";
}
/**jsdoc
* Information on a GPU.
* @typedef {object} PlatformInfo.GPUDescription
* @property {string} vendor - The GPU vendor (e.g., <code>"NVIDIA"</code>, <code>"AMD"</code>, or <code>"Intel"</code>).
* @property {string} model - The GPU model.
* @property {string} driver - The GPU driver version.
* @property {number} videoMemory - The size of the GPU's video memory, in MB.
* @property {number[]} displays - The index numbers of the displays currently being driven by the GPU. An empty array if
* the GPU is currently not driving any displays.
* @property {boolean} isMaster - <code>true</code> if the GPU is the "master" or primary GPU, <code>false</code> or
* <code>undefined</code> if it isn't.
*/
namespace gpu {
const char* vendor = "vendor";
const char* vendor_NVIDIA = "NVIDIA";
@ -35,6 +68,45 @@ namespace platform { namespace keys {
const char* displays = "displays";
const char* isMaster = "isMaster";
}
/**jsdoc
* Information on a graphics API.
* @typedef {object} PlatformInfo.GraphicsAPIDescription
* @property {string} name - The name of the graphics API.
* @property {string} version - The version of the graphics API.
*
* @property {string} [renderer] - If an OpenGL API, then the graphics card that performs the rendering.
* @property {string} [vendor] - If an OpenGL API, then the OpenGL vendor.
* @property {string} [shadingLanguageVersion] - If an OpenGL API, then the shading language version.
* @property {string[]} [extensions] - If an OpenGL API, then the list of OpenGL extensions supported.
*
* @property {PlatformInfo.VulkanAPIDescription[]} [devices] - If a Vulkan API, then the devices provided in the API.
*/
/**jsdoc
* Information on a Vulkan graphics API.
* @typedef {object} PlatformInfo.VulkanAPIDescription
* @property {string}
* @property {string} driverVersion - The driver version.
* @property {string} apiVersion - The API version.
* @property {string} deviceType - The device type.
* @property {string} vendor - The device vendor.
* @property {string} name - The device name.
* @property {string[]} extensions - The list of Vulkan extensions supported.
* @property {PlatformInfo.VulkanQueueDescription[]} queues - The Vulkan queues available.
* @property {PlatformInfo.VulkanHeapDescription[]} heaps - The Vulkan heaps available.
*/
/**jsdoc
* Information on a Vulkan queue.
* @typedef {object} PlatformInfo.VulkanQueueDescription
* @property {string} flags - The Vulkan queue flags.
* @property {number} count - The queue count.
*/
/**jsdoc
* Information on a Vulkan heap.
* @typedef {object} PlatformInfo.VulkanHeapDescription
* @property {string} flags - The Vulkan heap flags.
* @property {number} size - The heap size.
*/
namespace graphicsAPI {
const char* name = "name";
const char* version = "version";
@ -74,10 +146,38 @@ namespace platform { namespace keys {
}
}
}
/**jsdoc
* Information on a network card.
* @typedef {object} PlatformInfo.NICDescription
* @property {string} name - The name of the network card.
* @property {string} mac - The MAC address of the network card.
*/
namespace nic {
const char* mac = "mac";
const char* name = "name";
}
/**jsdoc
* Information on a display.
* @typedef {object} PlatformInfo.DisplayDescription
* @property {string} description - The display's description.
* @property {string} deviceName - The display's device name.
* @property {number} boundsLeft - The pixel coordinate of the left edge of the display (e.g., <code>0</code>).
* @property {number} boundsRight - The pixel coordinate of the right edge of the display (e.g., <code>1920</code>).
* @property {number} boundsTop - The pixel coordinate of the top edge of the display (e.g., <code>0</code>).
* @property {number} boundsBottom - The pixel coordinate of the bottom edge of the display (e.g., <code>1080</code>).
* @property {number} gpu - The index number of the GPU that's driving the display.
* @property {number} ppi - The physical dots per inch of the display.
* @property {number} ppiDesktop - The logical dots per inch of the desktop as used by the operating system.
* @property {number} physicalWidth - The physical width of the display, in inches.
* @property {number} physicalHeight - The physical height of the display, in inches.
* @property {number} modeRefreshrate - The refresh rate of the current display mode, in Hz.
* @property {number} modeWidth - The width of the current display mode, in pixels.
* @property {number} modeHeight - The height of the current display mode, in pixels.
* @property {boolean} isMaster - <code>true</code> if the GPU is the "master" or primary display, <code>false</code> or
* <code>undefined</code> if it isn't.
*/
namespace display {
const char* description = "description";
const char* name = "deviceName";
@ -95,9 +195,40 @@ namespace platform { namespace keys {
const char* modeHeight = "modeHeight";
const char* isMaster = "isMaster";
}
/**jsdoc
* Information on the computer's memory.
* @typedef {object} PlatformInfo.MemoryDescription
* @property {number} memTotal - The total amount of usable physical memory, in MB.
*/
namespace memory {
const char* memTotal = "memTotal";
}
/**jsdoc
* Information on the computer.
* @typedef {object} PlatformInfo.ComputerDescription
* @property {PlatformInfo.ComputerOS} OS - The operating system.
* @property {string} OSversion - The operating system version.
* @property {string} vendor - The computer vendor.
* @property {string} model - The computer model.
* @property {PlatformInfo.PlatformTier} profileTier - The platform tier of the computer, profiled at Interface start-up.
*/
/**jsdoc
* <p>The computer operating system.</p>
* <table>
* <thead>
* <tr><th>Value</th><th>Description</th></tr>
* </thead>
* <tbody>
* <tr><td><code>"WINDOWS"</code></td><td>Windows.</td></tr>
* <tr><td><code>"MACOS"</code></td><td>Mac OS.</td></tr>
* <tr><td><code>"LINUX"</code></td><td>Linux.</td></tr>
* <tr><td><code>"ANDROID"</code></td><td>Android.</td></tr>
* </tbody>
* </table>
* @typedef {string} PlatformInfo.ComputerOS
*/
namespace computer {
const char* OS = "OS";
const char* OS_WINDOWS = "WINDOWS";

View file

@ -56,6 +56,14 @@ QVector<QUuid> PickQuery::getIgnoreItems() const {
});
}
void PickQuery::setScriptParameters(const QVariantMap& parameters) {
_scriptParameters = parameters;
}
QVariantMap PickQuery::getScriptParameters() const {
return _scriptParameters;
}
QVector<QUuid> PickQuery::getIncludeItems() const {
return resultWithReadLock<QVector<QUuid>>([&] {
return _includeItems;

View file

@ -117,7 +117,8 @@ public:
Stylus,
Parabola,
Collision,
NUM_PICK_TYPES
NUM_PICK_TYPES,
INVALID_PICK_TYPE = -1
};
Q_ENUM(PickType)
@ -134,6 +135,7 @@ public:
PickFilter getFilter() const;
float getMaxDistance() const;
bool isEnabled() const;
virtual PickType getType() const = 0;
void setPrecisionPicking(bool precisionPicking);
@ -168,6 +170,27 @@ public:
void setIgnoreItems(const QVector<QUuid>& items);
void setIncludeItems(const QVector<QUuid>& items);
virtual QVariantMap toVariantMap() const {
QVariantMap properties;
properties["pickType"] = (int)getType();
properties["enabled"] = isEnabled();
properties["filter"] = (unsigned int)getFilter()._flags.to_ulong();
properties["maxDistance"] = getMaxDistance();
if (parentTransform) {
auto transformNodeProperties = parentTransform->toVariantMap();
for (auto it = transformNodeProperties.cbegin(); it != transformNodeProperties.cend(); ++it) {
properties[it.key()] = it.value();
}
}
return properties;
}
void setScriptParameters(const QVariantMap& parameters);
QVariantMap getScriptParameters() const;
virtual bool isLeftHand() const { return _jointState == JOINT_STATE_LEFT_HAND; }
virtual bool isRightHand() const { return _jointState == JOINT_STATE_RIGHT_HAND; }
virtual bool isMouse() const { return _jointState == JOINT_STATE_MOUSE; }
@ -187,6 +210,9 @@ private:
QVector<QUuid> _ignoreItems;
QVector<QUuid> _includeItems;
// The parameters used to create this pick when created through a script
QVariantMap _scriptParameters;
JointState _jointState { JOINT_STATE_NONE };
};
Q_DECLARE_METATYPE(PickQuery::PickType)
@ -202,6 +228,17 @@ public:
virtual PickResultPointer getAvatarIntersection(const T& pick) = 0;
virtual PickResultPointer getHUDIntersection(const T& pick) = 0;
QVariantMap toVariantMap() const override {
QVariantMap properties = PickQuery::toVariantMap();
const QVariantMap mathPickProperties = _mathPick.toVariantMap();
for (auto it = mathPickProperties.cbegin(); it != mathPickProperties.cend(); ++it) {
properties[it.key()] = it.value();
}
return properties;
}
protected:
T _mathPick;
};

View file

@ -49,6 +49,35 @@ void PickManager::removePick(unsigned int uid) {
});
}
QVariantMap PickManager::getPickProperties(unsigned int uid) const {
auto pick = findPick(uid);
if (pick) {
return pick->toVariantMap();
}
return QVariantMap();
}
QVariantMap PickManager::getPickScriptParameters(unsigned int uid) const {
auto pick = findPick(uid);
if (pick) {
return pick->getScriptParameters();
}
return QVariantMap();
}
QVector<unsigned int> PickManager::getPicks() const {
QVector<unsigned int> picks;
withReadLock([&] {
for (auto typeIt = _picks.cbegin(); typeIt != _picks.cend(); ++typeIt) {
auto& picksForType = typeIt->second;
for (auto pickIt = picksForType.cbegin(); pickIt != picksForType.cend(); ++pickIt) {
picks.push_back(pickIt->first);
}
}
});
return picks;
}
PickResultPointer PickManager::getPrevPickResult(unsigned int uid) const {
auto pick = findPick(uid);
if (pick) {
@ -71,6 +100,14 @@ void PickManager::disablePick(unsigned int uid) const {
}
}
bool PickManager::isPickEnabled(unsigned int uid) const {
auto pick = findPick(uid);
if (pick) {
return pick->isEnabled();
}
return false;
}
void PickManager::setPrecisionPicking(unsigned int uid, bool precisionPicking) const {
auto pick = findPick(uid);
if (pick) {

View file

@ -31,8 +31,14 @@ public:
void removePick(unsigned int uid);
void enablePick(unsigned int uid) const;
void disablePick(unsigned int uid) const;
bool isPickEnabled(unsigned int uid) const;
QVector<unsigned int> getPicks() const;
PickResultPointer getPrevPickResult(unsigned int uid) const;
// The actual current properties of the pick
QVariantMap getPickProperties(unsigned int uid) const;
// The properties that were passed in to create the pick (may be empty if the pick was created by invoking the constructor)
QVariantMap getPickScriptParameters(unsigned int uid) const;
template <typename T>
std::shared_ptr<T> getPrevPickResultTyped(unsigned int uid) const {

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/22/2018
// Created by Sabrina Shanman 2018/08/22
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -23,4 +23,10 @@ Transform PickTransformNode::getTransform() {
}
return pickManager->getResultTransform(_uid);
}
}
QVariantMap PickTransformNode::toVariantMap() const {
QVariantMap map;
map["parentID"] = _uid;
return map;
}

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/22/2018
// Created by Sabrina Shanman 2018/08/22
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -15,9 +15,10 @@ class PickTransformNode : public TransformNode {
public:
PickTransformNode(unsigned int uid);
Transform getTransform() override;
QVariantMap toVariantMap() const override;
protected:
unsigned int _uid;
};
#endif // hifi_PickTransformNode_h
#endif // hifi_PickTransformNode_h

View file

@ -36,10 +36,32 @@ void Pointer::disable() {
DependencyManager::get<PickManager>()->disablePick(_pickUID);
}
bool Pointer::isEnabled() {
return _enabled;
}
PickResultPointer Pointer::getPrevPickResult() {
return DependencyManager::get<PickManager>()->getPrevPickResult(_pickUID);
}
QVariantMap Pointer::toVariantMap() const {
QVariantMap qVariantMap = DependencyManager::get<PickManager>()->getPickProperties(_pickUID);
qVariantMap["pointerType"] = getType();
qVariantMap["pickID"] = _pickUID;
qVariantMap["hover"] = _hover;
return qVariantMap;
}
void Pointer::setScriptParameters(const QVariantMap& scriptParameters) {
_scriptParameters = scriptParameters;
}
QVariantMap Pointer::getScriptParameters() const {
return _scriptParameters;
}
void Pointer::setPrecisionPicking(bool precisionPicking) {
DependencyManager::get<PickManager>()->setPrecisionPicking(_pickUID, precisionPicking);
}

View file

@ -45,12 +45,16 @@ public:
virtual void enable();
virtual void disable();
virtual bool isEnabled();
virtual PickQuery::PickType getType() const = 0;
virtual PickResultPointer getPrevPickResult();
virtual void setRenderState(const std::string& state) = 0;
virtual void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) = 0;
virtual QVariantMap toVariantMap() const = 0;
virtual QVariantMap toVariantMap() const;
virtual void setScriptParameters(const QVariantMap& scriptParameters);
virtual QVariantMap getScriptParameters() const;
virtual void setPrecisionPicking(bool precisionPicking);
virtual void setIgnoreItems(const QVector<QUuid>& ignoreItems) const;
@ -84,6 +88,9 @@ protected:
bool _enabled;
bool _hover;
// The parameters used to create this pointer when created through a script
QVariantMap _scriptParameters;
virtual PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, const std::string& button = "", bool hover = true) = 0;
virtual PickedObject getHoveredObject(const PickResultPointer& pickResult) = 0;

View file

@ -54,6 +54,24 @@ void PointerManager::disablePointer(unsigned int uid) const {
}
}
bool PointerManager::isPointerEnabled(unsigned int uid) const {
auto pointer = find(uid);
if (pointer) {
return pointer->isEnabled();
}
return false;
}
QVector<unsigned int> PointerManager::getPointers() const {
QVector<unsigned int> pointers;
withReadLock([&] {
for (auto it = _pointers.cbegin(); it != _pointers.cend(); ++it) {
pointers.push_back(it->first);
}
});
return pointers;
}
void PointerManager::setRenderState(unsigned int uid, const std::string& renderState) const {
auto pointer = find(uid);
if (pointer) {
@ -86,6 +104,14 @@ QVariantMap PointerManager::getPointerProperties(unsigned int uid) const {
}
}
QVariantMap PointerManager::getPointerScriptParameters(unsigned int uid) const {
auto pointer = find(uid);
if (pointer) {
return pointer->getScriptParameters();
}
return QVariantMap();
}
void PointerManager::update() {
auto cachedPointers = resultWithReadLock<std::unordered_map<unsigned int, std::shared_ptr<Pointer>>>([&] {
return _pointers;

View file

@ -27,10 +27,17 @@ public:
void removePointer(unsigned int uid);
void enablePointer(unsigned int uid) const;
void disablePointer(unsigned int uid) const;
bool isPointerEnabled(unsigned int uid) const;
QVector<unsigned int> getPointers() const;
void setRenderState(unsigned int uid, const std::string& renderState) const;
void editRenderState(unsigned int uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const;
PickResultPointer getPrevPickResult(unsigned int uid) const;
// The actual current properties of the pointer
QVariantMap getPointerProperties(unsigned int uid) const;
// The properties that were passed in to create the pointer (may be empty if the pointer was created by invoking the constructor)
QVariantMap getPointerScriptParameters(unsigned int uid) const;
void setPrecisionPicking(unsigned int uid, bool precisionPicking) const;
void setIgnoreItems(unsigned int uid, const QVector<QUuid>& ignoreEntities) const;

View file

@ -106,13 +106,17 @@ static const float AVATAR_WALK_SPEED_SCALAR = 1.0f;
static const float AVATAR_DESKTOP_SPRINT_SPEED_SCALAR = 3.0f;
static const float AVATAR_HMD_SPRINT_SPEED_SCALAR = 2.0f;
enum AvatarReaction {
enum AvatarTriggerReaction {
AVATAR_REACTION_POSITIVE = 0,
AVATAR_REACTION_NEGATIVE,
NUM_AVATAR_TRIGGER_REACTIONS
};
enum AvatarBeginEndReaction {
AVATAR_REACTION_RAISE_HAND,
AVATAR_REACTION_APPLAUD,
AVATAR_REACTION_POINT,
NUM_AVATAR_REACTIONS
NUM_AVATAR_BEGIN_END_REACTIONS
};
#endif // hifi_AvatarConstants_h

View file

@ -22,8 +22,9 @@
#include <QString>
/**jsdoc
* Helper functions to render ephemeral debug markers and lines.
* DebugDraw markers and lines are only visible locally, they are not visible by other users.
* The <code>DebugDraw</code> API renders debug markers and lines. These markers are only visible locally; they are not visible
* to other users.
*
* @namespace DebugDraw
*
* @hifi-interface
@ -41,57 +42,107 @@ public:
~DebugDraw();
/**jsdoc
* Draws a line in world space, but it will only be visible for a single frame.
* Draws a line in world space, visible for a single frame. To make the line visually persist, you need to repeatedly draw
* it.
* @function DebugDraw.drawRay
* @param {Vec3} start - start position of line in world space.
* @param {Vec3} end - end position of line in world space.
* @param {Vec4} color - color of line, each component should be in the zero to one range. x = red, y = blue, z = green, w = alpha.
* @param {Vec3} start - The start position of the line, in world coordinates.
* @param {Vec3} end - The end position of the line, in world coordinates.
* @param {Vec4} color - The color of the line. Each component should be in the range <code>0.0</code> &ndash;
* <code>1.0</code>, with <code>x</code> = red, <code>y</code> = green, <code>z</code> = blue, and <code>w</code> = alpha.
* @example <caption>Draw a red ray from your initial avatar position to 10m in front of it.</caption>
* var start = MyAvatar.position;
* var end = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -10 }));
* var color = { x: 1.0, y: 0.0, z: 0.0, w: 1.0 };
*
* Script.update.connect(function () {
* DebugDraw.drawRay(start, end, color);
* });
*/
Q_INVOKABLE void drawRay(const glm::vec3& start, const glm::vec3& end, const glm::vec4& color);
/**jsdoc
* Draws a line in world space, but it will only be visible for a single frame.
* @function DebugDraw.drawRay
* @param {Vec3} start - start position of line in world space.
* @param {Vec3} end - end position of line in world space.
* @param {Vec4} color - color of line, each component should be in the zero to one range. x = red, y = blue, z = green, w = alpha.
*/
* Draws lines in world space, visible for a single frame. To make the lines visually persist, you need to repeatedly draw
* them.
* <p><strong>Note:</strong> Currently doesn't work.
* @function DebugDraw.drawRays
* @param {Vec3Pair[]} lines - The start and end points of the lines to draw.
* @param {Vec4} color - The color of the lines. Each component should be in the range <code>0.0</code> &ndash;
* <code>1.0</code>, with <code>x</code> = red, <code>y</code> = green, <code>z</code> = blue, and <code>w</code> = alpha.
* @param {Vec3} [translation=0,0,0] - A translation applied to each line.
* @param {Quat} [rotation=Quat.IDENTITY] - A rotation applied to each line.
* @example <caption>Draw a red "V" in front of your initial avatar position.</caption>
* var lines = [
* [{ x: -1, y: 0.5, z: 0 }, { x: 0, y: 0, z: 0 }],
* [{ x: 0, y: 0, z: 0 }, { x: 1, y: 0.5, z: 0 }]
* ];
* var color = { x: 1, y: 0, z: 0, w: 1 };
* var translation = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -5 }));
* var rotation = MyAvatar.orientation;
*
* Script.update.connect(function () {
* DebugDraw.drawRays(lines, color, translation, rotation);
* });
*/
Q_INVOKABLE void drawRays(const std::vector<std::pair<glm::vec3, glm::vec3>>& lines, const glm::vec4& color,
const glm::vec3& translation = glm::vec3(0.0f, 0.0f, 0.0f), const glm::quat& rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
/**jsdoc
* Adds a debug marker to the world. This marker will be drawn every frame until it is removed with DebugDraw.removeMarker.
* This can be called repeatedly to change the position of the marker.
* Adds or updates a debug marker in world coordinates. This marker is drawn every frame until it is removed using
* {@link DebugDraw.removeMarker|removeMarker}. If a world coordinates debug marker of the specified <code>name</code>
* already exists, its parameters are updated.
* @function DebugDraw.addMarker
* @param {string} key - name to uniquely identify this marker, later used for DebugDraw.removeMarker.
* @param {Quat} rotation - start position of line in world space.
* @param {Vec3} position - position of the marker in world space.
* @param {Vec4} color - color of the marker.
* @param {string} key - A name that uniquely identifies the marker.
* @param {Quat} rotation - The orientation of the marker in world coordinates.
* @param {Vec3} position - The position of the market in world coordinates.
* @param {Vec4} color - The color of the marker.
* @example <caption>Briefly draw a debug marker in front of your avatar, in world coordinates.</caption>
* var MARKER_NAME = "my marker";
* DebugDraw.addMarker(
* MARKER_NAME,
* Quat.ZERO,
* Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5})),
* { red: 255, green: 0, blue: 0 }
* );
* Script.setTimeout(function () {
* DebugDraw.removeMarker(MARKER_NAME);
* }, 5000);
*/
Q_INVOKABLE void addMarker(const QString& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color);
/**jsdoc
* Removes debug marker from the world. Once a marker is removed, it will no longer be visible.
* Removes a debug marker that was added in world coordinates.
* @function DebugDraw.removeMarker
* @param {string} key - name of marker to remove.
* @param {string} key - The name of the world coordinates debug marker to remove.
*/
Q_INVOKABLE void removeMarker(const QString& key);
/**jsdoc
* Adds a debug marker to the world, this marker will be drawn every frame until it is removed with DebugDraw.removeMyAvatarMarker.
* This can be called repeatedly to change the position of the marker.
* Adds or updates a debug marker to the world in avatar coordinates. This marker is drawn every frame until it is removed
* using {@link DebugDraw.removeMyAvatarMarker|removeMyAvatarMarker}. If an avatar coordinates debug marker of the
* specified <code>name</code> already exists, its parameters are updated. The debug marker moves with your avatar.
* @function DebugDraw.addMyAvatarMarker
* @param {string} key - name to uniquely identify this marker, later used for DebugDraw.removeMyAvatarMarker.
* @param {Quat} rotation - start position of line in avatar space.
* @param {Vec3} position - position of the marker in avatar space.
* @param {string} key - A name that uniquely identifies the marker.
* @param {Quat} rotation - The orientation of the marker in avatar coordinates.
* @param {Vec3} position - The position of the market in avatar coordinates.
* @param {Vec4} color - color of the marker.
* @example <caption>Briefly draw a debug marker in front of your avatar, in avatar coordinates.</caption>
* var MARKER_NAME = "My avatar marker";
* DebugDraw.addMyAvatarMarker(
* MARKER_NAME,
* Quat.ZERO,
* { x: 0, y: 0, z: -5 },
* { red: 255, green: 0, blue: 0 }
* );
* Script.setTimeout(function () {
* DebugDraw.removeMyAvatarMarker(MARKER_NAME);
* }, 5000);
*/
Q_INVOKABLE void addMyAvatarMarker(const QString& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color);
/**jsdoc
* Removes debug marker from the world. Once a marker is removed, it will no longer be visible
* Removes a debug marker that was added in avatar coordinates.
* @function DebugDraw.removeMyAvatarMarker
* @param {string} key - name of marker to remove.
* @param {string} key - The name of the avatar coordinates debug marker to remove.
*/
Q_INVOKABLE void removeMyAvatarMarker(const QString& key);

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/14/2018
// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -11,4 +11,4 @@
template<>
glm::vec3 BaseNestableTransformNode<SpatiallyNestable>::getActualScale(const std::shared_ptr<SpatiallyNestable>& nestablePointer) const {
return nestablePointer->getAbsoluteJointScaleInObjectFrame(_jointIndex);
}
}

View file

@ -1,5 +1,5 @@
//
// Created by Sabrina Shanman 8/14/2018
// Created by Sabrina Shanman 2018/08/14
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -12,6 +12,8 @@
#include "SpatiallyNestable.h"
#include "RegisteredMetaTypes.h"
template <typename T>
class BaseNestableTransformNode : public TransformNode {
public:
@ -45,6 +47,19 @@ public:
return jointWorldTransform;
}
QVariantMap toVariantMap() const override {
QVariantMap map;
auto nestable = _spatiallyNestable.lock();
if (nestable) {
map["parentID"] = nestable->getID();
map["parentJointIndex"] = _jointIndex;
map["baseParentScale"] = vec3toVariant(_baseScale);
}
return map;
}
glm::vec3 getActualScale(const std::shared_ptr<T>& nestablePointer) const;
protected:

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