Example #1
0
void AvatarManager::removeDeadAvatarEntities(const SetOfEntities& deadEntities) {
    auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
    EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
    for (auto entity : deadEntities) {
        QUuid entityOwnerID = entity->getOwningAvatarID();
        AvatarSharedPointer avatar = getAvatarBySessionID(entityOwnerID);
        const bool REQUIRES_REMOVAL_FROM_TREE = false;
        if (avatar) {
            avatar->clearAvatarEntity(entity->getID(), REQUIRES_REMOVAL_FROM_TREE);
        }
        if (entityTree && entity->isMyAvatarEntity()) {
            entityTree->withWriteLock([&] {
                // We only need to delete the direct children (rather than the descendants) because
                // when the child is deleted, it will take care of its own children.  If the child
                // is also an avatar-entity, we'll end up back here.  If it's not, the entity-server
                // will take care of it in the usual way.
                entity->forEachChild([&](SpatiallyNestablePointer child) {
                    EntityItemPointer childEntity = std::dynamic_pointer_cast<EntityItem>(child);
                    if (childEntity) {
                        entityTree->deleteEntity(childEntity->getID(), true, true);
                        if (avatar) {
                            avatar->clearAvatarEntity(childEntity->getID(), REQUIRES_REMOVAL_FROM_TREE);
                        }
                    }
                });
            });
        }
    }
}
Example #2
0
void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
    EntitySimulation::changeEntityInternal(entity);
    if (!entity->getSimulatorID().isNull()) {
        _entitiesWithSimulator.insert(entity);
    }
    entity->clearDirtyFlags();
}
Example #3
0
EntityRenderer::EntityRenderer(const EntityItemPointer& entity) : _entity(entity) {
    connect(entity.get(), &EntityItem::requestRenderUpdate, this, [&] {
        _needsRenderUpdate = true;
        emit requestRenderUpdate();
    });
    _materials = entity->getMaterials();
}
Example #4
0
void EntitySimulation::addEntityInternal(EntityItemPointer entity) {
    if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
        QMutexLocker lock(&_mutex);
        _simpleKinematicEntities.insert(entity);
        entity->setLastSimulated(usecTimestampNow());
    }
}
QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties) {

    EntityItemProperties propertiesWithSimID = properties;

    EntityItemID id = EntityItemID(QUuid::createUuid());

    // If we have a local entity tree set, then also update it.
    bool success = true;
    if (_entityTree) {
        _entityTree->withWriteLock([&] {
            EntityItemPointer entity = _entityTree->addEntity(id, propertiesWithSimID);
            if (entity) {
                // This Node is creating a new object.  If it's in motion, set this Node as the simulator.
                auto nodeList = DependencyManager::get<NodeList>();
                const QUuid myNodeID = nodeList->getSessionUUID();
                propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY);

                // and make note of it now, so we can act on it right away.
                entity->setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY);

                entity->setLastBroadcast(usecTimestampNow());
            } else {
                qCDebug(entities) << "script failed to add new Entity to local Octree";
                success = false;
            }
        });
    }

    // queue the packet
    if (success) {
        queueEntityMessage(PacketType::EntityAdd, id, propertiesWithSimID);
    }

    return id;
}
Example #6
0
// protected
void EntitySimulation::sortEntitiesThatMoved() {
    // NOTE: this is only for entities that have been moved by THIS EntitySimulation.
    // External changes to entity position/shape are expected to be sorted outside of the EntitySimulation.
    MovingEntitiesOperator moveOperator(_entityTree);
    AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE);
    SetOfEntities::iterator itemItr = _entitiesToSort.begin();
    while (itemItr != _entitiesToSort.end()) {
        EntityItemPointer entity = *itemItr;
        // check to see if this movement has sent the entity outside of the domain.
        bool success;
        AACube newCube = entity->getQueryAACube(success);
        if (success && !domainBounds.touches(newCube)) {
            qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
            itemItr = _entitiesToSort.erase(itemItr);
            entity->die();
            prepareEntityForDelete(entity);
        } else {
            moveOperator.addEntityToMoveList(entity, newCube);
            ++itemItr;
        }
    }
    if (moveOperator.hasMovingEntities()) {
        PerformanceTimer perfTimer("recurseTreeWithOperator");
        _entityTree->recurseTreeWithOperator(&moveOperator);
    }

    _entitiesToSort.clear();
}
Example #7
0
SpatiallyNestablePointer ObjectDynamic::getOther() {
    SpatiallyNestablePointer other;
    withWriteLock([&]{
        if (_otherID == QUuid()) {
            // no other
            return;
        }
        other = _other.lock();
        if (other && other->getID() == _otherID) {
            // other is already up-to-date
            return;
        }
        if (other) {
            // we have a pointer to other, but it's wrong
            other.reset();
            _other.reset();
        }
        // we have an other-id but no pointer to other cached
        QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
        if (!parentFinder) {
            return;
        }
        EntityItemPointer ownerEntity = _ownerEntity.lock();
        if (!ownerEntity) {
            return;
        }
        bool success;
        _other = parentFinder->find(_otherID, success, ownerEntity->getParentTree());
        if (success) {
            other = _other.lock();
        }
    });
    return other;
}
void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
    // queue incoming changes: from external sources (script, EntityServer, etc) to physics engine
    assert(entity);
    EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
    if (motionState) {
        if (!entity->shouldBePhysical()) {
            // the entity should be removed from the physical simulation
            _pendingChanges.remove(motionState);
            _physicalObjects.remove(motionState);
            _pendingRemoves.insert(motionState);
            _outgoingChanges.remove(motionState);
            if (entity->isMoving()) {
                _simpleKinematicEntities.insert(entity);
            }
        } else {
            _pendingChanges.insert(motionState);
        }
    } else if (entity->shouldBePhysical()) {
        // The intent is for this object to be in the PhysicsEngine, but it has no MotionState yet.
        // Perhaps it's shape has changed and it can now be added?
        _pendingAdds.insert(entity);
        _simpleKinematicEntities.remove(entity); // just in case it's non-physical-kinematic
    } else if (entity->isMoving()) {
        _simpleKinematicEntities.insert(entity);
    } else {
        _simpleKinematicEntities.remove(entity); // just in case it's non-physical-kinematic
    }
}
void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
    if (now > _nextOwnerlessExpiry) {
        // search for ownerless objects that have expired
        QMutexLocker lock(&_mutex);
        _nextOwnerlessExpiry = -1;
        SetOfEntities::iterator itemItr = _entitiesThatNeedSimulationOwner.begin();
        while (itemItr != _entitiesThatNeedSimulationOwner.end()) {
            EntityItemPointer entity = *itemItr;
            quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
            if (expiry < now) {
                // no simulators have volunteered ownership --> remove from list
                itemItr = _entitiesThatNeedSimulationOwner.erase(itemItr);

                if (entity->getSimulatorID().isNull() && entity->getDynamic() && entity->hasLocalVelocity()) {
                    // zero the derivatives
                    entity->setVelocity(Vectors::ZERO);
                    entity->setAngularVelocity(Vectors::ZERO);
                    entity->setAcceleration(Vectors::ZERO);

                    // dirty all the tree elements that contain it
                    entity->markAsChangedOnServer();
                    DirtyOctreeElementOperator op(entity->getElement());
                    getEntityTree()->recurseTreeWithOperator(&op);
                }
            } else {
                ++itemItr;
                if (expiry < _nextOwnerlessExpiry) {
                    _nextOwnerlessExpiry = expiry;
                }
            }
        }
    }
}
Example #10
0
void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ignoreWarnings) {
    EntityTreeElementPointer containingElement = getContainingElement(entityID);
    if (!containingElement) {
        if (!ignoreWarnings) {
            qCDebug(entities) << "UNEXPECTED!!!!  EntityTree::deleteEntity() entityID doesn't exist!!! entityID=" << entityID;
        }
        return;
    }

    EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
    if (!existingEntity) {
        if (!ignoreWarnings) {
            qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. "
                        "entityID=" << entityID;
        }
        return;
    }

    if (existingEntity->getLocked() && !force) {
        if (!ignoreWarnings) {
            qCDebug(entities) << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID;
        }
        return;
    }

    emit deletingEntity(entityID);

    // NOTE: callers must lock the tree before using this method
    DeleteEntityOperator theOperator(getThisPointer(), entityID);
    recurseTreeWithOperator(&theOperator);
    processRemovedEntities(theOperator);
    _isDirty = true;
}
Example #11
0
void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
    if (_ownerEntity.expired()) {
        qDebug() << "warning -- action with no entity removing self from btCollisionWorld.";
        btDynamicsWorld* dynamicsWorld = static_cast<btDynamicsWorld*>(collisionWorld);
        dynamicsWorld->removeAction(this);
        return;
    }

    if (_expires > 0) {
        quint64 now = usecTimestampNow();
        if (now > _expires) {
            EntityItemPointer ownerEntity = _ownerEntity.lock();
            _active = false;
            if (ownerEntity) {
                ownerEntity->removeAction(nullptr, getID());
            }
        }
    }

    if (!_active) {
        return;
    }

    updateActionWorker(deltaTimeStep);
}
Example #12
0
void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force, bool ignoreWarnings) {
    // NOTE: callers must lock the tree before using this method
    DeleteEntityOperator theOperator(getThisPointer());
    foreach(const EntityItemID& entityID, entityIDs) {
        EntityTreeElementPointer containingElement = getContainingElement(entityID);
        if (!containingElement) {
            if (!ignoreWarnings) {
                qCDebug(entities) << "UNEXPECTED!!!!  EntityTree::deleteEntities() entityID doesn't exist!!! entityID=" << entityID;
            }
            continue;
        }

        EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
        if (!existingEntity) {
            if (!ignoreWarnings) {
                qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. "
                            "entityID=" << entityID;
            }
            continue;
        }

        if (existingEntity->getLocked() && !force) {
            if (!ignoreWarnings) {
                qCDebug(entities) << "ERROR! EntityTree::deleteEntities() trying to delete locked entity. entityID=" << entityID;
            }
            continue;
        }

        // tell our delete operator about this entityID
        theOperator.addEntityIDToDeleteList(entityID);
        emit deletingEntity(entityID);
    }
Example #13
0
// Note: The "type" property is set in EntityItem::getActionArguments().
QVariantMap ObjectDynamic::getArguments() {
    QVariantMap arguments;
    withReadLock([&]{
        if (_expires == 0) {
            arguments["ttl"] = 0.0f;
        } else {
            quint64 now = usecTimestampNow();
            arguments["ttl"] = (float)(_expires - now) / (float)USECS_PER_SECOND;
        }
        arguments["tag"] = _tag;

        EntityItemPointer entity = _ownerEntity.lock();
        if (entity) {
            ObjectMotionState* motionState = static_cast<ObjectMotionState*>(entity->getPhysicsInfo());
            if (motionState) {
                arguments["::active"] = motionState->isActive();
                arguments["::motion-type"] = motionTypeToString(motionState->getMotionType());
            } else {
                arguments["::no-motion-state"] = true;
            }
        }
        arguments["isMine"] = isMine();
    });
    return arguments;
}
Example #14
0
// protected
void EntitySimulation::expireMortalEntities(const quint64& now) {
    if (now > _nextExpiry) {
        // only search for expired entities if we expect to find one
        _nextExpiry = quint64(-1);
        QMutexLocker lock(&_mutex);
        SetOfEntities::iterator itemItr = _mortalEntities.begin();
        while (itemItr != _mortalEntities.end()) {
            EntityItemPointer entity = *itemItr;
            quint64 expiry = entity->getExpiry();
            if (expiry < now) {
                itemItr = _mortalEntities.erase(itemItr);
                entity->die();
                prepareEntityForDelete(entity);
            } else {
                if (expiry < _nextExpiry) {
                    // remember the smallest _nextExpiry so we know when to start the next search
                    _nextExpiry = expiry;
                }
                ++itemItr;
            }
        }
        if (_mortalEntities.size() < 1) {
            _nextExpiry = -1;
        }
    }
}
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) {
    EntityItemProperties results;
    if (_entityTree) {
        _entityTree->withReadLock([&] {
            EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
            if (entity) {
                results = entity->getProperties(desiredProperties);

                // TODO: improve sitting points and naturalDimensions in the future,
                //       for now we've included the old sitting points model behavior for entity types that are models
                //        we've also added this hack for setting natural dimensions of models
                if (entity->getType() == EntityTypes::Model) {
                    const FBXGeometry* geometry = _entityTree->getGeometryForEntity(entity);
                    if (geometry) {
                        results.setSittingPoints(geometry->sittingPoints);
                        Extents meshExtents = geometry->getUnscaledMeshExtents();
                        results.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum);
                        results.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum);
                    }
                }

            }
        });
    }

    return results;
}
Example #16
0
File: main.cpp Project: rudi-c/hifi
int main(int argc, char** argv) {
    QCoreApplication app(argc, argv);
    {
        auto start = usecTimestampNow();
        for (int i = 0; i < 1000; ++i) {
            testPropertyFlags();
            testByteCountCoded<quint8>();
            testByteCountCoded<quint16>();
            testByteCountCoded<quint32>();
            testByteCountCoded<quint64>();
        }
        auto duration = usecTimestampNow() - start;
        qDebug() << duration;

    }
    DependencyManager::set<NodeList>(NodeType::Unassigned);

    QFile file(getTestResourceDir() + "packet.bin");
    if (!file.open(QIODevice::ReadOnly)) return -1;
    QByteArray packet = file.readAll();
    EntityItemPointer item = BoxEntityItem::factory(EntityItemID(), EntityItemProperties());
    ReadBitstreamToTreeParams params;
    params.bitstreamVersion = 33;

    auto start = usecTimestampNow();
    for (int i = 0; i < 1000; ++i) {
        item->readEntityDataFromBuffer(reinterpret_cast<const unsigned char*>(packet.constData()), packet.size(), params);
    }
    float duration = (usecTimestampNow() - start);
    qDebug() << (duration / 1000.0f);
    return 0;
}
Example #17
0
// protected
void EntitySimulation::expireMortalEntities(const quint64& now) {
    if (now > _nextExpiry) {
        // only search for expired entities if we expect to find one
        _nextExpiry = quint64(-1);
        SetOfEntities::iterator itemItr = _mortalEntities.begin();
        while (itemItr != _mortalEntities.end()) {
            EntityItemPointer entity = *itemItr;
            quint64 expiry = entity->getExpiry();
            if (expiry < now) {
                _entitiesToDelete.insert(entity);
                itemItr = _mortalEntities.erase(itemItr);
                _entitiesToUpdate.remove(entity);
                _entitiesToSort.remove(entity);
                _simpleKinematicEntities.remove(entity);
                removeEntityInternal(entity);

                _allEntities.remove(entity);
                entity->_simulated = false;
            } else {
                if (expiry < _nextExpiry) {
                    // remeber the smallest _nextExpiry so we know when to start the next search
                    _nextExpiry = expiry;
                }
                ++itemItr;
            }
        }
    }
}
Example #18
0
// protected
void EntitySimulation::sortEntitiesThatMoved() {
    // NOTE: this is only for entities that have been moved by THIS EntitySimulation.
    // External changes to entity position/shape are expected to be sorted outside of the EntitySimulation.
    PerformanceTimer perfTimer("sortingEntities");
    MovingEntitiesOperator moveOperator(_entityTree);
    AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE);
    SetOfEntities::iterator itemItr = _entitiesToSort.begin();
    while (itemItr != _entitiesToSort.end()) {
        EntityItemPointer entity = *itemItr;
        // check to see if this movement has sent the entity outside of the domain.
        AACube newCube = entity->getMaximumAACube();
        if (!domainBounds.touches(newCube)) {
            qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
            _entitiesToDelete.insert(entity);
            _mortalEntities.remove(entity);
            _entitiesToUpdate.remove(entity);
            _simpleKinematicEntities.remove(entity);
            removeEntityInternal(entity);

            _allEntities.remove(entity);
            entity->_simulated = false;

            itemItr = _entitiesToSort.erase(itemItr);
        } else {
            moveOperator.addEntityToMoveList(entity, newCube);
            ++itemItr;
        }
    }
    if (moveOperator.hasMovingEntities()) {
        PerformanceTimer perfTimer("recurseTreeWithOperator");
        _entityTree->recurseTreeWithOperator(&moveOperator);
    }

    _entitiesToSort.clear();
}
Example #19
0
void EntitySimulation::changeEntityInternal(EntityItemPointer entity) {
    if (entity->isMoving() && !entity->getPhysicsInfo()) {
        _simpleKinematicEntities.insert(entity);
    } else {
        _simpleKinematicEntities.remove(entity);
    }
}
Example #20
0
void EntitySimulation::changeEntityInternal(EntityItemPointer entity) {
    QMutexLocker lock(&_mutex);
    if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
        _simpleKinematicEntities.insert(entity);
    } else {
        _simpleKinematicEntities.remove(entity);
    }
}
QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties) {
    EntityItemProperties propertiesWithSimID = convertLocationFromScriptSemantics(properties);
    propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged());

    auto dimensions = propertiesWithSimID.getDimensions();
    float volume = dimensions.x * dimensions.y * dimensions.z;
    auto density = propertiesWithSimID.getDensity();
    auto newVelocity = propertiesWithSimID.getVelocity().length();
    float cost = calculateCost(density * volume, 0, newVelocity);
    cost *= costMultiplier;

    if (cost > _currentAvatarEnergy) {
        return QUuid();
    }

    EntityItemID id = EntityItemID(QUuid::createUuid());

    // If we have a local entity tree set, then also update it.
    bool success = true;
    if (_entityTree) {
        _entityTree->withWriteLock([&] {
            EntityItemPointer entity = _entityTree->addEntity(id, propertiesWithSimID);
            if (entity) {
                if (propertiesWithSimID.parentRelatedPropertyChanged()) {
                    // due to parenting, the server may not know where something is in world-space, so include the bounding cube.
                    bool success;
                    AACube queryAACube = entity->getQueryAACube(success);
                    if (success) {
                        propertiesWithSimID.setQueryAACube(queryAACube);
                    }
                }

                if (_bidOnSimulationOwnership) {
                    // This Node is creating a new object.  If it's in motion, set this Node as the simulator.
                    auto nodeList = DependencyManager::get<NodeList>();
                    const QUuid myNodeID = nodeList->getSessionUUID();

                    // and make note of it now, so we can act on it right away.
                    propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY);
                    entity->setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY);
                }

                entity->setLastBroadcast(usecTimestampNow());
            } else {
                qCDebug(entities) << "script failed to add new Entity to local Octree";
                success = false;
            }
        });
    }

    // queue the packet
    if (success) {
        emit debitEnergySource(cost);
        queueEntityMessage(PacketType::EntityAdd, id, propertiesWithSimID);
    }

    return id;
}
Example #22
0
bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
    EntityTreeElement* containingElement = getContainingElement(entity->getEntityItemID());
    if (!containingElement) {
        qCDebug(entities) << "UNEXPECTED!!!!  EntityTree::updateEntity() entity-->element lookup failed!!! entityID=" 
            << entity->getEntityItemID();
        return false;
    }
    return updateEntityWithElement(entity, properties, containingElement, senderNode);
}
void SimpleEntitySimulation::sortEntitiesThatMoved() {
    SetOfEntities::iterator itemItr = _entitiesToSort.begin();
    while (itemItr != _entitiesToSort.end()) {
        EntityItemPointer entity = *itemItr;
        entity->computePuffedQueryAACube();
        ++itemItr;
    }
    EntitySimulation::sortEntitiesThatMoved();
}
Example #24
0
/// Adds a new entity item to the tree
void EntityTree::postAddEntity(EntityItemPointer entity) {
    assert(entity);
    // check to see if we need to simulate this entity..
    if (_simulation) {
        _simulation->addEntity(entity);
    }
    _isDirty = true;
    maybeNotifyNewCollisionSoundURL("", entity->getCollisionSoundURL());
    emit addingEntity(entity->getEntityItemID());
}
void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
    EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
    if (motionState) {
        motionState->clearObjectBackPointer();
        entity->setPhysicsInfo(nullptr);
        _pendingRemoves.insert(motionState);
        _outgoingChanges.remove(motionState);
    }
    _pendingAdds.remove(entity);
}
Example #26
0
void EntitySimulation::prepareEntityForDelete(EntityItemPointer entity) {
    assert(entity);
    assert(entity->isDead());
    if (entity->isSimulated()) {
        QMutexLocker lock(&_mutex);
        entity->clearActions(getThisPointer());
        removeEntityInternal(entity);
        _entitiesToDelete.insert(entity);
    }
}
void SimpleEntitySimulation::clearOwnership(const QUuid& ownerID) {
    QMutexLocker lock(&_mutex);
    SetOfEntities::iterator itemItr = _entitiesWithSimulationOwner.begin();
    while (itemItr != _entitiesWithSimulationOwner.end()) {
        EntityItemPointer entity = *itemItr;
        if (entity->getSimulatorID() == ownerID) {
            // the simulator has abandonded this object --> remove from owned list
            qCDebug(entities) << "auto-removing simulation owner " << entity->getSimulatorID();
            itemItr = _entitiesWithSimulationOwner.erase(itemItr);

            if (entity->getDynamic() && entity->hasLocalVelocity()) {
                // it is still moving dynamically --> add to orphaned list
                _entitiesThatNeedSimulationOwner.insert(entity);
                quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
                if (expiry < _nextOwnerlessExpiry) {
                    _nextOwnerlessExpiry = expiry;
                }
            }

            // remove ownership and dirty all the tree elements that contain the it
            entity->clearSimulationOwnership();
            entity->markAsChangedOnServer();
            DirtyOctreeElementOperator op(entity->getElement());
            getEntityTree()->recurseTreeWithOperator(&op);
        } else {
            ++itemItr;
        }
    }
}
Example #28
0
void addAvatarEntities(const QVariantList& avatarEntities) {
    auto nodeList = DependencyManager::get<NodeList>();
    const QUuid myNodeID = nodeList->getSessionUUID();
    EntityTreePointer entityTree = DependencyManager::get<EntityTreeRenderer>()->getTree();
    if (!entityTree) {
        return;
    }
    EntitySimulationPointer entitySimulation = entityTree->getSimulation();
    PhysicalEntitySimulationPointer physicalEntitySimulation = std::static_pointer_cast<PhysicalEntitySimulation>(entitySimulation);
    EntityEditPacketSender* entityPacketSender = physicalEntitySimulation->getPacketSender();
    QScriptEngine scriptEngine;
    for (int index = 0; index < avatarEntities.count(); index++) {
        const QVariantMap& avatarEntityProperties = avatarEntities.at(index).toMap();
        QVariant variantProperties = avatarEntityProperties["properties"];
        QVariantMap asMap = variantProperties.toMap();
        QScriptValue scriptProperties = variantMapToScriptValue(asMap, scriptEngine);
        EntityItemProperties entityProperties;
        EntityItemPropertiesFromScriptValueHonorReadOnly(scriptProperties, entityProperties);

        entityProperties.setParentID(myNodeID);
        entityProperties.setClientOnly(true);
        entityProperties.setOwningAvatarID(myNodeID);
        entityProperties.setSimulationOwner(myNodeID, AVATAR_ENTITY_SIMULATION_PRIORITY);
        entityProperties.markAllChanged();

        EntityItemID id = EntityItemID(QUuid::createUuid());
        bool success = true;
        entityTree->withWriteLock([&] {
            EntityItemPointer entity = entityTree->addEntity(id, entityProperties);
            if (entity) {
                if (entityProperties.queryAACubeRelatedPropertyChanged()) {
                    // due to parenting, the server may not know where something is in world-space, so include the bounding cube.
                    bool success;
                    AACube queryAACube = entity->getQueryAACube(success);
                    if (success) {
                        entityProperties.setQueryAACube(queryAACube);
                    }
                }

                entity->setLastBroadcast(usecTimestampNow());
                // since we're creating this object we will immediately volunteer to own its simulation
                entity->flagForOwnershipBid(VOLUNTEER_SIMULATION_PRIORITY);
                entityProperties.setLastEdited(entity->getLastEdited());
            } else {
                qCDebug(entities) << "AvatarEntitiesBookmark failed to add new Entity to local Octree";
                success = false;
            }
        });

        if (success) {
            entityPacketSender->queueEditEntityMessage(PacketType::EntityAdd, entityTree, id, entityProperties);
        }
    }
}
void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
    assert(entity);
    if (entity->shouldBePhysical()) { 
        EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
        if (!motionState) {
            _pendingAdds.insert(entity);
        }
    } else if (entity->isMoving()) {
        _simpleKinematicEntities.insert(entity);
    }
}
Example #30
0
EntityItemPointer ObjectDynamic::getEntityByID(EntityItemID entityID) const {
    EntityItemPointer ownerEntity;
    withReadLock([&]{
        ownerEntity = _ownerEntity.lock();
    });
    EntityTreeElementPointer element = ownerEntity ? ownerEntity->getElement() : nullptr;
    EntityTreePointer tree = element ? element->getTree() : nullptr;
    if (!tree) {
        return nullptr;
    }
    return tree->findEntityByID(entityID);
}