mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 19:55:07 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into hdr
This commit is contained in:
commit
00addcad9e
33 changed files with 640 additions and 157 deletions
|
@ -489,7 +489,7 @@ void AudioMixer::handleNodeAudioPacket(QSharedPointer<ReceivedMessage> message,
|
|||
void AudioMixer::handleMuteEnvironmentPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
if (sendingNode->isAllowedEditor()) {
|
||||
if (sendingNode->getCanKick()) {
|
||||
glm::vec3 position;
|
||||
float radius;
|
||||
|
||||
|
|
|
@ -396,15 +396,6 @@ Menu::Menu() {
|
|||
});
|
||||
}
|
||||
|
||||
// Developer > Render > Enable Incremental Texture Transfer
|
||||
{
|
||||
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::IncrementalTextureTransfer, 0, gpu::Texture::getEnableIncrementalTextureTransfers());
|
||||
connect(action, &QAction::triggered, [&](bool checked) {
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] --- Enable Incremental Texture Transfer menu option:" << checked;
|
||||
gpu::Texture::setEnableIncrementalTextureTransfers(checked);
|
||||
});
|
||||
}
|
||||
|
||||
#else
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] Incremental Texture Transfer and Dynamic Texture Management not supported on this platform.";
|
||||
#endif
|
||||
|
|
|
@ -112,7 +112,6 @@ namespace MenuOption {
|
|||
const QString FrameTimer = "Show Timer";
|
||||
const QString FullscreenMirror = "Mirror";
|
||||
const QString Help = "Help...";
|
||||
const QString IncrementalTextureTransfer = "Enable Incremental Texture Transfer";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IndependentMode = "Independent Mode";
|
||||
const QString ActionMotorControl = "Enable Default Motor Control";
|
||||
|
|
|
@ -19,12 +19,35 @@ class AccountScriptingInterface : public QObject {
|
|||
|
||||
Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
|
||||
|
||||
/**jsdoc
|
||||
* @namespace Account
|
||||
* @property username {String} username if user is logged in, otherwise it returns "Unknown user"
|
||||
*/
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when username has changed.
|
||||
* @function Account.usernameChanged
|
||||
* @return {Signal}
|
||||
*/
|
||||
void usernameChanged();
|
||||
|
||||
public slots:
|
||||
static AccountScriptingInterface* getInstance();
|
||||
|
||||
/**jsdoc
|
||||
* Returns the username for the currently logged in High Fidelity metaverse account.
|
||||
* @function Account.getUsername
|
||||
* @return {string} username if user is logged in, otherwise it returns "Unknown user"
|
||||
*/
|
||||
QString getUsername();
|
||||
|
||||
/**jsdoc
|
||||
* Determine if the user is logged into the High Fidleity metaverse.
|
||||
* @function Account.isLoggedIn
|
||||
* @return {bool} true when user is logged into the High Fidelity metaverse.
|
||||
*/
|
||||
bool isLoggedIn();
|
||||
bool checkAndSignalForAccessToken();
|
||||
};
|
||||
|
|
|
@ -126,6 +126,23 @@ void MenuScriptingInterface::setIsOptionChecked(const QString& menuOption, bool
|
|||
Q_ARG(bool, isChecked));
|
||||
}
|
||||
|
||||
bool MenuScriptingInterface::isMenuEnabled(const QString& menuOption) {
|
||||
if (QThread::currentThread() == qApp->thread()) {
|
||||
return Menu::getInstance()->isOptionChecked(menuOption);
|
||||
}
|
||||
bool result;
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "isMenuEnabled", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, result),
|
||||
Q_ARG(const QString&, menuOption));
|
||||
return result;
|
||||
}
|
||||
|
||||
void MenuScriptingInterface::setMenuEnabled(const QString& menuOption, bool isChecked) {
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "setMenuEnabled",
|
||||
Q_ARG(const QString&, menuOption),
|
||||
Q_ARG(bool, isChecked));
|
||||
}
|
||||
|
||||
void MenuScriptingInterface::triggerOption(const QString& menuOption) {
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "triggerOption", Q_ARG(const QString&, menuOption));
|
||||
}
|
||||
|
|
|
@ -50,6 +50,9 @@ public slots:
|
|||
void setIsOptionChecked(const QString& menuOption, bool isChecked);
|
||||
|
||||
void triggerOption(const QString& menuOption);
|
||||
|
||||
bool isMenuEnabled(const QString& menuName);
|
||||
void setMenuEnabled(const QString& menuName, bool isEnabled);
|
||||
|
||||
signals:
|
||||
void menuItemEvent(const QString& menuItem);
|
||||
|
|
|
@ -29,7 +29,19 @@ class AnimationCache : public ResourceCache, public Dependency {
|
|||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
/**jsdoc
|
||||
* @namespace AnimationCache
|
||||
* @augments ResourceCache
|
||||
*/
|
||||
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
* Returns animation resource for particular animation
|
||||
* @function AnimationCache.getAnimation
|
||||
* @param url {string} url to load
|
||||
* @return {Resource} animation
|
||||
*/
|
||||
Q_INVOKABLE AnimationPointer getAnimation(const QString& url) { return getAnimation(QUrl(url)); }
|
||||
Q_INVOKABLE AnimationPointer getAnimation(const QUrl& url);
|
||||
|
||||
|
|
|
@ -308,6 +308,13 @@ void Rig::clearIKJointLimitHistory() {
|
|||
}
|
||||
}
|
||||
|
||||
int Rig::getJointParentIndex(int childIndex) const {
|
||||
if (_animSkeleton && isIndexValid(childIndex)) {
|
||||
return _animSkeleton->getParentIndex(childIndex);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Rig::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) {
|
||||
if (isIndexValid(index)) {
|
||||
if (valid) {
|
||||
|
@ -414,6 +421,16 @@ bool Rig::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& trans
|
|||
}
|
||||
}
|
||||
|
||||
bool Rig::getAbsoluteJointPoseInRigFrame(int jointIndex, AnimPose& returnPose) const {
|
||||
QReadLocker readLock(&_externalPoseSetLock);
|
||||
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) {
|
||||
returnPose = _externalPoseSet._absolutePoses[jointIndex];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const {
|
||||
// AJT: TODO: used by attachments
|
||||
ASSERT(false);
|
||||
|
|
|
@ -105,6 +105,8 @@ public:
|
|||
|
||||
void clearIKJointLimitHistory();
|
||||
|
||||
int getJointParentIndex(int childIndex) const;
|
||||
|
||||
// geometry space
|
||||
void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority);
|
||||
|
||||
|
@ -133,6 +135,7 @@ public:
|
|||
// rig space (thread-safe)
|
||||
bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const;
|
||||
bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const;
|
||||
bool getAbsoluteJointPoseInRigFrame(int jointIndex, AnimPose& returnPose) const;
|
||||
|
||||
// legacy
|
||||
bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const;
|
||||
|
|
|
@ -310,14 +310,14 @@ bool RenderableModelEntityItem::getAnimationFrame() {
|
|||
}
|
||||
glm::mat4 finalMat = (translationMat * fbxJoints[index].preTransform *
|
||||
rotationMat * fbxJoints[index].postTransform);
|
||||
_absoluteJointTranslationsInObjectFrame[j] = extractTranslation(finalMat);
|
||||
_absoluteJointTranslationsInObjectFrameSet[j] = true;
|
||||
_absoluteJointTranslationsInObjectFrameDirty[j] = true;
|
||||
_localJointTranslations[j] = extractTranslation(finalMat);
|
||||
_localJointTranslationsSet[j] = true;
|
||||
_localJointTranslationsDirty[j] = true;
|
||||
|
||||
_absoluteJointRotationsInObjectFrame[j] = glmExtractRotation(finalMat);
|
||||
_localJointRotations[j] = glmExtractRotation(finalMat);
|
||||
|
||||
_absoluteJointRotationsInObjectFrameSet[j] = true;
|
||||
_absoluteJointRotationsInObjectFrameDirty[j] = true;
|
||||
_localJointRotationsSet[j] = true;
|
||||
_localJointRotationsDirty[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,18 +390,18 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
getAnimationFrame();
|
||||
|
||||
// relay any inbound joint changes from scripts/animation/network to the model/rig
|
||||
for (int index = 0; index < _absoluteJointRotationsInObjectFrame.size(); index++) {
|
||||
if (_absoluteJointRotationsInObjectFrameDirty[index]) {
|
||||
glm::quat rotation = _absoluteJointRotationsInObjectFrame[index];
|
||||
for (int index = 0; index < _localJointRotations.size(); index++) {
|
||||
if (_localJointRotationsDirty[index]) {
|
||||
glm::quat rotation = _localJointRotations[index];
|
||||
_model->setJointRotation(index, true, rotation, 1.0f);
|
||||
_absoluteJointRotationsInObjectFrameDirty[index] = false;
|
||||
_localJointRotationsDirty[index] = false;
|
||||
}
|
||||
}
|
||||
for (int index = 0; index < _absoluteJointTranslationsInObjectFrame.size(); index++) {
|
||||
if (_absoluteJointTranslationsInObjectFrameDirty[index]) {
|
||||
glm::vec3 translation = _absoluteJointTranslationsInObjectFrame[index];
|
||||
for (int index = 0; index < _localJointTranslations.size(); index++) {
|
||||
if (_localJointTranslationsDirty[index]) {
|
||||
glm::vec3 translation = _localJointTranslations[index];
|
||||
_model->setJointTranslation(index, true, translation, 1.0f);
|
||||
_absoluteJointTranslationsInObjectFrameDirty[index] = false;
|
||||
_localJointTranslationsDirty[index] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1028,15 +1028,101 @@ glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(in
|
|||
}
|
||||
|
||||
bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) {
|
||||
if (!_model) {
|
||||
return false;
|
||||
}
|
||||
RigPointer rig = _model->getRig();
|
||||
if (!rig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int jointParentIndex = rig->getJointParentIndex(index);
|
||||
if (jointParentIndex == -1) {
|
||||
return setLocalJointRotation(index, rotation);
|
||||
}
|
||||
|
||||
bool success;
|
||||
AnimPose jointParentPose;
|
||||
success = rig->getAbsoluteJointPoseInRigFrame(jointParentIndex, jointParentPose);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
AnimPose jointParentInversePose = jointParentPose.inverse();
|
||||
|
||||
AnimPose jointAbsolutePose; // in rig frame
|
||||
success = rig->getAbsoluteJointPoseInRigFrame(index, jointAbsolutePose);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
jointAbsolutePose.rot = rotation;
|
||||
|
||||
AnimPose jointRelativePose = jointParentInversePose * jointAbsolutePose;
|
||||
return setLocalJointRotation(index, jointRelativePose.rot);
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) {
|
||||
if (!_model) {
|
||||
return false;
|
||||
}
|
||||
RigPointer rig = _model->getRig();
|
||||
if (!rig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int jointParentIndex = rig->getJointParentIndex(index);
|
||||
if (jointParentIndex == -1) {
|
||||
return setLocalJointTranslation(index, translation);
|
||||
}
|
||||
|
||||
bool success;
|
||||
AnimPose jointParentPose;
|
||||
success = rig->getAbsoluteJointPoseInRigFrame(jointParentIndex, jointParentPose);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
AnimPose jointParentInversePose = jointParentPose.inverse();
|
||||
|
||||
AnimPose jointAbsolutePose; // in rig frame
|
||||
success = rig->getAbsoluteJointPoseInRigFrame(index, jointAbsolutePose);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
jointAbsolutePose.trans = translation;
|
||||
|
||||
AnimPose jointRelativePose = jointParentInversePose * jointAbsolutePose;
|
||||
return setLocalJointTranslation(index, jointRelativePose.trans);
|
||||
}
|
||||
|
||||
glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const {
|
||||
if (_model) {
|
||||
glm::quat result;
|
||||
if (_model->getJointRotation(index, result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return glm::quat();
|
||||
}
|
||||
|
||||
glm::vec3 RenderableModelEntityItem::getLocalJointTranslation(int index) const {
|
||||
if (_model) {
|
||||
glm::vec3 result;
|
||||
if (_model->getJointTranslation(index, result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return glm::vec3();
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::setLocalJointRotation(int index, const glm::quat& rotation) {
|
||||
bool result = false;
|
||||
_jointDataLock.withWriteLock([&] {
|
||||
_jointRotationsExplicitlySet = true;
|
||||
resizeJointArrays();
|
||||
if (index >= 0 && index < _absoluteJointRotationsInObjectFrame.size() &&
|
||||
_absoluteJointRotationsInObjectFrame[index] != rotation) {
|
||||
_absoluteJointRotationsInObjectFrame[index] = rotation;
|
||||
_absoluteJointRotationsInObjectFrameSet[index] = true;
|
||||
_absoluteJointRotationsInObjectFrameDirty[index] = true;
|
||||
if (index >= 0 && index < _localJointRotations.size() &&
|
||||
_localJointRotations[index] != rotation) {
|
||||
_localJointRotations[index] = rotation;
|
||||
_localJointRotationsSet[index] = true;
|
||||
_localJointRotationsDirty[index] = true;
|
||||
result = true;
|
||||
_needsJointSimulation = true;
|
||||
}
|
||||
|
@ -1044,16 +1130,16 @@ bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index,
|
|||
return result;
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) {
|
||||
bool RenderableModelEntityItem::setLocalJointTranslation(int index, const glm::vec3& translation) {
|
||||
bool result = false;
|
||||
_jointDataLock.withWriteLock([&] {
|
||||
_jointTranslationsExplicitlySet = true;
|
||||
resizeJointArrays();
|
||||
if (index >= 0 && index < _absoluteJointTranslationsInObjectFrame.size() &&
|
||||
_absoluteJointTranslationsInObjectFrame[index] != translation) {
|
||||
_absoluteJointTranslationsInObjectFrame[index] = translation;
|
||||
_absoluteJointTranslationsInObjectFrameSet[index] = true;
|
||||
_absoluteJointTranslationsInObjectFrameDirty[index] = true;
|
||||
if (index >= 0 && index < _localJointTranslations.size() &&
|
||||
_localJointTranslations[index] != translation) {
|
||||
_localJointTranslations[index] = translation;
|
||||
_localJointTranslationsSet[index] = true;
|
||||
_localJointTranslationsDirty[index] = true;
|
||||
result = true;
|
||||
_needsJointSimulation = true;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,12 @@ public:
|
|||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override;
|
||||
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override;
|
||||
|
||||
|
||||
virtual glm::quat getLocalJointRotation(int index) const override;
|
||||
virtual glm::vec3 getLocalJointTranslation(int index) const override;
|
||||
virtual bool setLocalJointRotation(int index, const glm::quat& rotation) override;
|
||||
virtual bool setLocalJointTranslation(int index, const glm::vec3& translation) override;
|
||||
|
||||
virtual void setJointRotations(const QVector<glm::quat>& rotations) override;
|
||||
virtual void setJointRotationsSet(const QVector<bool>& rotationsSet) override;
|
||||
virtual void setJointTranslations(const QVector<glm::vec3>& translations) override;
|
||||
|
|
|
@ -418,8 +418,9 @@ public:
|
|||
// these are in the frame of this object
|
||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override { return glm::quat(); }
|
||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override { return glm::vec3(0.0f); }
|
||||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; }
|
||||
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; }
|
||||
|
||||
virtual bool setLocalJointRotation(int index, const glm::quat& rotation) override { return false; }
|
||||
virtual bool setLocalJointTranslation(int index, const glm::vec3& translation) override { return false; }
|
||||
|
||||
virtual int getJointIndex(const QString& name) const { return -1; }
|
||||
virtual QStringList getJointNames() const { return QStringList(); }
|
||||
|
|
|
@ -1154,17 +1154,76 @@ bool EntityScriptingInterface::setAbsoluteJointRotationInObjectFrame(const QUuid
|
|||
return false;
|
||||
}
|
||||
|
||||
glm::vec3 EntityScriptingInterface::getLocalJointTranslation(const QUuid& entityID, int jointIndex) {
|
||||
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
|
||||
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
|
||||
return modelEntity->getLocalJointTranslation(jointIndex);
|
||||
} else {
|
||||
return glm::vec3(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
glm::quat EntityScriptingInterface::getLocalJointRotation(const QUuid& entityID, int jointIndex) {
|
||||
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
|
||||
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
|
||||
return modelEntity->getLocalJointRotation(jointIndex);
|
||||
} else {
|
||||
return glm::quat();
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setLocalJointTranslation(const QUuid& entityID, int jointIndex, glm::vec3 translation) {
|
||||
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
|
||||
auto now = usecTimestampNow();
|
||||
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
|
||||
bool result = modelEntity->setLocalJointTranslation(jointIndex, translation);
|
||||
if (result) {
|
||||
EntityItemProperties properties;
|
||||
_entityTree->withWriteLock([&] {
|
||||
properties = entity->getProperties();
|
||||
entity->setLastBroadcast(now);
|
||||
});
|
||||
|
||||
properties.setJointTranslationsDirty();
|
||||
properties.setLastEdited(now);
|
||||
queueEntityMessage(PacketType::EntityEdit, entityID, properties);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setLocalJointRotation(const QUuid& entityID, int jointIndex, glm::quat rotation) {
|
||||
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
|
||||
auto now = usecTimestampNow();
|
||||
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
|
||||
bool result = modelEntity->setLocalJointRotation(jointIndex, rotation);
|
||||
if (result) {
|
||||
EntityItemProperties properties;
|
||||
_entityTree->withWriteLock([&] {
|
||||
properties = entity->getProperties();
|
||||
entity->setLastBroadcast(now);
|
||||
});
|
||||
|
||||
properties.setJointRotationsDirty();
|
||||
properties.setLastEdited(now);
|
||||
queueEntityMessage(PacketType::EntityEdit, entityID, properties);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::setAbsoluteJointRotationsInObjectFrame(const QUuid& entityID,
|
||||
const QVector<glm::quat>& rotations) {
|
||||
|
||||
bool EntityScriptingInterface::setLocalJointRotations(const QUuid& entityID, const QVector<glm::quat>& rotations) {
|
||||
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
|
||||
auto now = usecTimestampNow();
|
||||
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
|
||||
|
||||
bool result = false;
|
||||
for (int index = 0; index < rotations.size(); index++) {
|
||||
result |= modelEntity->setAbsoluteJointRotationInObjectFrame(index, rotations[index]);
|
||||
result |= modelEntity->setLocalJointRotation(index, rotations[index]);
|
||||
}
|
||||
if (result) {
|
||||
EntityItemProperties properties;
|
||||
|
@ -1184,15 +1243,14 @@ bool EntityScriptingInterface::setAbsoluteJointRotationsInObjectFrame(const QUui
|
|||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::setAbsoluteJointTranslationsInObjectFrame(const QUuid& entityID,
|
||||
const QVector<glm::vec3>& translations) {
|
||||
bool EntityScriptingInterface::setLocalJointTranslations(const QUuid& entityID, const QVector<glm::vec3>& translations) {
|
||||
if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) {
|
||||
auto now = usecTimestampNow();
|
||||
auto modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity);
|
||||
|
||||
bool result = false;
|
||||
for (int index = 0; index < translations.size(); index++) {
|
||||
result |= modelEntity->setAbsoluteJointTranslationInObjectFrame(index, translations[index]);
|
||||
result |= modelEntity->setLocalJointTranslation(index, translations[index]);
|
||||
}
|
||||
if (result) {
|
||||
EntityItemProperties properties;
|
||||
|
@ -1211,12 +1269,12 @@ bool EntityScriptingInterface::setAbsoluteJointTranslationsInObjectFrame(const Q
|
|||
return false;
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setAbsoluteJointsDataInObjectFrame(const QUuid& entityID,
|
||||
const QVector<glm::quat>& rotations,
|
||||
const QVector<glm::vec3>& translations) {
|
||||
bool EntityScriptingInterface::setLocalJointsData(const QUuid& entityID,
|
||||
const QVector<glm::quat>& rotations,
|
||||
const QVector<glm::vec3>& translations) {
|
||||
// for a model with 80 joints, sending both these in one edit packet causes the packet to be too large.
|
||||
return setAbsoluteJointRotationsInObjectFrame(entityID, rotations) ||
|
||||
setAbsoluteJointTranslationsInObjectFrame(entityID, translations);
|
||||
return setLocalJointRotations(entityID, rotations) ||
|
||||
setLocalJointTranslations(entityID, translations);
|
||||
}
|
||||
|
||||
int EntityScriptingInterface::getJointIndex(const QUuid& entityID, const QString& name) {
|
||||
|
|
|
@ -186,13 +186,17 @@ public slots:
|
|||
Q_INVOKABLE glm::quat getAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex);
|
||||
Q_INVOKABLE bool setAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex, glm::vec3 translation);
|
||||
Q_INVOKABLE bool setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex, glm::quat rotation);
|
||||
Q_INVOKABLE bool setAbsoluteJointRotationsInObjectFrame(const QUuid& entityID,
|
||||
const QVector<glm::quat>& rotations);
|
||||
Q_INVOKABLE bool setAbsoluteJointTranslationsInObjectFrame(const QUuid& entityID,
|
||||
const QVector<glm::vec3>& translations);
|
||||
Q_INVOKABLE bool setAbsoluteJointsDataInObjectFrame(const QUuid& entityID,
|
||||
const QVector<glm::quat>& rotations,
|
||||
const QVector<glm::vec3>& translations);
|
||||
|
||||
Q_INVOKABLE glm::vec3 getLocalJointTranslation(const QUuid& entityID, int jointIndex);
|
||||
Q_INVOKABLE glm::quat getLocalJointRotation(const QUuid& entityID, int jointIndex);
|
||||
Q_INVOKABLE bool setLocalJointTranslation(const QUuid& entityID, int jointIndex, glm::vec3 translation);
|
||||
Q_INVOKABLE bool setLocalJointRotation(const QUuid& entityID, int jointIndex, glm::quat rotation);
|
||||
|
||||
Q_INVOKABLE bool setLocalJointRotations(const QUuid& entityID, const QVector<glm::quat>& rotations);
|
||||
Q_INVOKABLE bool setLocalJointTranslations(const QUuid& entityID, const QVector<glm::vec3>& translations);
|
||||
Q_INVOKABLE bool setLocalJointsData(const QUuid& entityID,
|
||||
const QVector<glm::quat>& rotations,
|
||||
const QVector<glm::vec3>& translations);
|
||||
|
||||
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name);
|
||||
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID);
|
||||
|
|
|
@ -389,13 +389,13 @@ bool ModelEntityItem::shouldBePhysical() const {
|
|||
}
|
||||
|
||||
void ModelEntityItem::resizeJointArrays(int newSize) {
|
||||
if (newSize >= 0 && newSize > _absoluteJointRotationsInObjectFrame.size()) {
|
||||
_absoluteJointRotationsInObjectFrame.resize(newSize);
|
||||
_absoluteJointRotationsInObjectFrameSet.resize(newSize);
|
||||
_absoluteJointRotationsInObjectFrameDirty.resize(newSize);
|
||||
_absoluteJointTranslationsInObjectFrame.resize(newSize);
|
||||
_absoluteJointTranslationsInObjectFrameSet.resize(newSize);
|
||||
_absoluteJointTranslationsInObjectFrameDirty.resize(newSize);
|
||||
if (newSize >= 0 && newSize > _localJointRotations.size()) {
|
||||
_localJointRotations.resize(newSize);
|
||||
_localJointRotationsSet.resize(newSize);
|
||||
_localJointRotationsDirty.resize(newSize);
|
||||
_localJointTranslations.resize(newSize);
|
||||
_localJointTranslationsSet.resize(newSize);
|
||||
_localJointTranslationsDirty.resize(newSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,9 +404,9 @@ void ModelEntityItem::setJointRotations(const QVector<glm::quat>& rotations) {
|
|||
_jointRotationsExplicitlySet = rotations.size() > 0;
|
||||
resizeJointArrays(rotations.size());
|
||||
for (int index = 0; index < rotations.size(); index++) {
|
||||
if (_absoluteJointRotationsInObjectFrameSet[index]) {
|
||||
_absoluteJointRotationsInObjectFrame[index] = rotations[index];
|
||||
_absoluteJointRotationsInObjectFrameDirty[index] = true;
|
||||
if (_localJointRotationsSet[index]) {
|
||||
_localJointRotations[index] = rotations[index];
|
||||
_localJointRotationsDirty[index] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -417,7 +417,7 @@ void ModelEntityItem::setJointRotationsSet(const QVector<bool>& rotationsSet) {
|
|||
_jointRotationsExplicitlySet = rotationsSet.size() > 0;
|
||||
resizeJointArrays(rotationsSet.size());
|
||||
for (int index = 0; index < rotationsSet.size(); index++) {
|
||||
_absoluteJointRotationsInObjectFrameSet[index] = rotationsSet[index];
|
||||
_localJointRotationsSet[index] = rotationsSet[index];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -427,9 +427,9 @@ void ModelEntityItem::setJointTranslations(const QVector<glm::vec3>& translation
|
|||
_jointTranslationsExplicitlySet = translations.size() > 0;
|
||||
resizeJointArrays(translations.size());
|
||||
for (int index = 0; index < translations.size(); index++) {
|
||||
if (_absoluteJointTranslationsInObjectFrameSet[index]) {
|
||||
_absoluteJointTranslationsInObjectFrame[index] = translations[index];
|
||||
_absoluteJointTranslationsInObjectFrameSet[index] = true;
|
||||
if (_localJointTranslationsSet[index]) {
|
||||
_localJointTranslations[index] = translations[index];
|
||||
_localJointTranslationsSet[index] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -440,7 +440,7 @@ void ModelEntityItem::setJointTranslationsSet(const QVector<bool>& translationsS
|
|||
_jointTranslationsExplicitlySet = translationsSet.size() > 0;
|
||||
resizeJointArrays(translationsSet.size());
|
||||
for (int index = 0; index < translationsSet.size(); index++) {
|
||||
_absoluteJointTranslationsInObjectFrameSet[index] = translationsSet[index];
|
||||
_localJointTranslationsSet[index] = translationsSet[index];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ QVector<glm::quat> ModelEntityItem::getJointRotations() const {
|
|||
QVector<glm::quat> result;
|
||||
_jointDataLock.withReadLock([&] {
|
||||
if (_jointRotationsExplicitlySet) {
|
||||
result = _absoluteJointRotationsInObjectFrame;
|
||||
result = _localJointRotations;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
|
@ -459,7 +459,7 @@ QVector<bool> ModelEntityItem::getJointRotationsSet() const {
|
|||
QVector<bool> result;
|
||||
_jointDataLock.withReadLock([&] {
|
||||
if (_jointRotationsExplicitlySet) {
|
||||
result = _absoluteJointRotationsInObjectFrameSet;
|
||||
result = _localJointRotationsSet;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -470,7 +470,7 @@ QVector<glm::vec3> ModelEntityItem::getJointTranslations() const {
|
|||
QVector<glm::vec3> result;
|
||||
_jointDataLock.withReadLock([&] {
|
||||
if (_jointTranslationsExplicitlySet) {
|
||||
result = _absoluteJointTranslationsInObjectFrame;
|
||||
result = _localJointTranslations;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
|
@ -480,7 +480,7 @@ QVector<bool> ModelEntityItem::getJointTranslationsSet() const {
|
|||
QVector<bool> result;
|
||||
_jointDataLock.withReadLock([&] {
|
||||
if (_jointTranslationsExplicitlySet) {
|
||||
result = _absoluteJointTranslationsInObjectFrameSet;
|
||||
result = _localJointTranslationsSet;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
|
|
|
@ -117,9 +117,6 @@ public:
|
|||
|
||||
virtual bool shouldBePhysical() const override;
|
||||
|
||||
virtual glm::vec3 getJointPosition(int jointIndex) const { return glm::vec3(); }
|
||||
virtual glm::quat getJointRotation(int jointIndex) const { return glm::quat(); }
|
||||
|
||||
virtual void setJointRotations(const QVector<glm::quat>& rotations);
|
||||
virtual void setJointRotationsSet(const QVector<bool>& rotationsSet);
|
||||
virtual void setJointTranslations(const QVector<glm::vec3>& translations);
|
||||
|
@ -143,14 +140,14 @@ protected:
|
|||
ReadWriteLockable _jointDataLock;
|
||||
|
||||
bool _jointRotationsExplicitlySet { false }; // were the joints set as a property or just side effect of animations
|
||||
QVector<glm::quat> _absoluteJointRotationsInObjectFrame;
|
||||
QVector<bool> _absoluteJointRotationsInObjectFrameSet; // ever set?
|
||||
QVector<bool> _absoluteJointRotationsInObjectFrameDirty; // needs a relay to model/rig?
|
||||
|
||||
QVector<glm::quat> _localJointRotations;
|
||||
QVector<bool> _localJointRotationsSet; // ever set?
|
||||
QVector<bool> _localJointRotationsDirty; // needs a relay to model/rig?
|
||||
|
||||
bool _jointTranslationsExplicitlySet { false }; // were the joints set as a property or just side effect of animations
|
||||
QVector<glm::vec3> _absoluteJointTranslationsInObjectFrame;
|
||||
QVector<bool> _absoluteJointTranslationsInObjectFrameSet; // ever set?
|
||||
QVector<bool> _absoluteJointTranslationsInObjectFrameDirty; // needs a relay to model/rig?
|
||||
QVector<glm::vec3> _localJointTranslations;
|
||||
QVector<bool> _localJointTranslationsSet; // ever set?
|
||||
QVector<bool> _localJointTranslationsDirty; // needs a relay to model/rig?
|
||||
int _lastKnownCurrentFrame;
|
||||
virtual void resizeJointArrays(int newSize = -1);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "GLHelpers.h"
|
||||
|
||||
// Minimum gl version required is 4.1
|
||||
#define MINIMUM_GL_VERSION 0x0401
|
||||
|
||||
OpenGLVersionChecker::OpenGLVersionChecker(int& argc, char** argv) :
|
||||
|
@ -75,15 +76,26 @@ QJsonObject OpenGLVersionChecker::checkVersion(bool& valid, bool& override) {
|
|||
// - major_number.minor_number
|
||||
// - major_number.minor_number.release_number
|
||||
// Reference: https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glGetString.xml
|
||||
const QString version { "version" };
|
||||
QString glVersion = glData[version].toString();
|
||||
QStringList versionParts = glVersion.split(QRegularExpression("[\\.\\s]"));
|
||||
int majorNumber = versionParts[0].toInt();
|
||||
int minorNumber = versionParts[1].toInt();
|
||||
int minimumMajorNumber = (MINIMUM_GL_VERSION >> 16);
|
||||
|
||||
int minimumMajorNumber = (MINIMUM_GL_VERSION >> 8) & 0xFF;
|
||||
int minimumMinorNumber = (MINIMUM_GL_VERSION & 0xFF);
|
||||
valid = (majorNumber > minimumMajorNumber
|
||||
|| (majorNumber == minimumMajorNumber && minorNumber >= minimumMinorNumber));
|
||||
int majorNumber = 0;
|
||||
int minorNumber = 0;
|
||||
const QString version { "version" };
|
||||
if (glData.contains(version)) {
|
||||
QString glVersion = glData[version].toString();
|
||||
QStringList versionParts = glVersion.split(QRegularExpression("[\\.\\s]"));
|
||||
if (versionParts.size() >= 2) {
|
||||
majorNumber = versionParts[0].toInt();
|
||||
minorNumber = versionParts[1].toInt();
|
||||
valid = (majorNumber > minimumMajorNumber
|
||||
|| (majorNumber == minimumMajorNumber && minorNumber >= minimumMinorNumber));
|
||||
} else {
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// Prompt user if below minimum
|
||||
if (!valid) {
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "../gl/GLBackend.h"
|
||||
#include "../gl/GLTexture.h"
|
||||
|
||||
#define INCREMENTAL_TRANSFER 0
|
||||
|
||||
namespace gpu { namespace gl45 {
|
||||
|
||||
using namespace gpu::gl;
|
||||
|
@ -56,6 +58,7 @@ public:
|
|||
GLint pageDimensionsIndex { 0 };
|
||||
};
|
||||
|
||||
#if INCREMENTAL_TRANSFER
|
||||
struct TransferState {
|
||||
TransferState(GL45Texture& texture);
|
||||
uvec3 currentPageSize() const;
|
||||
|
@ -74,6 +77,10 @@ public:
|
|||
uvec3 mipOffset;
|
||||
const uint8_t* srcPointer { nullptr };
|
||||
};
|
||||
protected:
|
||||
TransferState _transferState;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void updateMips() override;
|
||||
void stripToMip(uint16_t newMinMip);
|
||||
|
@ -91,7 +98,6 @@ public:
|
|||
void derez();
|
||||
|
||||
SparseInfo _sparseInfo;
|
||||
TransferState _transferState;
|
||||
uint32_t _allocatedPages { 0 };
|
||||
uint32_t _lastMipAllocatedPages { 0 };
|
||||
uint16_t _mipOffset { 0 };
|
||||
|
|
|
@ -162,6 +162,8 @@ void GL45Backend::initTextureManagementStage() {
|
|||
}
|
||||
}
|
||||
|
||||
#if INCREMENTAL_TRANSFER
|
||||
|
||||
using TransferState = GL45Backend::GL45Texture::TransferState;
|
||||
|
||||
TransferState::TransferState(GL45Texture& texture) : texture(texture) {
|
||||
|
@ -246,6 +248,7 @@ void TransferState::populatePage(std::vector<uint8_t>& buffer) {
|
|||
uvec3 TransferState::currentPageSize() const {
|
||||
return glm::clamp(mipDimensions - mipOffset, uvec3(1), texture._sparseInfo.pageDimensions);
|
||||
}
|
||||
#endif
|
||||
|
||||
GLuint GL45Texture::allocate(const Texture& texture) {
|
||||
GLuint result;
|
||||
|
@ -258,11 +261,19 @@ GLuint GL45Backend::getTextureID(const TexturePointer& texture, bool transfer) {
|
|||
}
|
||||
|
||||
GL45Texture::GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture, GLuint externalId)
|
||||
: GLTexture(backend, texture, externalId), _sparseInfo(*this), _transferState(*this) {
|
||||
: GLTexture(backend, texture, externalId), _sparseInfo(*this)
|
||||
#if INCREMENTAL_TRANSFER
|
||||
, _transferState(*this)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
GL45Texture::GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture, bool transferrable)
|
||||
: GLTexture(backend, texture, allocate(texture), transferrable), _sparseInfo(*this), _transferState(*this) {
|
||||
: GLTexture(backend, texture, allocate(texture), transferrable), _sparseInfo(*this)
|
||||
#if INCREMENTAL_TRANSFER
|
||||
, _transferState(*this)
|
||||
#endif
|
||||
{
|
||||
|
||||
auto theBackend = _backend.lock();
|
||||
if (_transferrable && theBackend && theBackend->isTextureManagementSparseEnabled()) {
|
||||
|
@ -375,39 +386,40 @@ void GL45Texture::updateSize() const {
|
|||
void GL45Texture::startTransfer() {
|
||||
Parent::startTransfer();
|
||||
_sparseInfo.update();
|
||||
#if INCREMENTAL_TRANSFER
|
||||
_transferState.updateMip();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GL45Texture::continueTransfer() {
|
||||
if (!Texture::getEnableIncrementalTextureTransfers()) {
|
||||
size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1;
|
||||
for (uint8_t face = 0; face < maxFace; ++face) {
|
||||
for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) {
|
||||
auto size = _gpuObject.evalMipDimensions(mipLevel);
|
||||
if (_sparseInfo.sparse && mipLevel <= _sparseInfo.maxSparseLevel) {
|
||||
glTexturePageCommitmentEXT(_id, mipLevel, 0, 0, face, size.x, size.y, 1, GL_TRUE);
|
||||
_allocatedPages += _sparseInfo.getPageCount(size);
|
||||
}
|
||||
if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) {
|
||||
auto mip = _gpuObject.accessStoredMipFace(mipLevel, face);
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat());
|
||||
if (GL_TEXTURE_2D == _target) {
|
||||
glTextureSubImage2D(_id, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData());
|
||||
} else if (GL_TEXTURE_CUBE_MAP == _target) {
|
||||
// DSA ARB does not work on AMD, so use EXT
|
||||
// glTextureSubImage3D(_id, mipLevel, 0, 0, face, size.x, size.y, 1, texelFormat.format, texelFormat.type, mip->readData());
|
||||
auto target = CUBE_FACE_LAYOUT[face];
|
||||
glTextureSubImage2DEXT(_id, target, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData());
|
||||
} else {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
(void)CHECK_GL_ERROR();
|
||||
#if !INCREMENTAL_TRANSFER
|
||||
size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1;
|
||||
for (uint8_t face = 0; face < maxFace; ++face) {
|
||||
for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) {
|
||||
auto size = _gpuObject.evalMipDimensions(mipLevel);
|
||||
if (_sparseInfo.sparse && mipLevel <= _sparseInfo.maxSparseLevel) {
|
||||
glTexturePageCommitmentEXT(_id, mipLevel, 0, 0, face, size.x, size.y, 1, GL_TRUE);
|
||||
_allocatedPages += _sparseInfo.getPageCount(size);
|
||||
}
|
||||
if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) {
|
||||
auto mip = _gpuObject.accessStoredMipFace(mipLevel, face);
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat());
|
||||
if (GL_TEXTURE_2D == _target) {
|
||||
glTextureSubImage2D(_id, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData());
|
||||
} else if (GL_TEXTURE_CUBE_MAP == _target) {
|
||||
// DSA ARB does not work on AMD, so use EXT
|
||||
// glTextureSubImage3D(_id, mipLevel, 0, 0, face, size.x, size.y, 1, texelFormat.format, texelFormat.type, mip->readData());
|
||||
auto target = CUBE_FACE_LAYOUT[face];
|
||||
glTextureSubImage2DEXT(_id, target, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData());
|
||||
} else {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
#else
|
||||
static std::vector<uint8_t> buffer;
|
||||
if (buffer.empty()) {
|
||||
buffer.resize(DEFAULT_PAGE_BUFFER_SIZE);
|
||||
|
@ -458,6 +470,7 @@ bool GL45Texture::continueTransfer() {
|
|||
_lastMipAllocatedPages = _allocatedPages;
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GL45Texture::finishTransfer() {
|
||||
|
|
|
@ -35,18 +35,15 @@ std::atomic<Texture::Size> Texture::_allowedCPUMemoryUsage { 0 };
|
|||
|
||||
|
||||
#define MIN_CORES_FOR_INCREMENTAL_TEXTURES 5
|
||||
bool recommendedIncrementalTransfers = (QThread::idealThreadCount() >= MIN_CORES_FOR_INCREMENTAL_TEXTURES);
|
||||
bool recommendedSparseTextures = recommendedIncrementalTransfers;
|
||||
bool recommendedSparseTextures = (QThread::idealThreadCount() >= MIN_CORES_FOR_INCREMENTAL_TEXTURES);
|
||||
|
||||
std::atomic<bool> Texture::_enableSparseTextures { recommendedIncrementalTransfers };
|
||||
std::atomic<bool> Texture::_enableIncrementalTextureTransfers { recommendedSparseTextures };
|
||||
std::atomic<bool> Texture::_enableSparseTextures { recommendedSparseTextures };
|
||||
|
||||
struct ReportTextureState {
|
||||
ReportTextureState() {
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT]"
|
||||
<< "\n\tidealThreadCount:" << QThread::idealThreadCount()
|
||||
<< "\n\tRECOMMENDED enableSparseTextures:" << recommendedSparseTextures
|
||||
<< "\n\tRECOMMENDED enableIncrementalTextures:" << recommendedIncrementalTransfers;
|
||||
<< "\n\tRECOMMENDED enableSparseTextures:" << recommendedSparseTextures;
|
||||
}
|
||||
} report;
|
||||
|
||||
|
@ -59,16 +56,6 @@ void Texture::setEnableSparseTextures(bool enabled) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Texture::setEnableIncrementalTextureTransfers(bool enabled) {
|
||||
#ifdef Q_OS_WIN
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] SETTING - Enable Incremental Texture Transfer:" << enabled;
|
||||
_enableIncrementalTextureTransfers = enabled;
|
||||
#else
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] Incremental Texture Transfer not supported on this platform.";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Texture::updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize) {
|
||||
if (prevObjectSize == newObjectSize) {
|
||||
return;
|
||||
|
@ -84,10 +71,6 @@ bool Texture::getEnableSparseTextures() {
|
|||
return _enableSparseTextures.load();
|
||||
}
|
||||
|
||||
bool Texture::getEnableIncrementalTextureTransfers() {
|
||||
return _enableIncrementalTextureTransfers.load();
|
||||
}
|
||||
|
||||
uint32_t Texture::getTextureCPUCount() {
|
||||
return _textureCPUCount.load();
|
||||
}
|
||||
|
|
|
@ -143,10 +143,8 @@ class Texture : public Resource {
|
|||
static std::atomic<uint32_t> _textureCPUCount;
|
||||
static std::atomic<Size> _textureCPUMemoryUsage;
|
||||
static std::atomic<Size> _allowedCPUMemoryUsage;
|
||||
static void updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
||||
|
||||
static std::atomic<bool> _enableSparseTextures;
|
||||
static std::atomic<bool> _enableIncrementalTextureTransfers;
|
||||
static void updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
||||
|
||||
public:
|
||||
static uint32_t getTextureCPUCount();
|
||||
|
@ -162,10 +160,7 @@ public:
|
|||
static void setAllowedGPUMemoryUsage(Size size);
|
||||
|
||||
static bool getEnableSparseTextures();
|
||||
static bool getEnableIncrementalTextureTransfers();
|
||||
|
||||
static void setEnableSparseTextures(bool enabled);
|
||||
static void setEnableIncrementalTextureTransfers(bool enabled);
|
||||
|
||||
using ExternalRecycler = std::function<void(uint32, void*)>;
|
||||
using ExternalIdAndFence = std::pair<uint32, void*>;
|
||||
|
|
|
@ -88,7 +88,24 @@ class ScriptableResource : public QObject {
|
|||
Q_PROPERTY(QUrl url READ getUrl)
|
||||
Q_PROPERTY(int state READ getState NOTIFY stateChanged)
|
||||
|
||||
/**jsdoc
|
||||
* @constructor Resource
|
||||
* @property url {string} url of this resource
|
||||
* @property state {Resource.State} current loading state
|
||||
*/
|
||||
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
* @name Resource.State
|
||||
* @static
|
||||
* @property QUEUED {int} The resource is queued up, waiting to be loaded.
|
||||
* @property LOADING {int} The resource is downloading
|
||||
* @property LOADED {int} The resource has finished downloaded by is not complete
|
||||
* @property FINISHED {int} The resource has completly finished loading and is ready.
|
||||
* @property FAILED {int} Downloading the resource has failed.
|
||||
*/
|
||||
|
||||
enum State {
|
||||
QUEUED,
|
||||
LOADING,
|
||||
|
@ -101,6 +118,10 @@ public:
|
|||
ScriptableResource(const QUrl& url);
|
||||
virtual ~ScriptableResource() = default;
|
||||
|
||||
/**jsdoc
|
||||
* Release this resource
|
||||
* @function Resource#release
|
||||
*/
|
||||
Q_INVOKABLE void release();
|
||||
|
||||
const QUrl& getUrl() const { return _url; }
|
||||
|
@ -111,7 +132,22 @@ public:
|
|||
void setInScript(bool isInScript);
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* Signaled when download progress for this resource has changed
|
||||
* @function Resource#progressChanged
|
||||
* @param bytesReceived {int} bytes downloaded so far
|
||||
* @param bytesTotal {int} total number of bytes in the resource
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void progressChanged(uint64_t bytesReceived, uint64_t bytesTotal);
|
||||
|
||||
/**jsdoc
|
||||
* Signaled when resource loading state has changed
|
||||
* @function Resource#stateChanged
|
||||
* @param bytesReceived {Resource.State} new state
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void stateChanged(int state);
|
||||
|
||||
protected:
|
||||
|
@ -148,14 +184,49 @@ class ResourceCache : public QObject {
|
|||
Q_PROPERTY(size_t numCached READ getNumCachedResources NOTIFY dirty)
|
||||
Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty)
|
||||
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @namespace ResourceCache
|
||||
* @property numTotal {number} total number of total resources
|
||||
* @property numCached {number} total number of cached resource
|
||||
* @property sizeTotal {number} size in bytes of all resources
|
||||
* @property sizeCached {number} size in bytes of all cached resources
|
||||
*/
|
||||
|
||||
public:
|
||||
/**jsdoc
|
||||
* Returns the total number of resources
|
||||
* @function ResourceCache.getNumTotalResources
|
||||
* @return {number}
|
||||
*/
|
||||
size_t getNumTotalResources() const { return _numTotalResources; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total size in bytes of all resources
|
||||
* @function ResourceCache.getSizeTotalResources
|
||||
* @return {number}
|
||||
*/
|
||||
size_t getSizeTotalResources() const { return _totalResourcesSize; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total number of cached resources
|
||||
* @function ResourceCache.getNumCachedResources
|
||||
* @return {number}
|
||||
*/
|
||||
size_t getNumCachedResources() const { return _numUnusedResources; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns the total size in bytes of cached resources
|
||||
* @function ResourceCache.getSizeCachedResources
|
||||
* @return {number}
|
||||
*/
|
||||
size_t getSizeCachedResources() const { return _unusedResourcesSize; }
|
||||
|
||||
/**jsdoc
|
||||
* Returns list of all resource urls
|
||||
* @function ResourceCache.getResourceList
|
||||
* @return {string[]}
|
||||
*/
|
||||
Q_INVOKABLE QVariantList getResourceList();
|
||||
|
||||
static void setRequestLimit(int limit);
|
||||
|
@ -192,6 +263,13 @@ protected slots:
|
|||
/// returns an empty smart pointer and loads its asynchronously.
|
||||
/// \param fallback a fallback URL to load if the desired one is unavailable
|
||||
/// \param extra extra data to pass to the creator, if appropriate
|
||||
/**jsdoc
|
||||
* Asynchronously loads a resource from the spedified URL and returns it.
|
||||
* @param url {string} url of resource to load
|
||||
* @param fallback {string} fallback URL if load of the desired url fails
|
||||
* @function ResourceCache.getResource
|
||||
* @return {Resource}
|
||||
*/
|
||||
QSharedPointer<Resource> getResource(const QUrl& url, const QUrl& fallback = QUrl(),
|
||||
void* extra = NULL);
|
||||
|
||||
|
@ -203,6 +281,12 @@ protected:
|
|||
// Pointers created through this method should be owned by the caller,
|
||||
// which should be a QScriptEngine with ScriptableResource registered, so that
|
||||
// the QScriptEngine will delete the pointer when it is garbage collected.
|
||||
/**jsdoc
|
||||
* Prefetches a resource.
|
||||
* @param url {string} url of resource to load
|
||||
* @function ResourceCache.prefetch
|
||||
* @return {Resource}
|
||||
*/
|
||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url) { return prefetch(url, nullptr); }
|
||||
|
||||
/// Creates a new resource.
|
||||
|
|
|
@ -19,13 +19,60 @@
|
|||
|
||||
#include <AssetClient.h>
|
||||
|
||||
/**jsdoc
|
||||
* @namespace Assets
|
||||
*/
|
||||
class AssetScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AssetScriptingInterface(QScriptEngine* engine);
|
||||
|
||||
/**jsdoc
|
||||
* Upload content to the connected domain's asset server.
|
||||
* @function Assets.uploadData
|
||||
* @static
|
||||
* @param data {string} content to upload
|
||||
* @param callback {Assets~uploadDataCallback} called when upload is complete
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Called when uploadData is complete
|
||||
* @callback Assets~uploadDataCallback
|
||||
* @param {string} url
|
||||
* @param {string} hash
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void uploadData(QString data, QScriptValue callback);
|
||||
|
||||
/**jsdoc
|
||||
* Download data from the connected domain's asset server.
|
||||
* @function Assets.downloadData
|
||||
* @static
|
||||
* @param url {string} url of asset to download, must be atp scheme url.
|
||||
* @param callback {Assets~downloadDataCallback}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Called when downloadData is complete
|
||||
* @callback Assets~downloadDataCallback
|
||||
* @param data {string} content that was downloaded
|
||||
*/
|
||||
|
||||
Q_INVOKABLE void downloadData(QString url, QScriptValue downloadComplete);
|
||||
|
||||
/**jsdoc
|
||||
* Sets up a path to hash mapping within the connected domain's asset server
|
||||
* @function Assets.setMapping
|
||||
* @static
|
||||
* @param path {string}
|
||||
* @param hash {string}
|
||||
* @param callback {Assets~setMappingCallback}
|
||||
*/
|
||||
|
||||
/**jsdoc
|
||||
* Called when setMapping is complete
|
||||
* @callback Assets~setMappingCallback
|
||||
*/
|
||||
Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback);
|
||||
|
||||
#if (PR_BUILD || DEV_BUILD)
|
||||
|
|
|
@ -144,6 +144,11 @@ public:
|
|||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { return false; }
|
||||
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) {return false; }
|
||||
|
||||
virtual glm::quat getLocalJointRotation(int index) const {return glm::quat(); }
|
||||
virtual glm::vec3 getLocalJointTranslation(int index) const {return glm::vec3(); }
|
||||
virtual bool setLocalJointRotation(int index, const glm::quat& rotation) { return false; }
|
||||
virtual bool setLocalJointTranslation(int index, const glm::vec3& translation) { return false; }
|
||||
|
||||
SpatiallyNestablePointer getThisPointer() const;
|
||||
|
||||
void markAncestorMissing(bool value) { _missingAncestor = value; }
|
||||
|
|
|
@ -428,6 +428,25 @@ bool Menu::menuExists(const QString& menuName) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Menu::isMenuEnabled(const QString& menuName) {
|
||||
QAction* action = getMenuAction(menuName);
|
||||
|
||||
// only proceed if the menu actually exists
|
||||
if (action) {
|
||||
return action->isEnabled();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Menu::setMenuEnabled(const QString& menuName, bool isEnabled) {
|
||||
QAction* action = getMenuAction(menuName);
|
||||
|
||||
// only proceed if the menu actually exists
|
||||
if (action) {
|
||||
action->setEnabled(isEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::addSeparator(const QString& menuName, const QString& separatorName, const QString& grouping) {
|
||||
MenuWrapper* menuObj = getMenu(menuName);
|
||||
if (menuObj) {
|
||||
|
|
|
@ -106,6 +106,9 @@ public slots:
|
|||
bool isOptionChecked(const QString& menuOption) const;
|
||||
void setIsOptionChecked(const QString& menuOption, bool isChecked);
|
||||
|
||||
bool isMenuEnabled(const QString& menuName);
|
||||
void setMenuEnabled(const QString& menuName, bool isEnabled);
|
||||
|
||||
bool getGroupingIsVisible(const QString& grouping);
|
||||
void setGroupingIsVisible(const QString& grouping, bool isVisible); /// NOTE: the "" grouping is always visible
|
||||
|
||||
|
|
|
@ -24,10 +24,16 @@ var desktopMenuItemName = "Desktop";
|
|||
|
||||
var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system");
|
||||
var button;
|
||||
// Independent and Entity mode make people sick. Third Person and Mirror have traps that we need to work through.
|
||||
// Disable them in hmd.
|
||||
var desktopOnlyViews = ['Third Person', 'Mirror', 'Independent Mode', 'Entity Mode'];
|
||||
function onHmdChanged(isHmd) {
|
||||
button.writeProperty('buttonState', isHmd ? 0 : 1);
|
||||
button.writeProperty('defaultState', isHmd ? 0 : 1);
|
||||
button.writeProperty('hoverState', isHmd ? 2 : 3);
|
||||
desktopOnlyViews.forEach(function (view) {
|
||||
Menu.setMenuEnabled("View>" + view, !isHmd);
|
||||
});
|
||||
}
|
||||
function onClicked(){
|
||||
var isDesktop = Menu.isOptionChecked(desktopMenuItemName);
|
||||
|
|
|
@ -228,7 +228,7 @@ var usersWindow = (function () {
|
|||
|
||||
var WINDOW_WIDTH = 260,
|
||||
WINDOW_MARGIN = 12,
|
||||
WINDOW_BASE_MARGIN = 6, // A little less is needed in order look correct
|
||||
WINDOW_BASE_MARGIN = 24, // A little less is needed in order look correct
|
||||
WINDOW_FONT = {
|
||||
size: 12
|
||||
},
|
||||
|
@ -253,11 +253,17 @@ var usersWindow = (function () {
|
|||
windowPane,
|
||||
windowHeading,
|
||||
|
||||
// Margin on the left and right side of the window to keep
|
||||
// it from getting too close to the edge of the screen which
|
||||
// is unclickable.
|
||||
WINDOW_MARGIN_X = 20,
|
||||
|
||||
// Window border is similar to that of edit.js.
|
||||
WINDOW_BORDER_WIDTH = WINDOW_WIDTH + 2 * WINDOW_BASE_MARGIN,
|
||||
WINDOW_BORDER_TOP_MARGIN = 2 * WINDOW_BASE_MARGIN,
|
||||
WINDOW_BORDER_BOTTOM_MARGIN = WINDOW_BASE_MARGIN,
|
||||
WINDOW_BORDER_LEFT_MARGIN = WINDOW_BASE_MARGIN,
|
||||
WINDOW_MARGIN_HALF = WINDOW_MARGIN / 2,
|
||||
WINDOW_BORDER_WIDTH = WINDOW_WIDTH + 2 * WINDOW_MARGIN_HALF,
|
||||
WINDOW_BORDER_TOP_MARGIN = 2 * WINDOW_MARGIN_HALF,
|
||||
WINDOW_BORDER_BOTTOM_MARGIN = WINDOW_MARGIN_HALF,
|
||||
WINDOW_BORDER_LEFT_MARGIN = WINDOW_MARGIN_HALF,
|
||||
WINDOW_BORDER_RADIUS = 4,
|
||||
WINDOW_BORDER_COLOR = { red: 255, green: 255, blue: 255 },
|
||||
WINDOW_BORDER_ALPHA = 0.5,
|
||||
|
@ -371,7 +377,8 @@ var usersWindow = (function () {
|
|||
|
||||
MENU_NAME = "View",
|
||||
MENU_ITEM = "Users Online",
|
||||
MENU_ITEM_AFTER = "Overlays",
|
||||
MENU_ITEM_OVERLAYS = "Overlays",
|
||||
MENU_ITEM_AFTER = MENU_ITEM_OVERLAYS,
|
||||
|
||||
SETTING_USERS_SHOW_ME = "UsersWindow.ShowMe",
|
||||
SETTING_USERS_VISIBLE_TO = "UsersWindow.VisibleTo",
|
||||
|
@ -399,6 +406,10 @@ var usersWindow = (function () {
|
|||
scrollbarBarClickedAt, // 0.0 .. 1.0
|
||||
scrollbarValue = 0.0; // 0.0 .. 1.0
|
||||
|
||||
function isWindowDisabled() {
|
||||
return !Menu.isOptionChecked(MENU_ITEM) || !Menu.isOptionChecked(MENU_ITEM_OVERLAYS);
|
||||
}
|
||||
|
||||
function isValueTrue(value) {
|
||||
// Work around Boolean Settings values being read as string when Interface starts up but as Booleans when re-read after
|
||||
// Being written if refresh script.
|
||||
|
@ -445,7 +456,7 @@ var usersWindow = (function () {
|
|||
}
|
||||
|
||||
function saturateWindowPosition() {
|
||||
windowPosition.x = Math.max(0, Math.min(viewport.x - WINDOW_WIDTH, windowPosition.x));
|
||||
windowPosition.x = Math.max(WINDOW_MARGIN_X, Math.min(viewport.x - WINDOW_WIDTH - WINDOW_MARGIN_X, windowPosition.x));
|
||||
windowPosition.y = Math.max(windowMinimumHeight, Math.min(viewport.y, windowPosition.y));
|
||||
}
|
||||
|
||||
|
@ -744,7 +755,7 @@ var usersWindow = (function () {
|
|||
userClicked,
|
||||
delta;
|
||||
|
||||
if (!isVisible) {
|
||||
if (!isVisible || isWindowDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -856,7 +867,7 @@ var usersWindow = (function () {
|
|||
function onMouseMoveEvent(event) {
|
||||
var isVisible;
|
||||
|
||||
if (!isLoggedIn) {
|
||||
if (!isLoggedIn || isWindowDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -914,6 +925,10 @@ var usersWindow = (function () {
|
|||
function onMouseReleaseEvent() {
|
||||
var offset = {};
|
||||
|
||||
if (isWindowDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMovingScrollbar) {
|
||||
Overlays.editOverlay(scrollbarBar, {
|
||||
backgroundAlpha: SCROLLBAR_BAR_ALPHA
|
||||
|
@ -939,6 +954,10 @@ var usersWindow = (function () {
|
|||
MIRROR_MENU_ITEM = "Mirror",
|
||||
FULLSCREEN_MIRROR_MENU_ITEM = "Fullscreen Mirror";
|
||||
|
||||
if (isWindowDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
viewport = Controller.getViewportDimensions();
|
||||
isMirrorDisplay = Menu.isOptionChecked(MIRROR_MENU_ITEM);
|
||||
isFullscreenMirror = Menu.isOptionChecked(FULLSCREEN_MIRROR_MENU_ITEM);
|
||||
|
|
1
tools/jsdoc/.gitignore
vendored
Normal file
1
tools/jsdoc/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
out
|
13
tools/jsdoc/README.md
Normal file
13
tools/jsdoc/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
#JavaScript Documentation Generation
|
||||
|
||||
##Prerequisites
|
||||
|
||||
* Install node.js
|
||||
* Install jsdoc via npm. `npm install jsdoc -g`
|
||||
|
||||
To generate html documentation for the High Fidelity JavaScript API
|
||||
|
||||
`cd scripts/jsdoc`
|
||||
`jsdoc . -c config.json`
|
||||
|
||||
The out folder should contain index.html
|
8
tools/jsdoc/config.json
Normal file
8
tools/jsdoc/config.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"templates": {
|
||||
"default": {
|
||||
"outputSourceFiles": false
|
||||
}
|
||||
},
|
||||
"plugins": ["plugins/hifi"]
|
||||
}
|
41
tools/jsdoc/plugins/hifi.js
Normal file
41
tools/jsdoc/plugins/hifi.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
function endsWith(path, exts) {
|
||||
var result = false;
|
||||
exts.forEach(function(ext) {
|
||||
if (path.endsWith(ext)) {
|
||||
result = true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.handlers = {
|
||||
beforeParse: function(e) {
|
||||
console.log("Scanning hifi source for jsdoc comments...");
|
||||
|
||||
// directories to scan for jsdoc comments
|
||||
var dirList = [
|
||||
'../../interface/src',
|
||||
'../../interface/src/scripting',
|
||||
'../../libraries/script-engine/src',
|
||||
'../../libraries/networking/src',
|
||||
'../../libraries/animation/src',
|
||||
];
|
||||
var exts = ['.h', '.cpp'];
|
||||
|
||||
const fs = require('fs');
|
||||
dirList.forEach(function (dir) {
|
||||
var files = fs.readdirSync(dir)
|
||||
files.forEach(function (file) {
|
||||
var path = dir + "/" + file;
|
||||
if (fs.lstatSync(path).isFile() && endsWith(path, exts)) {
|
||||
var data = fs.readFileSync(path, "utf8");
|
||||
var reg = /(\/\*\*jsdoc(.|[\r\n])*?\*\/)/gm;
|
||||
var matches = data.match(reg);
|
||||
if (matches) {
|
||||
e.source += matches.map(function (s) { return s.replace('/**jsdoc', '/**'); }).join('\n');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
11
tools/jsdoc/root.js
Normal file
11
tools/jsdoc/root.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
//
|
||||
// root.js
|
||||
//
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
// Root of High Fidelity generated java script documentation
|
||||
//
|
||||
|
Loading…
Reference in a new issue