mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 09:59:20 +02: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);
|
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||||
tree->withTryWriteLock([&] {
|
tree->withTryWriteLock([&] {
|
||||||
tree->update();
|
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();
|
_physicsEngine->init();
|
||||||
|
|
||||||
EntityTreePointer tree = getEntities()->getTree();
|
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);
|
_entitySimulation->init(tree, _physicsEngine, &_entityEditSender);
|
||||||
tree->setSimulation(_entitySimulation);
|
tree->setSimulation(_entitySimulation);
|
||||||
|
|
||||||
|
@ -4879,14 +4877,16 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
|
||||||
auto entityId = _keyboardFocusedEntity.get();
|
auto entityId = _keyboardFocusedEntity.get();
|
||||||
if (entities->wantsKeyboardFocus(entityId)) {
|
if (entities->wantsKeyboardFocus(entityId)) {
|
||||||
entities->setProxyWindow(entityId, _window->windowHandle());
|
entities->setProxyWindow(entityId, _window->windowHandle());
|
||||||
auto entity = getEntities()->getEntity(entityId);
|
|
||||||
if (_keyboardMouseDevice->isActive()) {
|
if (_keyboardMouseDevice->isActive()) {
|
||||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||||
}
|
}
|
||||||
_lastAcceptedKeyPress = usecTimestampNow();
|
_lastAcceptedKeyPress = usecTimestampNow();
|
||||||
|
|
||||||
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
|
auto entity = getEntities()->getEntity(entityId);
|
||||||
entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
|
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);
|
_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"
|
#include "Application.moc"
|
||||||
|
|
|
@ -391,9 +391,6 @@ public slots:
|
||||||
const QString getPreferredCursor() const { return _preferredCursor.get(); }
|
const QString getPreferredCursor() const { return _preferredCursor.get(); }
|
||||||
void setPreferredCursor(const QString& cursor);
|
void setPreferredCursor(const QString& cursor);
|
||||||
|
|
||||||
void addingEntity(const EntityItemID& entityID);
|
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onDesktopRootItemCreated(QQuickItem* qmlContext);
|
void onDesktopRootItemCreated(QQuickItem* qmlContext);
|
||||||
void onDesktopRootContextCreated(QQmlContext* qmlContext);
|
void onDesktopRootContextCreated(QQmlContext* qmlContext);
|
||||||
|
|
|
@ -14,5 +14,6 @@ include_hifi_library_headers(audio)
|
||||||
include_hifi_library_headers(entities)
|
include_hifi_library_headers(entities)
|
||||||
include_hifi_library_headers(octree)
|
include_hifi_library_headers(octree)
|
||||||
include_hifi_library_headers(task)
|
include_hifi_library_headers(task)
|
||||||
|
include_hifi_library_headers(workload)
|
||||||
|
|
||||||
target_bullet()
|
target_bullet()
|
||||||
|
|
|
@ -14,6 +14,7 @@ include_hifi_library_headers(entities)
|
||||||
include_hifi_library_headers(avatars)
|
include_hifi_library_headers(avatars)
|
||||||
include_hifi_library_headers(controllers)
|
include_hifi_library_headers(controllers)
|
||||||
include_hifi_library_headers(task)
|
include_hifi_library_headers(task)
|
||||||
|
include_hifi_library_headers(workload)
|
||||||
|
|
||||||
target_bullet()
|
target_bullet()
|
||||||
target_polyvox()
|
target_polyvox()
|
||||||
|
|
|
@ -278,6 +278,13 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
|
||||||
if (!entity->isParentPathComplete()) {
|
if (!entity->isParentPathComplete()) {
|
||||||
continue;
|
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();
|
auto entityID = entity->getEntityItemID();
|
||||||
processedIds.insert(entityID);
|
processedIds.insert(entityID);
|
||||||
|
@ -287,7 +294,6 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!processedIds.empty()) {
|
if (!processedIds.empty()) {
|
||||||
for (const auto& processedId : processedIds) {
|
for (const auto& processedId : processedIds) {
|
||||||
_entitiesToAdd.erase(processedId);
|
_entitiesToAdd.erase(processedId);
|
||||||
|
@ -407,8 +413,7 @@ void EntityTreeRenderer::update(bool simulate) {
|
||||||
// here we update _currentFrame and _lastAnimated and sync with the server properties.
|
// here we update _currentFrame and _lastAnimated and sync with the server properties.
|
||||||
tree->update(simulate);
|
tree->update(simulate);
|
||||||
|
|
||||||
// Update the rendereable entities as needed
|
{ // Update the rendereable entities as needed
|
||||||
{
|
|
||||||
PROFILE_RANGE(simulation_physics, "Scene");
|
PROFILE_RANGE(simulation_physics, "Scene");
|
||||||
PerformanceTimer sceneTimer("scene");
|
PerformanceTimer sceneTimer("scene");
|
||||||
auto scene = _viewState->getMain3DScene();
|
auto scene = _viewState->getMain3DScene();
|
||||||
|
@ -421,6 +426,25 @@ void EntityTreeRenderer::update(bool simulate) {
|
||||||
scene->enqueueTransaction(transaction);
|
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) {
|
if (simulate) {
|
||||||
// Handle enter/leave entity logic
|
// 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 EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar) {
|
||||||
bool didUpdate = false;
|
bool didUpdate = false;
|
||||||
float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later
|
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 <TextureCache.h>
|
||||||
#include <OctreeProcessor.h>
|
#include <OctreeProcessor.h>
|
||||||
#include <render/Forward.h>
|
#include <render/Forward.h>
|
||||||
|
#include <workload/Space.h>
|
||||||
|
|
||||||
class AbstractScriptingServicesInterface;
|
class AbstractScriptingServicesInterface;
|
||||||
class AbstractViewStateInterface;
|
class AbstractViewStateInterface;
|
||||||
|
@ -139,6 +140,10 @@ public slots:
|
||||||
EntityRendererPointer renderableForEntityId(const EntityItemID& id) const;
|
EntityRendererPointer renderableForEntityId(const EntityItemID& id) const;
|
||||||
render::ItemID renderableIdForEntityId(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:
|
protected:
|
||||||
virtual OctreePointer createTree() override {
|
virtual OctreePointer createTree() override {
|
||||||
EntityTreePointer newTree = EntityTreePointer(new EntityTree(true));
|
EntityTreePointer newTree = EntityTreePointer(new EntityTree(true));
|
||||||
|
@ -261,6 +266,10 @@ private:
|
||||||
static std::function<bool()> _entitiesShouldFadeFunction;
|
static std::function<bool()> _entitiesShouldFadeFunction;
|
||||||
|
|
||||||
static std::function<bool()> _renderDebugHullsOperator;
|
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());
|
tree->entityChanged(getThisPointer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Andrew to connect this to the Space instance in Application
|
|
||||||
SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also
|
SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also
|
||||||
|
std::pair<int32_t, glm::vec4> data(_spaceIndex, glm::vec4(getWorldPosition(), _boundingRadius));
|
||||||
|
emit spaceUpdate(data);
|
||||||
somethingChangedNotification();
|
somethingChangedNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::dimensionsChanged() {
|
void EntityItem::dimensionsChanged() {
|
||||||
requiresRecalcBoxes();
|
requiresRecalcBoxes();
|
||||||
SpatiallyNestable::dimensionsChanged(); // Do what you have to do
|
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();
|
somethingChangedNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -464,6 +464,7 @@ public:
|
||||||
virtual bool getMeshes(MeshProxyList& result) { return true; }
|
virtual bool getMeshes(MeshProxyList& result) { return true; }
|
||||||
|
|
||||||
virtual void locationChanged(bool tellPhysics = true) override;
|
virtual void locationChanged(bool tellPhysics = true) override;
|
||||||
|
//void wtf(int32_t i) override;
|
||||||
|
|
||||||
virtual bool getScalesWithParent() const override;
|
virtual bool getScalesWithParent() const override;
|
||||||
|
|
||||||
|
@ -478,6 +479,7 @@ public:
|
||||||
void setCauterized(bool value) { _cauterized = value; }
|
void setCauterized(bool value) { _cauterized = value; }
|
||||||
bool getCauterized() const { return _cauterized; }
|
bool getCauterized() const { return _cauterized; }
|
||||||
|
|
||||||
|
float getBoundingRadius() const { return _boundingRadius; }
|
||||||
void setSpaceIndex(int32_t index) { assert(_spaceIndex == -1); _spaceIndex = index; }
|
void setSpaceIndex(int32_t index) { assert(_spaceIndex == -1); _spaceIndex = index; }
|
||||||
int32_t getSpaceIndex() const { return _spaceIndex; }
|
int32_t getSpaceIndex() const { return _spaceIndex; }
|
||||||
|
|
||||||
|
@ -490,6 +492,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestRenderUpdate();
|
void requestRenderUpdate();
|
||||||
|
void spaceUpdate(std::pair<int32_t, glm::vec4> data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<ChangeHandlerId, ChangeHandlerCallback> _changeHandlers;
|
QHash<ChangeHandlerId, ChangeHandlerCallback> _changeHandlers;
|
||||||
|
@ -641,6 +644,7 @@ protected:
|
||||||
quint64 _lastUpdatedAccelerationTimestamp { 0 };
|
quint64 _lastUpdatedAccelerationTimestamp { 0 };
|
||||||
quint64 _lastUpdatedQueryAACubeTimestamp { 0 };
|
quint64 _lastUpdatedQueryAACubeTimestamp { 0 };
|
||||||
|
|
||||||
|
float _boundingRadius { 0.0f };
|
||||||
int32_t _spaceIndex { -1 }; // index to proxy in workload::Space
|
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
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if we need to simulate this entity..
|
// check to see if we need to simulate this entity..
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
_simulation->addEntity(entity);
|
_simulation->addEntity(entity);
|
||||||
|
@ -271,10 +271,11 @@ void EntityTree::postAddEntity(EntityItemPointer entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
emit addingEntity(entity->getEntityItemID());
|
|
||||||
|
|
||||||
// find and hook up any entities with this entity as a (previously) missing parent
|
// find and hook up any entities with this entity as a (previously) missing parent
|
||||||
fixupNeedsParentFixups();
|
fixupNeedsParentFixups();
|
||||||
|
|
||||||
|
emit addingEntity(entity->getEntityItemID());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
||||||
|
@ -695,6 +696,11 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
_simulation->prepareEntityForDelete(theEntity);
|
_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 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 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; }
|
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::MaterialPointer, const std::string&)> _removeMaterialFromAvatarOperator;
|
||||||
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToOverlayOperator;
|
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToOverlayOperator;
|
||||||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromOverlayOperator;
|
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromOverlayOperator;
|
||||||
|
|
||||||
|
std::vector<EntityItemPointer> _removedEntities;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityTree_h
|
#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) {
|
for (uint32_t i = 0; i < changedProxies.size(); ++i) {
|
||||||
int32_t proxyId = changedProxies[i].first;
|
int32_t proxyId = changedProxies[i].first;
|
||||||
if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) {
|
if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
static const uint8_t REGION_INVALID = 4;
|
static const uint8_t REGION_INVALID = 4;
|
||||||
|
|
||||||
using Sphere = glm::vec4; // <x,y,z> = center, w = radius
|
using Sphere = glm::vec4; // <x,y,z> = center, w = radius
|
||||||
|
using ProxyUpdate = std::pair<int32_t, Sphere>;
|
||||||
|
|
||||||
class Proxy {
|
class Proxy {
|
||||||
public:
|
public:
|
||||||
|
@ -61,7 +62,7 @@ public:
|
||||||
|
|
||||||
int32_t createProxy(const Sphere& sphere);
|
int32_t createProxy(const Sphere& sphere);
|
||||||
void deleteProxies(const std::vector<int32_t>& deadIndices);
|
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);
|
void setViews(const std::vector<View>& views);
|
||||||
|
|
||||||
uint32_t getNumObjects() const { return (uint32_t)(_proxies.size() - _freeIndices.size()); }
|
uint32_t getNumObjects() const { return (uint32_t)(_proxies.size() - _freeIndices.size()); }
|
||||||
|
|
Loading…
Reference in a new issue