mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
maintain Space proxies for entities
This commit is contained in:
parent
76d2e9bc78
commit
e7495d830b
13 changed files with 75 additions and 25 deletions
|
@ -35,6 +35,10 @@ void EntityTreeHeadlessViewer::update() {
|
|||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||
tree->withTryWriteLock([&] {
|
||||
tree->update();
|
||||
|
||||
// flush final EntityTree references to deleted entities
|
||||
std::vector<EntityItemPointer> deletedEntities;
|
||||
tree->swapRemovedEntities(deletedEntities);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4544,8 +4544,6 @@ void Application::init() {
|
|||
_physicsEngine->init();
|
||||
|
||||
EntityTreePointer tree = getEntities()->getTree();
|
||||
connect(tree.get(), &EntityTree::deletingEntity, this, &Application::deletingEntity, Qt::QueuedConnection);
|
||||
connect(tree.get(), &EntityTree::addingEntity, this, &Application::addingEntity, Qt::QueuedConnection);
|
||||
_entitySimulation->init(tree, _physicsEngine, &_entityEditSender);
|
||||
tree->setSimulation(_entitySimulation);
|
||||
|
||||
|
@ -4879,14 +4877,16 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
|
|||
auto entityId = _keyboardFocusedEntity.get();
|
||||
if (entities->wantsKeyboardFocus(entityId)) {
|
||||
entities->setProxyWindow(entityId, _window->windowHandle());
|
||||
auto entity = getEntities()->getEntity(entityId);
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||
}
|
||||
_lastAcceptedKeyPress = usecTimestampNow();
|
||||
|
||||
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
|
||||
entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
|
||||
auto entity = getEntities()->getEntity(entityId);
|
||||
if (entity) {
|
||||
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
|
||||
entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7675,12 +7675,4 @@ void Application::saveNextPhysicsStats(QString filename) {
|
|||
_physicsEngine->saveNextPhysicsStats(filename);
|
||||
}
|
||||
|
||||
void Application::addingEntity(const EntityItemID& entityID) {
|
||||
// TODO: Andrew to implement this
|
||||
}
|
||||
|
||||
void Application::deletingEntity(const EntityItemID& entityID) {
|
||||
// TODO: Andrew to implement this
|
||||
}
|
||||
|
||||
#include "Application.moc"
|
||||
|
|
|
@ -391,9 +391,6 @@ public slots:
|
|||
const QString getPreferredCursor() const { return _preferredCursor.get(); }
|
||||
void setPreferredCursor(const QString& cursor);
|
||||
|
||||
void addingEntity(const EntityItemID& entityID);
|
||||
void deletingEntity(const EntityItemID& entityID);
|
||||
|
||||
private slots:
|
||||
void onDesktopRootItemCreated(QQuickItem* qmlContext);
|
||||
void onDesktopRootContextCreated(QQmlContext* qmlContext);
|
||||
|
|
|
@ -14,5 +14,6 @@ include_hifi_library_headers(audio)
|
|||
include_hifi_library_headers(entities)
|
||||
include_hifi_library_headers(octree)
|
||||
include_hifi_library_headers(task)
|
||||
include_hifi_library_headers(workload)
|
||||
|
||||
target_bullet()
|
||||
|
|
|
@ -14,6 +14,7 @@ include_hifi_library_headers(entities)
|
|||
include_hifi_library_headers(avatars)
|
||||
include_hifi_library_headers(controllers)
|
||||
include_hifi_library_headers(task)
|
||||
include_hifi_library_headers(workload)
|
||||
|
||||
target_bullet()
|
||||
target_polyvox()
|
||||
|
|
|
@ -278,6 +278,13 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
|
|||
if (!entity->isParentPathComplete()) {
|
||||
continue;
|
||||
}
|
||||
if (entity->getSpaceIndex() == -1) {
|
||||
std::unique_lock<std::mutex> lock(_spaceLock);
|
||||
workload::Space::Sphere sphere(entity->getWorldPosition(), entity->getBoundingRadius());
|
||||
int32_t spaceIndex = _space.createProxy(sphere);
|
||||
entity->setSpaceIndex(spaceIndex);
|
||||
connect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
auto entityID = entity->getEntityItemID();
|
||||
processedIds.insert(entityID);
|
||||
|
@ -287,7 +294,6 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!processedIds.empty()) {
|
||||
for (const auto& processedId : processedIds) {
|
||||
_entitiesToAdd.erase(processedId);
|
||||
|
@ -407,8 +413,7 @@ void EntityTreeRenderer::update(bool simulate) {
|
|||
// here we update _currentFrame and _lastAnimated and sync with the server properties.
|
||||
tree->update(simulate);
|
||||
|
||||
// Update the rendereable entities as needed
|
||||
{
|
||||
{ // Update the rendereable entities as needed
|
||||
PROFILE_RANGE(simulation_physics, "Scene");
|
||||
PerformanceTimer sceneTimer("scene");
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
|
@ -421,6 +426,25 @@ void EntityTreeRenderer::update(bool simulate) {
|
|||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
}
|
||||
{ // update proxies in the workload::Space
|
||||
std::unique_lock<std::mutex> lock(_spaceLock);
|
||||
_space.updateProxies(_spaceUpdates);
|
||||
_spaceUpdates.clear();
|
||||
}
|
||||
{ // flush final EntityTree references to removed entities
|
||||
std::vector<EntityItemPointer> deletedEntities;
|
||||
tree->swapRemovedEntities(deletedEntities);
|
||||
{ // delete proxies from workload::Space
|
||||
std::vector<int32_t> deadProxies;
|
||||
std::unique_lock<std::mutex> lock(_spaceLock);
|
||||
for (auto entity : deletedEntities) {
|
||||
int32_t spaceIndex = entity->getSpaceIndex();
|
||||
disconnect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate);
|
||||
deadProxies.push_back(spaceIndex);
|
||||
}
|
||||
_space.deleteProxies(deadProxies);
|
||||
}
|
||||
}
|
||||
|
||||
if (simulate) {
|
||||
// Handle enter/leave entity logic
|
||||
|
@ -437,6 +461,11 @@ void EntityTreeRenderer::update(bool simulate) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUpdate) {
|
||||
std::unique_lock<std::mutex> lock(_spaceLock);
|
||||
_spaceUpdates.push_back(proxyUpdate);
|
||||
}
|
||||
|
||||
bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar) {
|
||||
bool didUpdate = false;
|
||||
float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <TextureCache.h>
|
||||
#include <OctreeProcessor.h>
|
||||
#include <render/Forward.h>
|
||||
#include <workload/Space.h>
|
||||
|
||||
class AbstractScriptingServicesInterface;
|
||||
class AbstractViewStateInterface;
|
||||
|
@ -139,6 +140,10 @@ public slots:
|
|||
EntityRendererPointer renderableForEntityId(const EntityItemID& id) const;
|
||||
render::ItemID renderableIdForEntityId(const EntityItemID& id) const;
|
||||
|
||||
//void handleSpaceUpdate(workload::Space::ProxyUpdate proxyUpdate);
|
||||
void handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUpdate);
|
||||
void testSlot();
|
||||
|
||||
protected:
|
||||
virtual OctreePointer createTree() override {
|
||||
EntityTreePointer newTree = EntityTreePointer(new EntityTree(true));
|
||||
|
@ -261,6 +266,10 @@ private:
|
|||
static std::function<bool()> _entitiesShouldFadeFunction;
|
||||
|
||||
static std::function<bool()> _renderDebugHullsOperator;
|
||||
|
||||
mutable std::mutex _spaceLock;
|
||||
workload::Space _space;
|
||||
std::vector<workload::Space::ProxyUpdate> _spaceUpdates;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2364,14 +2364,18 @@ void EntityItem::locationChanged(bool tellPhysics) {
|
|||
tree->entityChanged(getThisPointer());
|
||||
}
|
||||
}
|
||||
// TODO: Andrew to connect this to the Space instance in Application
|
||||
SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also
|
||||
std::pair<int32_t, glm::vec4> data(_spaceIndex, glm::vec4(getWorldPosition(), _boundingRadius));
|
||||
emit spaceUpdate(data);
|
||||
somethingChangedNotification();
|
||||
}
|
||||
|
||||
void EntityItem::dimensionsChanged() {
|
||||
requiresRecalcBoxes();
|
||||
SpatiallyNestable::dimensionsChanged(); // Do what you have to do
|
||||
_boundingRadius = 0.5f * glm::length(getScaledDimensions());
|
||||
std::pair<int32_t, glm::vec4> data(_spaceIndex, glm::vec4(getWorldPosition(), _boundingRadius));
|
||||
emit spaceUpdate(data);
|
||||
somethingChangedNotification();
|
||||
}
|
||||
|
||||
|
|
|
@ -464,6 +464,7 @@ public:
|
|||
virtual bool getMeshes(MeshProxyList& result) { return true; }
|
||||
|
||||
virtual void locationChanged(bool tellPhysics = true) override;
|
||||
//void wtf(int32_t i) override;
|
||||
|
||||
virtual bool getScalesWithParent() const override;
|
||||
|
||||
|
@ -478,6 +479,7 @@ public:
|
|||
void setCauterized(bool value) { _cauterized = value; }
|
||||
bool getCauterized() const { return _cauterized; }
|
||||
|
||||
float getBoundingRadius() const { return _boundingRadius; }
|
||||
void setSpaceIndex(int32_t index) { assert(_spaceIndex == -1); _spaceIndex = index; }
|
||||
int32_t getSpaceIndex() const { return _spaceIndex; }
|
||||
|
||||
|
@ -490,6 +492,7 @@ public:
|
|||
|
||||
signals:
|
||||
void requestRenderUpdate();
|
||||
void spaceUpdate(std::pair<int32_t, glm::vec4> data);
|
||||
|
||||
protected:
|
||||
QHash<ChangeHandlerId, ChangeHandlerCallback> _changeHandlers;
|
||||
|
@ -641,6 +644,7 @@ protected:
|
|||
quint64 _lastUpdatedAccelerationTimestamp { 0 };
|
||||
quint64 _lastUpdatedQueryAACubeTimestamp { 0 };
|
||||
|
||||
float _boundingRadius { 0.0f };
|
||||
int32_t _spaceIndex { -1 }; // index to proxy in workload::Space
|
||||
bool _cauterized { false }; // if true, don't draw because it would obscure 1st-person camera
|
||||
|
||||
|
|
|
@ -260,7 +260,7 @@ void EntityTree::postAddEntity(EntityItemPointer entity) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check to see if we need to simulate this entity..
|
||||
if (_simulation) {
|
||||
_simulation->addEntity(entity);
|
||||
|
@ -271,10 +271,11 @@ void EntityTree::postAddEntity(EntityItemPointer entity) {
|
|||
}
|
||||
|
||||
_isDirty = true;
|
||||
emit addingEntity(entity->getEntityItemID());
|
||||
|
||||
// find and hook up any entities with this entity as a (previously) missing parent
|
||||
fixupNeedsParentFixups();
|
||||
|
||||
emit addingEntity(entity->getEntityItemID());
|
||||
}
|
||||
|
||||
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
||||
|
@ -695,6 +696,11 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
|||
if (_simulation) {
|
||||
_simulation->prepareEntityForDelete(theEntity);
|
||||
}
|
||||
|
||||
// We save a pointer to theEntity for external contexts that need it
|
||||
// but this means: external contexts that remove entities from the tree
|
||||
// must occasionally swapRemovedEntities() to flush these references.
|
||||
_removedEntities.push_back(theEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ public:
|
|||
|
||||
void setMyAvatar(std::shared_ptr<AvatarData> myAvatar) { _myAvatar = myAvatar; }
|
||||
|
||||
void queueUpdateSpaceProxy(int32_t index, const glm::vec4& sphere);
|
||||
void swapRemovedEntities(std::vector<EntityItemPointer>& entities) { entities.swap(_removedEntities); }
|
||||
|
||||
static void setAddMaterialToEntityOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; }
|
||||
static void setRemoveMaterialFromEntityOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; }
|
||||
|
@ -411,6 +411,8 @@ private:
|
|||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromAvatarOperator;
|
||||
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToOverlayOperator;
|
||||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromOverlayOperator;
|
||||
|
||||
std::vector<EntityItemPointer> _removedEntities;
|
||||
};
|
||||
|
||||
#endif // hifi_EntityTree_h
|
||||
|
|
|
@ -40,7 +40,7 @@ void Space::deleteProxies(const std::vector<int32_t>& deadIndices) {
|
|||
}
|
||||
}
|
||||
|
||||
void Space::updateProxies(const std::vector<std::pair<int32_t, Sphere> >& changedProxies) {
|
||||
void Space::updateProxies(const std::vector<ProxyUpdate>& changedProxies) {
|
||||
for (uint32_t i = 0; i < changedProxies.size(); ++i) {
|
||||
int32_t proxyId = changedProxies[i].first;
|
||||
if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) {
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
static const uint8_t REGION_INVALID = 4;
|
||||
|
||||
using Sphere = glm::vec4; // <x,y,z> = center, w = radius
|
||||
using ProxyUpdate = std::pair<int32_t, Sphere>;
|
||||
|
||||
class Proxy {
|
||||
public:
|
||||
|
@ -61,7 +62,7 @@ public:
|
|||
|
||||
int32_t createProxy(const Sphere& sphere);
|
||||
void deleteProxies(const std::vector<int32_t>& deadIndices);
|
||||
void updateProxies(const std::vector<std::pair<int32_t, Sphere> >& changedProxies);
|
||||
void updateProxies(const std::vector<ProxyUpdate>& changedProxies);
|
||||
void setViews(const std::vector<View>& views);
|
||||
|
||||
uint32_t getNumObjects() const { return (uint32_t)(_proxies.size() - _freeIndices.size()); }
|
||||
|
|
Loading…
Reference in a new issue