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

This commit is contained in:
Andrzej Kapolka 2014-11-12 15:42:36 -08:00
commit 49a9387020
15 changed files with 147 additions and 42 deletions

View file

@ -61,7 +61,7 @@
const float LOUDNESS_TO_DISTANCE_RATIO = 0.00001f;
const float DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE = 0.18;
const float DEFAULT_NOISE_MUTING_THRESHOLD = 0.001f;
const float DEFAULT_NOISE_MUTING_THRESHOLD = 0.003f;
const QString AUDIO_MIXER_LOGGING_TARGET_NAME = "audio-mixer";
const QString AUDIO_ENV_GROUP_KEY = "audio_env";
const QString AUDIO_BUFFER_GROUP_KEY = "audio_buffer";

View file

@ -93,8 +93,8 @@
"name": "noise_muting_threshold",
"label": "Noise Muting Threshold",
"help": "Loudness value for noise background between 0 and 1.0 (0: mute everyone, 1.0: never mute)",
"placeholder": "0.001",
"default": "0.001",
"placeholder": "0.003",
"default": "0.003",
"advanced": false
},
{

View file

@ -22,13 +22,21 @@
this.oldColorKnown = true;
print("storing old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);
};
this.preload = function(entityID) {
print("preload");
this.storeOldColor(entityID);
};
this.hoverEnterEntity = function(entityID, mouseEvent) {
print("hoverEnterEntity");
if (!this.oldColorKnown) {
this.storeOldColor(entityID);
}
Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} });
};
this.hoverLeaveEntity = function(entityID, mouseEvent) {
print("hoverLeaveEntity");
if (this.oldColorKnown) {
print("leave restoring old color... this.oldColor="
+ this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue);

View file

@ -12,13 +12,23 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function(){
var bird = new Sound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
var bird;
function playSound(entityID) {
var options = new AudioInjectionOptions();
var position = MyAvatar.position;
options.position = position;
options.volume = 0.5;
Audio.playSound(bird, options);
};
this.preload = function(entityID) {
print("preload("+entityID.id+")");
bird = new Sound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
};
this.clickDownOnEntity = function(entityID, mouseEvent) {
print("clickDownOnEntity()...");
var options = new AudioInjectionOptions();
var position = MyAvatar.position;
options.position = position;
options.volume = 0.5;
Audio.playSound(bird, options);
playSound();
};
})

View file

@ -12,9 +12,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function(){
var bird = new Sound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
var bird;
function playSound(entityID) {
function playSound() {
var options = new AudioInjectionOptions();
var position = MyAvatar.position;
options.position = position;
@ -22,6 +22,11 @@
Audio.playSound(bird, options);
};
this.preload = function(entityID) {
print("preload("+entityID.id+")");
bird = new Sound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
};
this.enterEntity = function(entityID) {
playSound();
};

View file

@ -837,14 +837,12 @@ void Application::controlledBroadcastToNodes(const QByteArray& packet, const Nod
}
bool Application::event(QEvent* event) {
// handle custom URL
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
if (!fileEvent->url().isEmpty()) {
AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile());
if (fileEvent->url().isValid()) {
openUrl(fileEvent->url());
}
return false;

View file

@ -81,6 +81,9 @@ void EntityTreeRenderer::init() {
_lastAvatarPosition = avatarPosition + glm::vec3(1.f, 1.f, 1.f);
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::checkAndCallPreload);
connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::checkAndCallPreload);
connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID);
}
QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItemID) {
@ -770,3 +773,20 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
_entityScripts.remove(entityID);
}
void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID) {
// load the entity script if needed...
QScriptValue entityScript = loadEntityScript(entityID);
if (entityScript.property("preload").isValid()) {
QScriptValueList entityArgs = createEntityArgs(entityID);
entityScript.property("preload").call(entityScript, entityArgs);
}
}
void EntityTreeRenderer::changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID) {
if (_entityScripts.contains(oldEntityID)) {
EntityScriptDetails details = _entityScripts[oldEntityID];
_entityScripts.remove(oldEntityID);
_entityScripts[newEntityID] = details;
}
}

