mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 12:10:44 +02:00
Merge remote-tracking branch 'upstream/master' into vive-ui
This commit is contained in:
commit
175dbb8924
25 changed files with 210 additions and 491 deletions
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.3
|
import QtQuick 2.3
|
||||||
import QtQuick.Controls 1.2
|
import QtQuick.Controls 1.2
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import "."
|
import "."
|
||||||
|
|
||||||
|
@ -44,6 +45,12 @@ Overlay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColorOverlay {
|
||||||
|
id: color
|
||||||
|
anchors.fill: image
|
||||||
|
source: image
|
||||||
|
}
|
||||||
|
|
||||||
function updateSubImage(subImage) {
|
function updateSubImage(subImage) {
|
||||||
var keys = Object.keys(subImage);
|
var keys = Object.keys(subImage);
|
||||||
for (var i = 0; i < keys.length; ++i) {
|
for (var i = 0; i < keys.length; ++i) {
|
||||||
|
@ -70,6 +77,7 @@ Overlay {
|
||||||
case "alpha": root.opacity = value; break;
|
case "alpha": root.opacity = value; break;
|
||||||
case "imageURL": image.source = value; break;
|
case "imageURL": image.source = value; break;
|
||||||
case "subImage": updateSubImage(value); break;
|
case "subImage": updateSubImage(value); break;
|
||||||
|
case "color": color.color = Qt.rgba(value.red / 255, value.green / 255, value.blue / 255, root.opacity); break;
|
||||||
default: console.log("OVERLAY Unhandled image property " + key);
|
default: console.log("OVERLAY Unhandled image property " + key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,11 +239,13 @@ void Avatar::updateAvatarEntities() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarEntityIDs recentlyDettachedAvatarEntities = getAndClearRecentlyDetachedIDs();
|
AvatarEntityIDs recentlyDettachedAvatarEntities = getAndClearRecentlyDetachedIDs();
|
||||||
foreach (auto entityID, recentlyDettachedAvatarEntities) {
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
if (!_avatarEntityData.contains(entityID)) {
|
foreach (auto entityID, recentlyDettachedAvatarEntities) {
|
||||||
entityTree->deleteEntity(entityID, true, true);
|
if (!_avatarEntityData.contains(entityID)) {
|
||||||
|
entityTree->deleteEntity(entityID, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
|
@ -709,12 +709,14 @@ void MyAvatar::saveData() {
|
||||||
|
|
||||||
settings.beginWriteArray("avatarEntityData");
|
settings.beginWriteArray("avatarEntityData");
|
||||||
int avatarEntityIndex = 0;
|
int avatarEntityIndex = 0;
|
||||||
for (auto entityID : _avatarEntityData.keys()) {
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
settings.setArrayIndex(avatarEntityIndex);
|
for (auto entityID : _avatarEntityData.keys()) {
|
||||||
settings.setValue("id", entityID);
|
settings.setArrayIndex(avatarEntityIndex);
|
||||||
settings.setValue("properties", _avatarEntityData.value(entityID));
|
settings.setValue("id", entityID);
|
||||||
avatarEntityIndex++;
|
settings.setValue("properties", _avatarEntityData.value(entityID));
|
||||||
}
|
avatarEntityIndex++;
|
||||||
|
}
|
||||||
|
});
|
||||||
settings.endArray();
|
settings.endArray();
|
||||||
|
|
||||||
settings.setValue("displayName", _displayName);
|
settings.setValue("displayName", _displayName);
|
||||||
|
|
|
@ -900,7 +900,11 @@ bool AvatarData::processAvatarIdentity(const Identity& identity) {
|
||||||
hasIdentityChanged = true;
|
hasIdentityChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identity.avatarEntityData != _avatarEntityData) {
|
bool avatarEntityDataChanged = false;
|
||||||
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
|
avatarEntityDataChanged = (identity.avatarEntityData != _avatarEntityData);
|
||||||
|
});
|
||||||
|
if (avatarEntityDataChanged) {
|
||||||
setAvatarEntityData(identity.avatarEntityData);
|
setAvatarEntityData(identity.avatarEntityData);
|
||||||
hasIdentityChanged = true;
|
hasIdentityChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -914,7 +918,9 @@ QByteArray AvatarData::identityByteArray() {
|
||||||
QUrl emptyURL("");
|
QUrl emptyURL("");
|
||||||
const QUrl& urlToSend = _skeletonModelURL.scheme() == "file" ? emptyURL : _skeletonModelURL;
|
const QUrl& urlToSend = _skeletonModelURL.scheme() == "file" ? emptyURL : _skeletonModelURL;
|
||||||
|
|
||||||
identityStream << getSessionUUID() << urlToSend << _attachmentData << _displayName << _avatarEntityData;
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
|
identityStream << getSessionUUID() << urlToSend << _attachmentData << _displayName << _avatarEntityData;
|
||||||
|
});
|
||||||
|
|
||||||
return identityData;
|
return identityData;
|
||||||
}
|
}
|
||||||
|
@ -1306,16 +1312,18 @@ QJsonObject AvatarData::toJson() const {
|
||||||
root[JSON_AVATAR_ATTACHEMENTS] = attachmentsJson;
|
root[JSON_AVATAR_ATTACHEMENTS] = attachmentsJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_avatarEntityData.empty()) {
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
QJsonArray avatarEntityJson;
|
if (!_avatarEntityData.empty()) {
|
||||||
for (auto entityID : _avatarEntityData.keys()) {
|
QJsonArray avatarEntityJson;
|
||||||
QVariantMap entityData;
|
for (auto entityID : _avatarEntityData.keys()) {
|
||||||
entityData.insert("id", entityID);
|
QVariantMap entityData;
|
||||||
entityData.insert("properties", _avatarEntityData.value(entityID));
|
entityData.insert("id", entityID);
|
||||||
avatarEntityJson.push_back(QVariant(entityData).toJsonObject());
|
entityData.insert("properties", _avatarEntityData.value(entityID));
|
||||||
|
avatarEntityJson.push_back(QVariant(entityData).toJsonObject());
|
||||||
|
}
|
||||||
|
root[JSON_AVATAR_ENTITIES] = avatarEntityJson;
|
||||||
}
|
}
|
||||||
root[JSON_AVATAR_ENTITIES] = avatarEntityJson;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
auto recordingBasis = getRecordingBasis();
|
auto recordingBasis = getRecordingBasis();
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -1604,8 +1612,10 @@ void AvatarData::updateAvatarEntity(const QUuid& entityID, const QByteArray& ent
|
||||||
QMetaObject::invokeMethod(this, "updateAvatarEntity", Q_ARG(const QUuid&, entityID), Q_ARG(QByteArray, entityData));
|
QMetaObject::invokeMethod(this, "updateAvatarEntity", Q_ARG(const QUuid&, entityID), Q_ARG(QByteArray, entityData));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_avatarEntityData.insert(entityID, entityData);
|
_avatarEntitiesLock.withWriteLock([&] {
|
||||||
_avatarEntityDataLocallyEdited = true;
|
_avatarEntityData.insert(entityID, entityData);
|
||||||
|
_avatarEntityDataLocallyEdited = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::clearAvatarEntity(const QUuid& entityID) {
|
void AvatarData::clearAvatarEntity(const QUuid& entityID) {
|
||||||
|
@ -1613,18 +1623,25 @@ void AvatarData::clearAvatarEntity(const QUuid& entityID) {
|
||||||
QMetaObject::invokeMethod(this, "clearAvatarEntity", Q_ARG(const QUuid&, entityID));
|
QMetaObject::invokeMethod(this, "clearAvatarEntity", Q_ARG(const QUuid&, entityID));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_avatarEntityData.remove(entityID);
|
|
||||||
_avatarEntityDataLocallyEdited = true;
|
_avatarEntitiesLock.withWriteLock([&] {
|
||||||
|
_avatarEntityData.remove(entityID);
|
||||||
|
_avatarEntityDataLocallyEdited = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarEntityMap AvatarData::getAvatarEntityData() const {
|
AvatarEntityMap AvatarData::getAvatarEntityData() const {
|
||||||
|
AvatarEntityMap result;
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
AvatarEntityMap result;
|
|
||||||
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getAvatarEntityData", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getAvatarEntityData", Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(AvatarEntityMap, result));
|
Q_RETURN_ARG(AvatarEntityMap, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return _avatarEntityData;
|
|
||||||
|
_avatarEntitiesLock.withReadLock([&] {
|
||||||
|
result = _avatarEntityData;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) {
|
void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) {
|
||||||
|
@ -1632,29 +1649,33 @@ void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) {
|
||||||
QMetaObject::invokeMethod(this, "setAvatarEntityData", Q_ARG(const AvatarEntityMap&, avatarEntityData));
|
QMetaObject::invokeMethod(this, "setAvatarEntityData", Q_ARG(const AvatarEntityMap&, avatarEntityData));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_avatarEntityData != avatarEntityData) {
|
_avatarEntitiesLock.withWriteLock([&] {
|
||||||
// keep track of entities that were attached to this avatar but no longer are
|
if (_avatarEntityData != avatarEntityData) {
|
||||||
AvatarEntityIDs previousAvatarEntityIDs = QSet<QUuid>::fromList(_avatarEntityData.keys());
|
// keep track of entities that were attached to this avatar but no longer are
|
||||||
|
AvatarEntityIDs previousAvatarEntityIDs = QSet<QUuid>::fromList(_avatarEntityData.keys());
|
||||||
|
|
||||||
_avatarEntityData = avatarEntityData;
|
_avatarEntityData = avatarEntityData;
|
||||||
setAvatarEntityDataChanged(true);
|
setAvatarEntityDataChanged(true);
|
||||||
|
|
||||||
foreach (auto entityID, previousAvatarEntityIDs) {
|
foreach (auto entityID, previousAvatarEntityIDs) {
|
||||||
if (!_avatarEntityData.contains(entityID)) {
|
if (!_avatarEntityData.contains(entityID)) {
|
||||||
_avatarEntityDetached.insert(entityID);
|
_avatarEntityDetached.insert(entityID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarEntityIDs AvatarData::getAndClearRecentlyDetachedIDs() {
|
AvatarEntityIDs AvatarData::getAndClearRecentlyDetachedIDs() {
|
||||||
|
AvatarEntityIDs result;
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
AvatarEntityIDs result;
|
|
||||||
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getRecentlyDetachedIDs", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(const_cast<AvatarData*>(this), "getRecentlyDetachedIDs", Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(AvatarEntityIDs, result));
|
Q_RETURN_ARG(AvatarEntityIDs, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
AvatarEntityIDs result = _avatarEntityDetached;
|
_avatarEntitiesLock.withWriteLock([&] {
|
||||||
_avatarEntityDetached.clear();
|
result = _avatarEntityDetached;
|
||||||
|
_avatarEntityDetached.clear();
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,6 +418,7 @@ protected:
|
||||||
// updates about one avatar to another.
|
// updates about one avatar to another.
|
||||||
glm::vec3 _globalPosition;
|
glm::vec3 _globalPosition;
|
||||||
|
|
||||||
|
mutable ReadWriteLockable _avatarEntitiesLock;
|
||||||
AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar
|
AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar
|
||||||
AvatarEntityMap _avatarEntityData;
|
AvatarEntityMap _avatarEntityData;
|
||||||
bool _avatarEntityDataLocallyEdited { false };
|
bool _avatarEntityDataLocallyEdited { false };
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
set(TARGET_NAME entities-renderer)
|
set(TARGET_NAME entities-renderer)
|
||||||
AUTOSCRIBE_SHADER_LIB(gpu model render render-utils)
|
AUTOSCRIBE_SHADER_LIB(gpu model procedural render render-utils)
|
||||||
setup_hifi_library(Widgets Network Script)
|
setup_hifi_library(Widgets Network Script)
|
||||||
link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils)
|
link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils)
|
||||||
|
|
||||||
|
|
|
@ -1,380 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 2015/09/05
|
|
||||||
// Copyright 2013-2015 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
|
|
||||||
//
|
|
||||||
|
|
||||||
// Shader includes portions of webgl-noise:
|
|
||||||
// Description : Array and textureless GLSL 2D/3D/4D simplex
|
|
||||||
// noise functions.
|
|
||||||
// Author : Ian McEwan, Ashima Arts.
|
|
||||||
// Maintainer : ijm
|
|
||||||
// Lastmod : 20110822 (ijm)
|
|
||||||
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
|
|
||||||
// Distributed under the MIT License. See LICENSE file.
|
|
||||||
// https://github.com/ashima/webgl-noise
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
const QString SHADER_COMMON = R"SHADER(
|
|
||||||
layout(location = 0) out vec4 _fragColor0;
|
|
||||||
layout(location = 1) out vec4 _fragColor1;
|
|
||||||
layout(location = 2) out vec4 _fragColor2;
|
|
||||||
|
|
||||||
// the alpha threshold
|
|
||||||
uniform float alphaThreshold;
|
|
||||||
|
|
||||||
vec2 signNotZero(vec2 v) {
|
|
||||||
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 float32x3_to_oct(in vec3 v) {
|
|
||||||
vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));
|
|
||||||
return ((v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vec3 oct_to_float32x3(in vec2 e) {
|
|
||||||
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
|
|
||||||
if (v.z < 0) {
|
|
||||||
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
|
|
||||||
}
|
|
||||||
return normalize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 snorm12x2_to_unorm8x3(vec2 f) {
|
|
||||||
vec2 u = vec2(round(clamp(f, -1.0, 1.0) * 2047.0 + 2047.0));
|
|
||||||
float t = floor(u.y / 256.0);
|
|
||||||
|
|
||||||
return floor(vec3(
|
|
||||||
u.x / 16.0,
|
|
||||||
fract(u.x / 16.0) * 256.0 + t,
|
|
||||||
u.y - t * 256.0
|
|
||||||
)) / 255.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 unorm8x3_to_snorm12x2(vec3 u) {
|
|
||||||
u *= 255.0;
|
|
||||||
u.y *= (1.0 / 16.0);
|
|
||||||
vec2 s = vec2( u.x * 16.0 + floor(u.y),
|
|
||||||
fract(u.y) * (16.0 * 256.0) + u.z);
|
|
||||||
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
float mod289(float x) {
|
|
||||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 mod289(vec2 x) {
|
|
||||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 mod289(vec3 x) {
|
|
||||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 mod289(vec4 x) {
|
|
||||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float permute(float x) {
|
|
||||||
return mod289(((x*34.0)+1.0)*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 permute(vec3 x) {
|
|
||||||
return mod289(((x*34.0)+1.0)*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 permute(vec4 x) {
|
|
||||||
return mod289(((x*34.0)+1.0)*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float taylorInvSqrt(float r) {
|
|
||||||
return 1.79284291400159 - 0.85373472095314 * r;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 taylorInvSqrt(vec4 r) {
|
|
||||||
return 1.79284291400159 - 0.85373472095314 * r;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 grad4(float j, vec4 ip) {
|
|
||||||
const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
|
|
||||||
vec4 p, s;
|
|
||||||
|
|
||||||
p.xyz = floor(fract(vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
|
|
||||||
p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
|
|
||||||
s = vec4(lessThan(p, vec4(0.0)));
|
|
||||||
p.xyz = p.xyz + (s.xyz * 2.0 - 1.0) * s.www;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (sqrt(5) - 1)/4 = F4, used once below
|
|
||||||
#define F4 0.309016994374947451
|
|
||||||
|
|
||||||
float snoise(vec4 v) {
|
|
||||||
const vec4 C = vec4(0.138196601125011, // (5 - sqrt(5))/20 G4
|
|
||||||
0.276393202250021, // 2 * G4
|
|
||||||
0.414589803375032, // 3 * G4
|
|
||||||
-0.447213595499958); // -1 + 4 * G4
|
|
||||||
|
|
||||||
// First corner
|
|
||||||
vec4 i = floor(v + dot(v, vec4(F4)));
|
|
||||||
vec4 x0 = v - i + dot(i, C.xxxx);
|
|
||||||
|
|
||||||
// Other corners
|
|
||||||
|
|
||||||
// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
|
|
||||||
vec4 i0;
|
|
||||||
vec3 isX = step(x0.yzw, x0.xxx);
|
|
||||||
vec3 isYZ = step(x0.zww, x0.yyz);
|
|
||||||
i0.x = isX.x + isX.y + isX.z;
|
|
||||||
i0.yzw = 1.0 - isX;
|
|
||||||
i0.y += isYZ.x + isYZ.y;
|
|
||||||
i0.zw += 1.0 - isYZ.xy;
|
|
||||||
i0.z += isYZ.z;
|
|
||||||
i0.w += 1.0 - isYZ.z;
|
|
||||||
|
|
||||||
// i0 now contains the unique values 0,1,2,3 in each channel
|
|
||||||
vec4 i3 = clamp(i0, 0.0, 1.0);
|
|
||||||
vec4 i2 = clamp(i0 - 1.0, 0.0, 1.0);
|
|
||||||
vec4 i1 = clamp(i0 - 2.0, 0.0, 1.0);
|
|
||||||
|
|
||||||
vec4 x1 = x0 - i1 + C.xxxx;
|
|
||||||
vec4 x2 = x0 - i2 + C.yyyy;
|
|
||||||
vec4 x3 = x0 - i3 + C.zzzz;
|
|
||||||
vec4 x4 = x0 + C.wwww;
|
|
||||||
|
|
||||||
// Permutations
|
|
||||||
i = mod289(i);
|
|
||||||
float j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x);
|
|
||||||
vec4 j1 = permute(
|
|
||||||
permute(
|
|
||||||
permute(
|
|
||||||
permute(i.w + vec4(i1.w, i2.w, i3.w, 1.0)) + i.z
|
|
||||||
+ vec4(i1.z, i2.z, i3.z, 1.0)) + i.y
|
|
||||||
+ vec4(i1.y, i2.y, i3.y, 1.0)) + i.x
|
|
||||||
+ vec4(i1.x, i2.x, i3.x, 1.0));
|
|
||||||
|
|
||||||
// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
|
|
||||||
// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
|
|
||||||
vec4 ip = vec4(1.0 / 294.0, 1.0 / 49.0, 1.0 / 7.0, 0.0);
|
|
||||||
|
|
||||||
vec4 p0 = grad4(j0, ip);
|
|
||||||
vec4 p1 = grad4(j1.x, ip);
|
|
||||||
vec4 p2 = grad4(j1.y, ip);
|
|
||||||
vec4 p3 = grad4(j1.z, ip);
|
|
||||||
vec4 p4 = grad4(j1.w, ip);
|
|
||||||
|
|
||||||
// Normalise gradients
|
|
||||||
vec4 norm = taylorInvSqrt(
|
|
||||||
vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
|
|
||||||
p0 *= norm.x;
|
|
||||||
p1 *= norm.y;
|
|
||||||
p2 *= norm.z;
|
|
||||||
p3 *= norm.w;
|
|
||||||
p4 *= taylorInvSqrt(dot(p4, p4));
|
|
||||||
|
|
||||||
// Mix contributions from the five corners
|
|
||||||
vec3 m0 = max(0.6 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0);
|
|
||||||
vec2 m1 = max(0.6 - vec2(dot(x3, x3), dot(x4, x4)), 0.0);
|
|
||||||
m0 = m0 * m0;
|
|
||||||
m1 = m1 * m1;
|
|
||||||
return 49.0
|
|
||||||
* (dot(m0 * m0, vec3(dot(p0, x0), dot(p1, x1), dot(p2, x2)))
|
|
||||||
+ dot(m1 * m1, vec2(dot(p3, x3), dot(p4, x4))));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
float snoise(vec3 v) {
|
|
||||||
const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
|
|
||||||
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
|
|
||||||
|
|
||||||
// First corner
|
|
||||||
vec3 i = floor(v + dot(v, C.yyy));
|
|
||||||
vec3 x0 = v - i + dot(i, C.xxx);
|
|
||||||
|
|
||||||
// Other corners
|
|
||||||
vec3 g = step(x0.yzx, x0.xyz);
|
|
||||||
vec3 l = 1.0 - g;
|
|
||||||
vec3 i1 = min(g.xyz, l.zxy);
|
|
||||||
vec3 i2 = max(g.xyz, l.zxy);
|
|
||||||
|
|
||||||
vec3 x1 = x0 - i1 + C.xxx;
|
|
||||||
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
|
|
||||||
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
|
|
||||||
|
|
||||||
// Permutations
|
|
||||||
i = mod289(i);
|
|
||||||
vec4 p = permute(
|
|
||||||
permute(
|
|
||||||
permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y
|
|
||||||
+ vec4(0.0, i1.y, i2.y, 1.0)) + i.x
|
|
||||||
+ vec4(0.0, i1.x, i2.x, 1.0));
|
|
||||||
|
|
||||||
// Gradients: 7x7 points over a square, mapped onto an octahedron.
|
|
||||||
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
|
|
||||||
float n_ = 0.142857142857; // 1.0/7.0
|
|
||||||
vec3 ns = n_ * D.wyz - D.xzx;
|
|
||||||
|
|
||||||
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
|
|
||||||
|
|
||||||
vec4 x_ = floor(j * ns.z);
|
|
||||||
vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)
|
|
||||||
|
|
||||||
vec4 x = x_ * ns.x + ns.yyyy;
|
|
||||||
vec4 y = y_ * ns.x + ns.yyyy;
|
|
||||||
vec4 h = 1.0 - abs(x) - abs(y);
|
|
||||||
|
|
||||||
vec4 b0 = vec4(x.xy, y.xy);
|
|
||||||
vec4 b1 = vec4(x.zw, y.zw);
|
|
||||||
|
|
||||||
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
|
|
||||||
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
|
|
||||||
vec4 s0 = floor(b0) * 2.0 + 1.0;
|
|
||||||
vec4 s1 = floor(b1) * 2.0 + 1.0;
|
|
||||||
vec4 sh = -step(h, vec4(0.0));
|
|
||||||
|
|
||||||
vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
|
|
||||||
vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
|
|
||||||
|
|
||||||
vec3 p0 = vec3(a0.xy, h.x);
|
|
||||||
vec3 p1 = vec3(a0.zw, h.y);
|
|
||||||
vec3 p2 = vec3(a1.xy, h.z);
|
|
||||||
vec3 p3 = vec3(a1.zw, h.w);
|
|
||||||
|
|
||||||
//Normalise gradients
|
|
||||||
vec4 norm = taylorInvSqrt(
|
|
||||||
vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
|
|
||||||
p0 *= norm.x;
|
|
||||||
p1 *= norm.y;
|
|
||||||
p2 *= norm.z;
|
|
||||||
p3 *= norm.w;
|
|
||||||
|
|
||||||
// Mix final noise value
|
|
||||||
vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)),
|
|
||||||
0.0);
|
|
||||||
m = m * m;
|
|
||||||
return 42.0
|
|
||||||
* dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
|
|
||||||
}
|
|
||||||
|
|
||||||
float snoise(vec2 v) {
|
|
||||||
const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
|
|
||||||
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
|
|
||||||
-0.577350269189626, // -1.0 + 2.0 * C.x
|
|
||||||
0.024390243902439); // 1.0 / 41.0
|
|
||||||
// First corner
|
|
||||||
vec2 i = floor(v + dot(v, C.yy));
|
|
||||||
vec2 x0 = v - i + dot(i, C.xx);
|
|
||||||
|
|
||||||
// Other corners
|
|
||||||
vec2 i1;
|
|
||||||
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
|
||||||
vec4 x12 = x0.xyxy + C.xxzz;
|
|
||||||
x12.xy -= i1;
|
|
||||||
|
|
||||||
// Permutations
|
|
||||||
i = mod289(i); // Avoid truncation effects in permutation
|
|
||||||
vec3 p = permute(
|
|
||||||
permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));
|
|
||||||
|
|
||||||
vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)),
|
|
||||||
0.0);
|
|
||||||
m = m * m;
|
|
||||||
m = m * m;
|
|
||||||
|
|
||||||
// Gradients: 41 points uniformly over a line, mapped onto a diamond.
|
|
||||||
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
|
|
||||||
|
|
||||||
vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
|
||||||
vec3 h = abs(x) - 0.5;
|
|
||||||
vec3 ox = floor(x + 0.5);
|
|
||||||
vec3 a0 = x - ox;
|
|
||||||
|
|
||||||
// Normalise gradients implicitly by scaling m
|
|
||||||
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
|
|
||||||
m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
|
|
||||||
|
|
||||||
// Compute final noise value at P
|
|
||||||
vec3 g;
|
|
||||||
g.x = a0.x * x0.x + h.x * x0.y;
|
|
||||||
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
|
||||||
return 130.0 * dot(m, g);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
in vec3 _normal;
|
|
||||||
in vec3 _color;
|
|
||||||
in vec2 _texCoord0;
|
|
||||||
in vec4 _position;
|
|
||||||
|
|
||||||
// TODO add more uniforms
|
|
||||||
uniform float iGlobalTime; // shader playback time (in seconds)
|
|
||||||
uniform vec3 iWorldScale; // the dimensions of the object being rendered
|
|
||||||
|
|
||||||
// TODO add support for textures
|
|
||||||
// TODO document available inputs other than the uniforms
|
|
||||||
// TODO provide world scale in addition to the untransformed position
|
|
||||||
|
|
||||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
|
||||||
const float DEFAULT_SHININESS = 10;
|
|
||||||
|
|
||||||
)SHADER";
|
|
||||||
|
|
||||||
// V1 shaders, only support emissive
|
|
||||||
// vec4 getProceduralColor()
|
|
||||||
const QString SHADER_TEMPLATE_V1 = SHADER_COMMON + R"SCRIBE(
|
|
||||||
|
|
||||||
#line 1001
|
|
||||||
%1
|
|
||||||
#line 317
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
vec4 emissive = getProceduralColor();
|
|
||||||
|
|
||||||
float alpha = emissive.a;
|
|
||||||
if (alpha != 1.0) {
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 diffuse = vec4(_color.rgb, alpha);
|
|
||||||
vec4 normal = vec4(packNormal(normalize(_normal)), 0.5);
|
|
||||||
|
|
||||||
_fragColor0 = diffuse;
|
|
||||||
_fragColor1 = normal;
|
|
||||||
_fragColor2 = vec4(emissive.rgb, DEFAULT_SHININESS / 128.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
)SCRIBE";
|
|
||||||
|
|
||||||
// void getProceduralDiffuseAndEmissive(out vec4 diffuse, out vec4 emissive)
|
|
||||||
const QString SHADER_TEMPLATE_V2 = SHADER_COMMON + R"SCRIBE(
|
|
||||||
// FIXME should we be doing the swizzle here?
|
|
||||||
vec3 iResolution = iWorldScale.xzy;
|
|
||||||
|
|
||||||
// FIXME Mouse X,Y coordinates, and Z,W are for the click position if clicked (not supported in High Fidelity at the moment)
|
|
||||||
vec4 iMouse = vec4(0);
|
|
||||||
|
|
||||||
// FIXME We set the seconds (iDate.w) of iDate to iGlobalTime, which contains the current date in seconds
|
|
||||||
vec4 iDate = vec4(0, 0, 0, iGlobalTime);
|
|
||||||
|
|
||||||
|
|
||||||
#line 1001
|
|
||||||
%1
|
|
||||||
#line 351
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
vec3 diffuse = _color.rgb;
|
|
||||||
vec3 specular = DEFAULT_SPECULAR;
|
|
||||||
float shininess = DEFAULT_SHININESS;
|
|
||||||
|
|
||||||
float emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
|
||||||
|
|
||||||
_fragColor0 = vec4(diffuse.rgb, 1.0);
|
|
||||||
_fragColor1 = vec4(packNormal(normalize(_normal.xyz)), 1.0 - (emissiveAmount / 2.0));
|
|
||||||
_fragColor2 = vec4(specular, shininess / 128.0);
|
|
||||||
}
|
|
||||||
)SCRIBE";
|
|
|
@ -98,7 +98,7 @@ void RenderableShapeEntityItem::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
|
batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
|
||||||
if (_procedural->ready()) {
|
if (_procedural->ready()) {
|
||||||
_procedural->prepare(batch, getPosition(), getDimensions());
|
_procedural->prepare(batch, getPosition(), getDimensions(), getOrientation());
|
||||||
auto outColor = _procedural->getColor(color);
|
auto outColor = _procedural->getColor(color);
|
||||||
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
||||||
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
|
DependencyManager::get<GeometryCache>()->renderShape(batch, MAPPING[_shape]);
|
||||||
|
|
|
@ -261,7 +261,14 @@ void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
||||||
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
||||||
while (itemItr != _simpleKinematicEntities.end()) {
|
while (itemItr != _simpleKinematicEntities.end()) {
|
||||||
EntityItemPointer entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
|
|
||||||
|
// The entity-server doesn't know where avatars are, so don't attempt to do simple extrapolation for
|
||||||
|
// children of avatars. See related code in EntityMotionState::remoteSimulationOutOfSync.
|
||||||
|
bool ancestryIsKnown;
|
||||||
|
entity->getMaximumAACube(ancestryIsKnown);
|
||||||
|
bool hasAvatarAncestor = entity->hasAncestorOfType(NestableType::Avatar);
|
||||||
|
|
||||||
|
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo() && ancestryIsKnown && !hasAvatarAncestor) {
|
||||||
entity->simulate(now);
|
entity->simulate(now);
|
||||||
_entitiesToSort.insert(entity);
|
_entitiesToSort.insert(entity);
|
||||||
++itemItr;
|
++itemItr;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
set(TARGET_NAME gpu-gl)
|
set(TARGET_NAME gpu-gl)
|
||||||
AUTOSCRIBE_SHADER_LIB(gpu)
|
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared gl gpu)
|
link_hifi_libraries(shared gl gpu)
|
||||||
GroupSources("src")
|
GroupSources("src")
|
||||||
|
|
|
@ -114,6 +114,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
||||||
(&::gpu::gl::GLBackend::do_glUniform3fv),
|
(&::gpu::gl::GLBackend::do_glUniform3fv),
|
||||||
(&::gpu::gl::GLBackend::do_glUniform4fv),
|
(&::gpu::gl::GLBackend::do_glUniform4fv),
|
||||||
(&::gpu::gl::GLBackend::do_glUniform4iv),
|
(&::gpu::gl::GLBackend::do_glUniform4iv),
|
||||||
|
(&::gpu::gl::GLBackend::do_glUniformMatrix3fv),
|
||||||
(&::gpu::gl::GLBackend::do_glUniformMatrix4fv),
|
(&::gpu::gl::GLBackend::do_glUniformMatrix4fv),
|
||||||
|
|
||||||
(&::gpu::gl::GLBackend::do_glColor4f),
|
(&::gpu::gl::GLBackend::do_glColor4f),
|
||||||
|
@ -515,6 +516,22 @@ void GLBackend::do_glUniform4iv(Batch& batch, size_t paramOffset) {
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLBackend::do_glUniformMatrix3fv(Batch& batch, size_t paramOffset) {
|
||||||
|
if (_pipeline._program == 0) {
|
||||||
|
// We should call updatePipeline() to bind the program but we are not doing that
|
||||||
|
// because these uniform setters are deprecated and we don;t want to create side effect
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updatePipeline();
|
||||||
|
|
||||||
|
glUniformMatrix3fv(
|
||||||
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int),
|
||||||
|
batch._params[paramOffset + 2]._uint,
|
||||||
|
batch._params[paramOffset + 1]._uint,
|
||||||
|
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||||
|
(void)CHECK_GL_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
void GLBackend::do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) {
|
||||||
if (_pipeline._program == 0) {
|
if (_pipeline._program == 0) {
|
||||||
// We should call updatePipeline() to bind the program but we are not doing that
|
// We should call updatePipeline() to bind the program but we are not doing that
|
||||||
|
|
|
@ -136,6 +136,7 @@ public:
|
||||||
virtual void do_glUniform3fv(Batch& batch, size_t paramOffset) final;
|
virtual void do_glUniform3fv(Batch& batch, size_t paramOffset) final;
|
||||||
virtual void do_glUniform4fv(Batch& batch, size_t paramOffset) final;
|
virtual void do_glUniform4fv(Batch& batch, size_t paramOffset) final;
|
||||||
virtual void do_glUniform4iv(Batch& batch, size_t paramOffset) final;
|
virtual void do_glUniform4iv(Batch& batch, size_t paramOffset) final;
|
||||||
|
virtual void do_glUniformMatrix3fv(Batch& batch, size_t paramOffset) final;
|
||||||
virtual void do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) final;
|
virtual void do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) final;
|
||||||
|
|
||||||
virtual void do_glColor4f(Batch& batch, size_t paramOffset) final;
|
virtual void do_glColor4f(Batch& batch, size_t paramOffset) final;
|
||||||
|
|
|
@ -567,6 +567,16 @@ void Batch::_glUniform4iv(int32 location, int count, const int32* value) {
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Batch::_glUniformMatrix3fv(int32 location, int count, uint8 transpose, const float* value) {
|
||||||
|
ADD_COMMAND(glUniformMatrix3fv);
|
||||||
|
|
||||||
|
const int MATRIX3_SIZE = 9 * sizeof(float);
|
||||||
|
_params.push_back(cacheData(count * MATRIX3_SIZE, value));
|
||||||
|
_params.push_back(transpose);
|
||||||
|
_params.push_back(count);
|
||||||
|
_params.push_back(location);
|
||||||
|
}
|
||||||
|
|
||||||
void Batch::_glUniformMatrix4fv(int32 location, int count, uint8 transpose, const float* value) {
|
void Batch::_glUniformMatrix4fv(int32 location, int count, uint8 transpose, const float* value) {
|
||||||
ADD_COMMAND(glUniformMatrix4fv);
|
ADD_COMMAND(glUniformMatrix4fv);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
#include <shared/NsightHelpers.h>
|
#include <shared/NsightHelpers.h>
|
||||||
|
|
||||||
|
@ -269,6 +270,7 @@ public:
|
||||||
void _glUniform3fv(int location, int count, const float* value);
|
void _glUniform3fv(int location, int count, const float* value);
|
||||||
void _glUniform4fv(int location, int count, const float* value);
|
void _glUniform4fv(int location, int count, const float* value);
|
||||||
void _glUniform4iv(int location, int count, const int* value);
|
void _glUniform4iv(int location, int count, const int* value);
|
||||||
|
void _glUniformMatrix3fv(int location, int count, unsigned char transpose, const float* value);
|
||||||
void _glUniformMatrix4fv(int location, int count, unsigned char transpose, const float* value);
|
void _glUniformMatrix4fv(int location, int count, unsigned char transpose, const float* value);
|
||||||
|
|
||||||
void _glUniform(int location, int v0) {
|
void _glUniform(int location, int v0) {
|
||||||
|
@ -291,6 +293,10 @@ public:
|
||||||
_glUniform4f(location, v.x, v.y, v.z, v.w);
|
_glUniform4f(location, v.x, v.y, v.z, v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glUniform(int location, const glm::mat3& v) {
|
||||||
|
_glUniformMatrix3fv(location, 1, false, glm::value_ptr(v));
|
||||||
|
}
|
||||||
|
|
||||||
void _glColor4f(float red, float green, float blue, float alpha);
|
void _glColor4f(float red, float green, float blue, float alpha);
|
||||||
|
|
||||||
enum Command {
|
enum Command {
|
||||||
|
@ -348,6 +354,7 @@ public:
|
||||||
COMMAND_glUniform3fv,
|
COMMAND_glUniform3fv,
|
||||||
COMMAND_glUniform4fv,
|
COMMAND_glUniform4fv,
|
||||||
COMMAND_glUniform4iv,
|
COMMAND_glUniform4iv,
|
||||||
|
COMMAND_glUniformMatrix3fv,
|
||||||
COMMAND_glUniformMatrix4fv,
|
COMMAND_glUniformMatrix4fv,
|
||||||
|
|
||||||
COMMAND_glColor4f,
|
COMMAND_glColor4f,
|
||||||
|
@ -446,7 +453,7 @@ public:
|
||||||
Params _params;
|
Params _params;
|
||||||
Bytes _data;
|
Bytes _data;
|
||||||
|
|
||||||
// SSBO class... layout MUST match the layout in TransformCamera.slh
|
// SSBO class... layout MUST match the layout in Transform.slh
|
||||||
class TransformObject {
|
class TransformObject {
|
||||||
public:
|
public:
|
||||||
Mat4 _model;
|
Mat4 _model;
|
||||||
|
|
|
@ -95,7 +95,7 @@ public:
|
||||||
virtual void syncCache() = 0;
|
virtual void syncCache() = 0;
|
||||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
||||||
|
|
||||||
// UBO class... layout MUST match the layout in TransformCamera.slh
|
// UBO class... layout MUST match the layout in Transform.slh
|
||||||
class TransformCamera {
|
class TransformCamera {
|
||||||
public:
|
public:
|
||||||
mutable Mat4 _view;
|
mutable Mat4 _view;
|
||||||
|
|
|
@ -27,6 +27,10 @@ layout(std140) uniform transformCameraBuffer {
|
||||||
TransformCamera getTransformCamera() {
|
TransformCamera getTransformCamera() {
|
||||||
return _camera;
|
return _camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 getEyeWorldPos() {
|
||||||
|
return _camera._viewInverse[3].xyz;
|
||||||
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,10 +85,10 @@ void EntityMotionState::updateServerPhysicsVariables() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_serverPosition = _entity->getPosition();
|
Transform localTransform;
|
||||||
_serverRotation = _entity->getRotation();
|
_entity->getLocalTransformAndVelocities(localTransform, _serverVelocity, _serverAngularVelocity);
|
||||||
_serverVelocity = _entity->getVelocity();
|
_serverPosition = localTransform.getTranslation();
|
||||||
_serverAngularVelocity = _entity->getAngularVelocity();
|
_serverRotation = localTransform.getRotation();
|
||||||
_serverAcceleration = _entity->getAcceleration();
|
_serverAcceleration = _entity->getAcceleration();
|
||||||
_serverActionData = _entity->getActionData();
|
_serverActionData = _entity->getActionData();
|
||||||
}
|
}
|
||||||
|
@ -271,14 +271,25 @@ bool EntityMotionState::isCandidateForOwnership() const {
|
||||||
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
// NOTE: we only get here if we think we own the simulation
|
// NOTE: we only get here if we think we own the simulation
|
||||||
assert(_body);
|
assert(_body);
|
||||||
|
|
||||||
|
bool parentTransformSuccess;
|
||||||
|
Transform localToWorld = _entity->getParentTransform(parentTransformSuccess);
|
||||||
|
Transform worldToLocal;
|
||||||
|
Transform worldVelocityToLocal;
|
||||||
|
if (parentTransformSuccess) {
|
||||||
|
localToWorld.evalInverse(worldToLocal);
|
||||||
|
worldVelocityToLocal = worldToLocal;
|
||||||
|
worldVelocityToLocal.setTranslation(glm::vec3(0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
// if we've never checked before, our _lastStep will be 0, and we need to initialize our state
|
// if we've never checked before, our _lastStep will be 0, and we need to initialize our state
|
||||||
if (_lastStep == 0) {
|
if (_lastStep == 0) {
|
||||||
btTransform xform = _body->getWorldTransform();
|
btTransform xform = _body->getWorldTransform();
|
||||||
_serverPosition = bulletToGLM(xform.getOrigin());
|
_serverPosition = worldToLocal.transform(bulletToGLM(xform.getOrigin()));
|
||||||
_serverRotation = bulletToGLM(xform.getRotation());
|
_serverRotation = worldToLocal.getRotation() * bulletToGLM(xform.getRotation());
|
||||||
_serverVelocity = getBodyLinearVelocityGTSigma();
|
_serverVelocity = worldVelocityToLocal.transform(getBodyLinearVelocityGTSigma());
|
||||||
_serverAcceleration = Vectors::ZERO;
|
_serverAcceleration = Vectors::ZERO;
|
||||||
_serverAngularVelocity = bulletToGLM(_body->getAngularVelocity());
|
_serverAngularVelocity = worldVelocityToLocal.transform(bulletToGLM(_body->getAngularVelocity()));
|
||||||
_lastStep = simulationStep;
|
_lastStep = simulationStep;
|
||||||
_serverActionData = _entity->getActionData();
|
_serverActionData = _entity->getActionData();
|
||||||
_numInactiveUpdates = 1;
|
_numInactiveUpdates = 1;
|
||||||
|
@ -315,11 +326,21 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
|
|
||||||
_lastStep = simulationStep;
|
_lastStep = simulationStep;
|
||||||
if (glm::length2(_serverVelocity) > 0.0f) {
|
if (glm::length2(_serverVelocity) > 0.0f) {
|
||||||
_serverVelocity += _serverAcceleration * dt;
|
// the entity-server doesn't know where avatars are, so it doesn't do simple extrapolation for children of
|
||||||
_serverVelocity *= powf(1.0f - _body->getLinearDamping(), dt);
|
// avatars. We are trying to guess what values the entity server has, so we don't do it here, either. See
|
||||||
// NOTE: we ignore the second-order acceleration term when integrating
|
// related code in EntitySimulation::moveSimpleKinematics.
|
||||||
// the position forward because Bullet also does this.
|
bool ancestryIsKnown;
|
||||||
_serverPosition += dt * _serverVelocity;
|
_entity->getMaximumAACube(ancestryIsKnown);
|
||||||
|
bool hasAvatarAncestor = _entity->hasAncestorOfType(NestableType::Avatar);
|
||||||
|
|
||||||
|
if (ancestryIsKnown && !hasAvatarAncestor) {
|
||||||
|
_serverVelocity += _serverAcceleration * dt;
|
||||||
|
_serverVelocity *= powf(1.0f - _body->getLinearDamping(), dt);
|
||||||
|
|
||||||
|
// NOTE: we ignore the second-order acceleration term when integrating
|
||||||
|
// the position forward because Bullet also does this.
|
||||||
|
_serverPosition += dt * _serverVelocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_entity->actionDataNeedsTransmit()) {
|
if (_entity->actionDataNeedsTransmit()) {
|
||||||
|
@ -341,7 +362,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
// compute position error
|
// compute position error
|
||||||
|
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
|
glm::vec3 position = worldToLocal.transform(bulletToGLM(worldTrans.getOrigin()));
|
||||||
|
|
||||||
float dx2 = glm::distance2(position, _serverPosition);
|
float dx2 = glm::distance2(position, _serverPosition);
|
||||||
const float MAX_POSITION_ERROR_SQUARED = 0.000004f; // corresponds to 2mm
|
const float MAX_POSITION_ERROR_SQUARED = 0.000004f; // corresponds to 2mm
|
||||||
|
@ -376,7 +397,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const float MIN_ROTATION_DOT = 0.99999f; // This corresponds to about 0.5 degrees of rotation
|
const float MIN_ROTATION_DOT = 0.99999f; // This corresponds to about 0.5 degrees of rotation
|
||||||
glm::quat actualRotation = bulletToGLM(worldTrans.getRotation());
|
glm::quat actualRotation = worldToLocal.getRotation() * bulletToGLM(worldTrans.getRotation());
|
||||||
|
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
if ((fabsf(glm::dot(actualRotation, _serverRotation)) < MIN_ROTATION_DOT)) {
|
if ((fabsf(glm::dot(actualRotation, _serverRotation)) < MIN_ROTATION_DOT)) {
|
||||||
|
@ -481,11 +502,11 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
}
|
}
|
||||||
|
|
||||||
// remember properties for local server prediction
|
// remember properties for local server prediction
|
||||||
_serverPosition = _entity->getPosition();
|
Transform localTransform;
|
||||||
_serverRotation = _entity->getRotation();
|
_entity->getLocalTransformAndVelocities(localTransform, _serverVelocity, _serverAngularVelocity);
|
||||||
_serverVelocity = _entity->getVelocity();
|
_serverPosition = localTransform.getTranslation();
|
||||||
|
_serverRotation = localTransform.getRotation();
|
||||||
_serverAcceleration = _entity->getAcceleration();
|
_serverAcceleration = _entity->getAcceleration();
|
||||||
_serverAngularVelocity = _entity->getAngularVelocity();
|
|
||||||
_serverActionData = _entity->getActionData();
|
_serverActionData = _entity->getActionData();
|
||||||
|
|
||||||
EntityItemProperties properties;
|
EntityItemProperties properties;
|
||||||
|
@ -590,7 +611,7 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
|
||||||
if (_body && _entity) {
|
if (_body && _entity) {
|
||||||
dirtyFlags = _entity->getDirtyFlags();
|
dirtyFlags = _entity->getDirtyFlags();
|
||||||
|
|
||||||
if (dirtyFlags | Simulation::DIRTY_SIMULATOR_ID) {
|
if (dirtyFlags & Simulation::DIRTY_SIMULATOR_ID) {
|
||||||
// when SIMULATOR_ID changes we must check for reinterpretation of asymmetric collision mask
|
// when SIMULATOR_ID changes we must check for reinterpretation of asymmetric collision mask
|
||||||
// bits for the avatar groups (e.g. MY_AVATAR vs OTHER_AVATAR)
|
// bits for the avatar groups (e.g. MY_AVATAR vs OTHER_AVATAR)
|
||||||
uint8_t entityCollisionMask = _entity->getCollisionless() ? 0 : _entity->getCollisionMask();
|
uint8_t entityCollisionMask = _entity->getCollisionless() ? 0 : _entity->getCollisionMask();
|
||||||
|
@ -603,8 +624,12 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
|
||||||
// we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings
|
// we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings
|
||||||
int bodyFlags = _body->getCollisionFlags();
|
int bodyFlags = _body->getCollisionFlags();
|
||||||
bool isMoving = _entity->isMovingRelativeToParent();
|
bool isMoving = _entity->isMovingRelativeToParent();
|
||||||
if (((bodyFlags & btCollisionObject::CF_STATIC_OBJECT) && isMoving) ||
|
|
||||||
(bodyFlags & btCollisionObject::CF_KINEMATIC_OBJECT && !isMoving)) {
|
if (((bodyFlags & btCollisionObject::CF_STATIC_OBJECT) && isMoving) // ||
|
||||||
|
// TODO -- there is opportunity for an optimization here, but this currently causes
|
||||||
|
// excessive re-insertion of the rigid body.
|
||||||
|
// (bodyFlags & btCollisionObject::CF_KINEMATIC_OBJECT && !isMoving)
|
||||||
|
) {
|
||||||
dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
#include "ProceduralShaders.h"
|
#include "ProceduralCommon_frag.h"
|
||||||
|
|
||||||
// Userdata parsing constants
|
// Userdata parsing constants
|
||||||
static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
|
static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
|
||||||
|
@ -39,6 +39,7 @@ static const std::string STANDARD_UNIFORM_NAMES[Procedural::NUM_STANDARD_UNIFORM
|
||||||
"iFrameCount",
|
"iFrameCount",
|
||||||
"iWorldScale",
|
"iWorldScale",
|
||||||
"iWorldPosition",
|
"iWorldPosition",
|
||||||
|
"iWorldOrientation",
|
||||||
"iChannelResolution"
|
"iChannelResolution"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,9 +203,10 @@ bool Procedural::ready() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size) {
|
void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation) {
|
||||||
_entityDimensions = size;
|
_entityDimensions = size;
|
||||||
_entityPosition = position;
|
_entityPosition = position;
|
||||||
|
_entityOrientation = glm::mat3_cast(orientation);
|
||||||
if (_shaderUrl.isLocalFile()) {
|
if (_shaderUrl.isLocalFile()) {
|
||||||
auto lastModified = (quint64)QFileInfo(_shaderPath).lastModified().toMSecsSinceEpoch();
|
auto lastModified = (quint64)QFileInfo(_shaderPath).lastModified().toMSecsSinceEpoch();
|
||||||
if (lastModified > _shaderModified) {
|
if (lastModified > _shaderModified) {
|
||||||
|
@ -227,7 +229,7 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
|
||||||
std::string fragmentShaderSource = _fragmentSource;
|
std::string fragmentShaderSource = _fragmentSource;
|
||||||
size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK);
|
size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK);
|
||||||
if (replaceIndex != std::string::npos) {
|
if (replaceIndex != std::string::npos) {
|
||||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), SHADER_COMMON);
|
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), ProceduralCommon_frag);
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION);
|
replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION);
|
||||||
|
@ -404,10 +406,10 @@ void Procedural::setupUniforms() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[SCALE]) {
|
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[ORIENTATION]) {
|
||||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||||
batch._glUniform(_standardUniformSlots[SCALE], _entityDimensions);
|
batch._glUniform(_standardUniformSlots[ORIENTATION], _entityOrientation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
void parse(const QString& userDataJson);
|
void parse(const QString& userDataJson);
|
||||||
|
|
||||||
bool ready();
|
bool ready();
|
||||||
void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size);
|
void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation);
|
||||||
const gpu::ShaderPointer& getShader() const { return _shader; }
|
const gpu::ShaderPointer& getShader() const { return _shader; }
|
||||||
|
|
||||||
glm::vec4 getColor(const glm::vec4& entityColor);
|
glm::vec4 getColor(const glm::vec4& entityColor);
|
||||||
|
@ -56,6 +56,7 @@ public:
|
||||||
FRAME_COUNT,
|
FRAME_COUNT,
|
||||||
SCALE,
|
SCALE,
|
||||||
POSITION,
|
POSITION,
|
||||||
|
ORIENTATION,
|
||||||
CHANNEL_RESOLUTION,
|
CHANNEL_RESOLUTION,
|
||||||
NUM_STANDARD_UNIFORMS
|
NUM_STANDARD_UNIFORMS
|
||||||
};
|
};
|
||||||
|
@ -93,6 +94,7 @@ protected:
|
||||||
// Entity metadata
|
// Entity metadata
|
||||||
glm::vec3 _entityDimensions;
|
glm::vec3 _entityDimensions;
|
||||||
glm::vec3 _entityPosition;
|
glm::vec3 _entityPosition;
|
||||||
|
glm::mat3 _entityOrientation;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This should only be called from the render thread, as it shares data with Procedural::prepare
|
// This should only be called from the render thread, as it shares data with Procedural::prepare
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
// Created by Bradley Austin Davis on 2015/09/05
|
// Created by Bradley Austin Davis on 2015/09/05
|
||||||
// Copyright 2013-2015 High Fidelity, Inc.
|
// Copyright 2013-2015 High Fidelity, Inc.
|
||||||
|
@ -17,11 +19,11 @@
|
||||||
// https://github.com/ashima/webgl-noise
|
// https://github.com/ashima/webgl-noise
|
||||||
//
|
//
|
||||||
|
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
const std::string SHADER_COMMON = R"SHADER(
|
<$declareStandardCameraTransform()$>
|
||||||
|
|
||||||
float mod289(float x) {
|
float mod289(float x) {
|
||||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 mod289(vec2 x) {
|
vec2 mod289(vec2 x) {
|
||||||
|
@ -262,11 +264,6 @@ float snoise(vec2 v) {
|
||||||
return 130.0 * dot(m, g);
|
return 130.0 * dot(m, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
// shader playback time (in seconds)
|
|
||||||
uniform float iGlobalTime;
|
|
||||||
// the dimensions of the object being rendered
|
|
||||||
uniform vec3 iWorldScale;
|
|
||||||
|
|
||||||
#define PROCEDURAL 1
|
#define PROCEDURAL 1
|
||||||
|
|
||||||
//PROCEDURAL_VERSION
|
//PROCEDURAL_VERSION
|
||||||
|
@ -286,15 +283,16 @@ const float iSampleRate = 1.0;
|
||||||
const vec4 iChannelTime = vec4(0.0);
|
const vec4 iChannelTime = vec4(0.0);
|
||||||
|
|
||||||
|
|
||||||
|
uniform float iGlobalTime; // shader playback time (in seconds)
|
||||||
uniform vec4 iDate;
|
uniform vec4 iDate;
|
||||||
uniform int iFrameCount;
|
uniform int iFrameCount;
|
||||||
uniform vec3 iWorldPosition;
|
uniform vec3 iWorldPosition; // the position of the object being rendered
|
||||||
|
uniform vec3 iWorldScale; // the dimensions of the object being rendered
|
||||||
|
uniform mat3 iWorldOrientation; // the orientation of the object being rendered
|
||||||
uniform vec3 iChannelResolution[4];
|
uniform vec3 iChannelResolution[4];
|
||||||
uniform sampler2D iChannel0;
|
uniform sampler2D iChannel0;
|
||||||
uniform sampler2D iChannel1;
|
uniform sampler2D iChannel1;
|
||||||
uniform sampler2D iChannel2;
|
uniform sampler2D iChannel2;
|
||||||
uniform sampler2D iChannel3;
|
uniform sampler2D iChannel3;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
)SHADER";
|
|
|
@ -52,7 +52,7 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum,
|
||||||
batch.setModelTransform(Transform()); // only for Mac
|
batch.setModelTransform(Transform()); // only for Mac
|
||||||
|
|
||||||
auto& procedural = skybox._procedural;
|
auto& procedural = skybox._procedural;
|
||||||
procedural.prepare(batch, glm::vec3(0), glm::vec3(1));
|
procedural.prepare(batch, glm::vec3(0), glm::vec3(1), glm::quat());
|
||||||
auto textureSlot = procedural.getShader()->getTextures().findLocation("cubeMap");
|
auto textureSlot = procedural.getShader()->getTextures().findLocation("cubeMap");
|
||||||
auto bufferSlot = procedural.getShader()->getBuffers().findLocation("skyboxBuffer");
|
auto bufferSlot = procedural.getShader()->getBuffers().findLocation("skyboxBuffer");
|
||||||
skybox.prepare(batch, textureSlot, bufferSlot);
|
skybox.prepare(batch, textureSlot, bufferSlot);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
set(TARGET_NAME render-utils)
|
set(TARGET_NAME render-utils)
|
||||||
AUTOSCRIBE_SHADER_LIB(gpu model render)
|
AUTOSCRIBE_SHADER_LIB(gpu model render procedural)
|
||||||
# pull in the resources.qrc file
|
# pull in the resources.qrc file
|
||||||
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
||||||
setup_hifi_library(Widgets OpenGL Network Qml Quick Script)
|
setup_hifi_library(Widgets OpenGL Network Qml Quick Script)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
set(TARGET_NAME render)
|
set(TARGET_NAME render)
|
||||||
AUTOSCRIBE_SHADER_LIB(gpu model)
|
AUTOSCRIBE_SHADER_LIB(gpu model procedural)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared gpu model)
|
link_hifi_libraries(shared gpu model)
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,15 @@ public:
|
||||||
|
|
||||||
bool hasAncestorOfType(NestableType nestableType);
|
bool hasAncestorOfType(NestableType nestableType);
|
||||||
|
|
||||||
|
void getLocalTransformAndVelocities(Transform& localTransform,
|
||||||
|
glm::vec3& localVelocity,
|
||||||
|
glm::vec3& localAngularVelocity) const;
|
||||||
|
|
||||||
|
void setLocalTransformAndVelocities(
|
||||||
|
const Transform& localTransform,
|
||||||
|
const glm::vec3& localVelocity,
|
||||||
|
const glm::vec3& localAngularVelocity);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const NestableType _nestableType; // EntityItem or an AvatarData
|
const NestableType _nestableType; // EntityItem or an AvatarData
|
||||||
QUuid _id;
|
QUuid _id;
|
||||||
|
@ -151,13 +160,6 @@ protected:
|
||||||
quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to?
|
quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to?
|
||||||
SpatiallyNestablePointer getParentPointer(bool& success) const;
|
SpatiallyNestablePointer getParentPointer(bool& success) const;
|
||||||
|
|
||||||
void getLocalTransformAndVelocities(Transform& localTransform, glm::vec3& localVelocity, glm::vec3& localAngularVelocity) const;
|
|
||||||
|
|
||||||
void setLocalTransformAndVelocities(
|
|
||||||
const Transform& localTransform,
|
|
||||||
const glm::vec3& localVelocity,
|
|
||||||
const glm::vec3& localAngularVelocity);
|
|
||||||
|
|
||||||
mutable SpatiallyNestableWeakPointer _parent;
|
mutable SpatiallyNestableWeakPointer _parent;
|
||||||
|
|
||||||
virtual void beParentOfChild(SpatiallyNestablePointer newChild) const;
|
virtual void beParentOfChild(SpatiallyNestablePointer newChild) const;
|
||||||
|
|
|
@ -546,17 +546,10 @@
|
||||||
|
|
||||||
disableProperties();
|
disableProperties();
|
||||||
} else {
|
} else {
|
||||||
var activeElement = document.activeElement;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var selected = (activeElement
|
|
||||||
&& activeElement.selectionStart == 0
|
|
||||||
&& activeElement.selectionEnd == activeElement.value.length);
|
|
||||||
} catch (e) {
|
|
||||||
var selected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
properties = data.selections[0].properties;
|
properties = data.selections[0].properties;
|
||||||
|
|
||||||
elID.innerHTML = properties.id;
|
elID.innerHTML = properties.id;
|
||||||
|
|
||||||
elType.innerHTML = properties.type;
|
elType.innerHTML = properties.type;
|
||||||
|
@ -571,7 +564,6 @@
|
||||||
} else {
|
} else {
|
||||||
enableProperties();
|
enableProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
elName.value = properties.name;
|
elName.value = properties.name;
|
||||||
|
|
||||||
|
@ -811,11 +803,10 @@
|
||||||
elYTextureURL.value = properties.yTextureURL;
|
elYTextureURL.value = properties.yTextureURL;
|
||||||
elZTextureURL.value = properties.zTextureURL;
|
elZTextureURL.value = properties.zTextureURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected) {
|
var activeElement = document.activeElement;
|
||||||
activeElement.focus();
|
|
||||||
activeElement.select();
|
activeElement.select();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1178,7 +1169,7 @@
|
||||||
for (var i = 0; i < els.length; i++) {
|
for (var i = 0; i < els.length; i++) {
|
||||||
var clicked = false;
|
var clicked = false;
|
||||||
var originalText;
|
var originalText;
|
||||||
els[i].onfocus = function() {
|
els[i].onfocus = function(e) {
|
||||||
originalText = this.value;
|
originalText = this.value;
|
||||||
this.select();
|
this.select();
|
||||||
clicked = false;
|
clicked = false;
|
||||||
|
|
Loading…
Reference in a new issue