View file

@ -104,6 +104,8 @@ signals:
public slots:
void deletingEntity(const EntityItemID& entityID);
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
void checkAndCallPreload(const EntityItemID& entityID);
private:
QList<Model*> _releasedModels;

View file

@ -547,7 +547,8 @@ NetworkGeometry::NetworkGeometry(const QUrl& url, const QSharedPointer<NetworkGe
Resource(url, delayLoad),
_mapping(mapping),
_textureBase(textureBase.isValid() ? textureBase : url),
_fallback(fallback) {
_fallback(fallback)
{
if (url.isEmpty()) {
// make the minimal amount of dummy geometry to satisfy Model
@ -562,6 +563,8 @@ NetworkGeometry::NetworkGeometry(const QUrl& url, const QSharedPointer<NetworkGe
_geometry.leftHandJointIndex = -1;
_geometry.rightHandJointIndex = -1;
}
connect(this, &Resource::loaded, this, &NetworkGeometry::replaceTexturesWithPendingChanges);
}
bool NetworkGeometry::isLoadedWithTextures() const {
@ -710,27 +713,33 @@ void NetworkGeometry::clearLoadPriority(const QPointer<QObject>& owner) {
}
void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& url) {
for (int i = 0; i < _meshes.size(); i++) {
NetworkMesh& mesh = _meshes[i];
for (int j = 0; j < mesh.parts.size(); j++) {
NetworkMeshPart& part = mesh.parts[j];
QSharedPointer<NetworkTexture> matchingTexture = QSharedPointer<NetworkTexture>();
if (part.diffuseTextureName == name) {
part.diffuseTexture =
if (_meshes.size() > 0) {
for (int i = 0; i < _meshes.size(); i++) {
NetworkMesh& mesh = _meshes[i];
for (int j = 0; j < mesh.parts.size(); j++) {
NetworkMeshPart& part = mesh.parts[j];
QSharedPointer<NetworkTexture> matchingTexture = QSharedPointer<NetworkTexture>();
if (part.diffuseTextureName == name) {
part.diffuseTexture =
Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE,
_geometry.meshes[i].isEye, QByteArray());
part.diffuseTexture->setLoadPriorities(_loadPriorities);
} else if (part.normalTextureName == name) {
part.normalTexture = Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE,
false, QByteArray());
part.normalTexture->setLoadPriorities(_loadPriorities);
} else if (part.specularTextureName == name) {
part.specularTexture = Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE,
false, QByteArray());
part.specularTexture->setLoadPriorities(_loadPriorities);
part.diffuseTexture->setLoadPriorities(_loadPriorities);
} else if (part.normalTextureName == name) {
part.normalTexture = Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE,
false, QByteArray());
part.normalTexture->setLoadPriorities(_loadPriorities);
} else if (part.specularTextureName == name) {
part.specularTexture = Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE,
false, QByteArray());
part.specularTexture->setLoadPriorities(_loadPriorities);
}
}
}
} else {
qDebug() << "Adding a name url pair to pending" << name << url;
// we don't have meshes downloaded yet, so hold this texture as pending
_pendingTextureChanges.insert(name, url);
}
}
@ -760,6 +769,15 @@ QStringList NetworkGeometry::getTextureNames() const {
return result;
}
void NetworkGeometry::replaceTexturesWithPendingChanges() {
QHash<QString, QUrl>::Iterator it = _pendingTextureChanges.begin();
while (it != _pendingTextureChanges.end()) {
setTextureWithNameToURL(it.key(), it.value());
it = _pendingTextureChanges.erase(it);
}
}
/// Reads geometry in a worker thread.
class GeometryReader : public QRunnable {
public:
@ -807,6 +825,7 @@ void NetworkGeometry::init() {
_geometry = FBXGeometry();
_meshes.clear();
_lods.clear();
_pendingTextureChanges.clear();
_request.setUrl(_url);
Resource::init();
}

View file

@ -113,7 +113,7 @@ public:
void setTextureWithNameToURL(const QString& name, const QUrl& url);
QStringList getTextureNames() const;
protected:
virtual void init();
@ -122,6 +122,8 @@ protected:
Q_INVOKABLE void setGeometry(const FBXGeometry& geometry);
private slots:
void replaceTexturesWithPendingChanges();
private:
friend class GeometryCache;
@ -139,6 +141,8 @@ private:
QWeakPointer<NetworkGeometry> _lodParent;
QHash<QWeakPointer<Animation>, QVector<int> > _jointMappings;
QHash<QString, QUrl> _pendingTextureChanges;
};
/// The state associated with a single mesh part.

View file

@ -52,9 +52,12 @@ JoystickScriptingInterface::JoystickScriptingInterface() :
for (int i = 0; i < joystickCount; i++) {
SDL_GameController* controller = SDL_GameControllerOpen(i);
SDL_JoystickID id = getInstanceId(controller);
Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller);
_openJoysticks[id] = joystick;
if (controller) {
SDL_JoystickID id = getInstanceId(controller);
Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller);
_openJoysticks[id] = joystick;
}
}
_isInitialized = true;

View file

@ -145,14 +145,14 @@ public:
float getLargestDimension() const { return glm::length(_dimensions); } /// get the largest possible dimension
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
void setDimensions(const glm::vec3& value) { _dimensions = value; ; recalculateCollisionShape(); }
void setDimensions(const glm::vec3& value) { _dimensions = value; recalculateCollisionShape(); }
/// set dimensions in meter units (0.0 - TREE_SCALE) this will also reset radius appropriately
void setDimensionsInMeters(const glm::vec3& value) { setDimensions(value / (float) TREE_SCALE); }
static const glm::quat DEFAULT_ROTATION;
const glm::quat& getRotation() const { return _rotation; }
void setRotation(const glm::quat& rotation) { _rotation = rotation; ; recalculateCollisionShape(); }
void setRotation(const glm::quat& rotation) { _rotation = rotation; recalculateCollisionShape(); }
static const float DEFAULT_GLOW_LEVEL;
float getGlowLevel() const { return _glowLevel; }
@ -169,7 +169,7 @@ public:
static const glm::vec3 DEFAULT_VELOCITY;
static const glm::vec3 NO_VELOCITY;
static const float EPSILON_VELOCITY_LENGTH;
const glm::vec3 getVelocity() const { return _velocity; } /// velocity in domain scale units (0.0-1.0) per second
const glm::vec3& getVelocity() const { return _velocity; } /// velocity in domain scale units (0.0-1.0) per second
glm::vec3 getVelocityInMeters() const { return _velocity * (float) TREE_SCALE; } /// get velocity in meters
void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in domain scale units (0.0-1.0) per second
void setVelocityInMeters(const glm::vec3& value) { _velocity = value / (float) TREE_SCALE; } /// velocity in meters

View file

@ -124,6 +124,7 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
} else {
// check to see if we need to simulate this entity...
EntityItem::SimulationState oldState = existingEntity->getSimulationState();
QString entityScriptBefore = existingEntity->getScript();
UpdateEntityOperator theOperator(this, containingElement, existingEntity, properties);
recurseTreeWithOperator(&theOperator);
@ -131,6 +132,12 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
EntityItem::SimulationState newState = existingEntity->getSimulationState();
changeEntityState(existingEntity, oldState, newState);
QString entityScriptAfter = existingEntity->getScript();
if (entityScriptBefore != entityScriptAfter) {
emitEntityScriptChanging(entityID); // the entity script has changed
}
}
containingElement = getContainingElement(entityID);
@ -168,6 +175,7 @@ EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItem
if (result) {
// this does the actual adding of the entity
addEntityItem(result);
emitAddingEntity(entityID);
}
return result;
}
@ -184,6 +192,14 @@ void EntityTree::trackDeletedEntity(const EntityItemID& entityID) {
}
}
void EntityTree::emitAddingEntity(const EntityItemID& entityItemID) {
emit addingEntity(entityItemID);
}
void EntityTree::emitEntityScriptChanging(const EntityItemID& entityItemID) {
emit entityScriptChanging(entityItemID);
}
void EntityTree::deleteEntity(const EntityItemID& entityID) {
emit deletingEntity(entityID);
@ -290,6 +306,7 @@ void EntityTree::handleAddEntityResponse(const QByteArray& packet) {
EntityItemID creatorTokenVersion = searchEntityID.convertToCreatorTokenVersion();
EntityItemID knownIDVersion = searchEntityID.convertToKnownIDVersion();
// First look for and find the "viewed version" of this entity... it's possible we got
// the known ID version sent to us between us creating our local version, and getting this
// remapping message. If this happened, we actually want to find and delete that version of
@ -310,6 +327,10 @@ void EntityTree::handleAddEntityResponse(const QByteArray& packet) {
creatorTokenContainingElement->updateEntityItemID(creatorTokenVersion, knownIDVersion);
setContainingElement(creatorTokenVersion, NULL);
setContainingElement(knownIDVersion, creatorTokenContainingElement);
// because the ID of the entity is switching, we need to emit these signals for any
// listeners who care about the changing of IDs
emit changingEntityID(creatorTokenVersion, knownIDVersion);
}
}
unlock();
@ -981,7 +1002,6 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons
return processedBytes;
}
EntityTreeElement* EntityTree::getContainingElement(const EntityItemID& entityItemID) /*const*/ {
// TODO: do we need to make this thread safe? Or is it acceptable as is
if (_entityToElementMap.contains(entityItemID)) {

View file

@ -140,10 +140,16 @@ public:
void trackDeletedEntity(const EntityItemID& entityID);
void emitAddingEntity(const EntityItemID& entityItemID);
void emitEntityScriptChanging(const EntityItemID& entityItemID);
QList<EntityItem*>& getMovingEntities() { return _movingEntities; }
signals:
void deletingEntity(const EntityItemID& entityID);
void addingEntity(const EntityItemID& entityID);
void entityScriptChanging(const EntityItemID& entityItemID);
void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID);
private:

View file

@ -726,7 +726,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
entityItemID = EntityItemID::readEntityItemIDFromBuffer(dataAt, bytesLeftToRead);
entityItem = _myTree->findEntityByEntityItemID(entityItemID);
}
// If the item already exists in our tree, we want do the following...
// 1) allow the existing item to read from the databuffer
// 2) check to see if after reading the item, the containing element is still correct, fix it if needed
@ -734,10 +734,13 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
// TODO: Do we need to also do this?
// 3) remember the old cube for the entity so we can mark it as dirty
if (entityItem) {
QString entityScriptBefore = entityItem->getScript();
bool bestFitBefore = bestFitEntityBounds(entityItem);
EntityTreeElement* currentContainingElement = _myTree->getContainingElement(entityItemID);
EntityItem::SimulationState oldState = entityItem->getSimulationState();
bytesForThisEntity = entityItem->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args);
EntityItem::SimulationState newState = entityItem->getSimulationState();
if (oldState != newState) {
_myTree->changeEntityState(entityItem, oldState, newState);
@ -755,6 +758,12 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
}
}
}
QString entityScriptAfter = entityItem->getScript();
if (entityScriptBefore != entityScriptAfter) {
_myTree->emitEntityScriptChanging(entityItemID); // the entity script has changed
}
} else {
entityItem = EntityTypes::constructEntityItem(dataAt, bytesLeftToRead, args);
if (entityItem) {
@ -762,6 +771,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
addEntityItem(entityItem); // add this new entity to this elements entities
entityItemID = entityItem->getEntityItemID();
_myTree->setContainingElement(entityItemID, this);
_myTree->emitAddingEntity(entityItemID); // we just added an entity
EntityItem::SimulationState newState = entityItem->getSimulationState();
_myTree->changeEntityState(entityItem, EntityItem::Static, newState);
}