mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 16:41:02 +02:00
Merge pull request #8532 from ctrlaltdavid/21040
Add performance information to entities list
This commit is contained in:
commit
e828a18a2e
20 changed files with 551 additions and 93 deletions
Binary file not shown.
|
@ -182,3 +182,16 @@ ViewFrustum Camera::toViewFrustum() const {
|
||||||
loadViewFrustum(result);
|
loadViewFrustum(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap Camera::getViewFrustum() {
|
||||||
|
ViewFrustum frustum;
|
||||||
|
loadViewFrustum(frustum);
|
||||||
|
|
||||||
|
QVariantMap result;
|
||||||
|
result["position"].setValue(frustum.getPosition());
|
||||||
|
result["orientation"].setValue(frustum.getOrientation());
|
||||||
|
result["projection"].setValue(frustum.getProjection());
|
||||||
|
result["centerRadius"].setValue(frustum.getCenterRadius());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ class Camera : public QObject {
|
||||||
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
|
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
|
||||||
Q_PROPERTY(QString mode READ getModeString WRITE setModeString)
|
Q_PROPERTY(QString mode READ getModeString WRITE setModeString)
|
||||||
Q_PROPERTY(QUuid cameraEntity READ getCameraEntity WRITE setCameraEntity)
|
Q_PROPERTY(QUuid cameraEntity READ getCameraEntity WRITE setCameraEntity)
|
||||||
|
Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Camera();
|
Camera();
|
||||||
|
|
||||||
|
@ -63,6 +65,8 @@ public:
|
||||||
const glm::mat4& getProjection() const { return _projection; }
|
const glm::mat4& getProjection() const { return _projection; }
|
||||||
void setProjection(const glm::mat4& projection);
|
void setProjection(const glm::mat4& projection);
|
||||||
|
|
||||||
|
QVariantMap getViewFrustum();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
QString getModeString() const;
|
QString getModeString() const;
|
||||||
void setModeString(const QString& mode);
|
void setModeString(const QString& mode);
|
||||||
|
|
|
@ -590,11 +590,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
renderInfo.setProperty("texturesSize", (int)getRenderInfoTextureSize()); // FIXME - theoretically the size of textures could be > max int
|
renderInfo.setProperty("texturesSize", (int)getRenderInfoTextureSize()); // FIXME - theoretically the size of textures could be > max int
|
||||||
renderInfo.setProperty("hasTransparent", getRenderInfoHasTransparent());
|
renderInfo.setProperty("hasTransparent", getRenderInfoHasTransparent());
|
||||||
renderInfo.setProperty("drawCalls", getRenderInfoDrawCalls());
|
renderInfo.setProperty("drawCalls", getRenderInfoDrawCalls());
|
||||||
|
renderInfo.setProperty("texturesCount", getRenderInfoTextureCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_type == EntityTypes::Model || _type == EntityTypes::PolyLine || _type == EntityTypes::ParticleEffect) {
|
|
||||||
renderInfo.setProperty("texturesCount", QScriptValue(_textureNames.count()));
|
|
||||||
}
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(renderInfo, renderInfo); // Gettable but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(renderInfo, renderInfo); // Gettable but not settable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,7 +769,7 @@ void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object
|
||||||
QScriptValue EntityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags) {
|
QScriptValue EntityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags) {
|
||||||
return EntityItemProperties::entityPropertyFlagsToScriptValue(engine, flags);
|
return EntityItemProperties::entityPropertyFlagsToScriptValue(engine, flags);
|
||||||
QScriptValue result = engine->newObject();
|
QScriptValue result = engine->newObject();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) {
|
void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
#include "LightEntityItem.h"
|
#include "LightEntityItem.h"
|
||||||
#include "ModelEntityItem.h"
|
#include "ModelEntityItem.h"
|
||||||
|
#include "QVariantGLM.h"
|
||||||
#include "SimulationOwner.h"
|
#include "SimulationOwner.h"
|
||||||
#include "ZoneEntityItem.h"
|
#include "ZoneEntityItem.h"
|
||||||
|
|
||||||
|
@ -566,6 +567,48 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<QUuid> EntityScriptingInterface::findEntitiesInFrustum(QVariantMap frustum) const {
|
||||||
|
QVector<QUuid> result;
|
||||||
|
|
||||||
|
const QString POSITION_PROPERTY = "position";
|
||||||
|
bool positionOK = frustum.contains(POSITION_PROPERTY);
|
||||||
|
glm::vec3 position = positionOK ? qMapToGlmVec3(frustum[POSITION_PROPERTY]) : glm::vec3();
|
||||||
|
|
||||||
|
const QString ORIENTATION_PROPERTY = "orientation";
|
||||||
|
bool orientationOK = frustum.contains(ORIENTATION_PROPERTY);
|
||||||
|
glm::quat orientation = orientationOK ? qMapToGlmQuat(frustum[ORIENTATION_PROPERTY]) : glm::quat();
|
||||||
|
|
||||||
|
const QString PROJECTION_PROPERTY = "projection";
|
||||||
|
bool projectionOK = frustum.contains(PROJECTION_PROPERTY);
|
||||||
|
glm::mat4 projection = projectionOK ? qMapToGlmMat4(frustum[PROJECTION_PROPERTY]) : glm::mat4();
|
||||||
|
|
||||||
|
const QString CENTER_RADIUS_PROPERTY = "centerRadius";
|
||||||
|
bool centerRadiusOK = frustum.contains(CENTER_RADIUS_PROPERTY);
|
||||||
|
float centerRadius = centerRadiusOK ? frustum[CENTER_RADIUS_PROPERTY].toFloat() : 0.0f;
|
||||||
|
|
||||||
|
if (positionOK && orientationOK && projectionOK && centerRadiusOK) {
|
||||||
|
ViewFrustum viewFrustum;
|
||||||
|
viewFrustum.setPosition(position);
|
||||||
|
viewFrustum.setOrientation(orientation);
|
||||||
|
viewFrustum.setProjection(projection);
|
||||||
|
viewFrustum.setCenterRadius(centerRadius);
|
||||||
|
viewFrustum.calculate();
|
||||||
|
|
||||||
|
if (_entityTree) {
|
||||||
|
QVector<EntityItemPointer> entities;
|
||||||
|
_entityTree->withReadLock([&] {
|
||||||
|
_entityTree->findEntities(viewFrustum, entities);
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach(EntityItemPointer entity, entities) {
|
||||||
|
result << entity->getEntityItemID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking,
|
||||||
const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard) {
|
const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard) {
|
||||||
|
|
||||||
|
|
|
@ -127,10 +127,19 @@ public slots:
|
||||||
/// this function will not find any models in script engine contexts which don't have access to models
|
/// this function will not find any models in script engine contexts which don't have access to models
|
||||||
Q_INVOKABLE QVector<QUuid> findEntities(const glm::vec3& center, float radius) const;
|
Q_INVOKABLE QVector<QUuid> findEntities(const glm::vec3& center, float radius) const;
|
||||||
|
|
||||||
/// finds models within the search sphere specified by the center point and radius
|
/// finds models within the box specified by the corner and dimensions
|
||||||
/// this function will not find any models in script engine contexts which don't have access to models
|
/// this function will not find any models in script engine contexts which don't have access to models
|
||||||
Q_INVOKABLE QVector<QUuid> findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const;
|
Q_INVOKABLE QVector<QUuid> findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const;
|
||||||
|
|
||||||
|
/// finds models within the frustum
|
||||||
|
/// the frustum must have the following properties:
|
||||||
|
/// - position
|
||||||
|
/// - orientation
|
||||||
|
/// - projection
|
||||||
|
/// - centerRadius
|
||||||
|
/// this function will not find any models in script engine contexts which don't have access to models
|
||||||
|
Q_INVOKABLE QVector<QUuid> findEntitiesInFrustum(QVariantMap frustum) const;
|
||||||
|
|
||||||
/// If the scripting context has visible entities, this will determine a ray intersection, the results
|
/// If the scripting context has visible entities, this will determine a ray intersection, the results
|
||||||
/// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate
|
/// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate
|
||||||
/// will be false.
|
/// will be false.
|
||||||
|
|
|
@ -688,6 +688,31 @@ void EntityTree::findEntities(const AABox& box, QVector<EntityItemPointer>& foun
|
||||||
foundEntities.swap(args._foundEntities);
|
foundEntities.swap(args._foundEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FindInFrustumArgs {
|
||||||
|
public:
|
||||||
|
ViewFrustum frustum;
|
||||||
|
QVector<EntityItemPointer> entities;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool EntityTree::findInFrustumOperation(OctreeElementPointer element, void* extraData) {
|
||||||
|
FindInFrustumArgs* args = static_cast<FindInFrustumArgs*>(extraData);
|
||||||
|
if (element->isInView(args->frustum)) {
|
||||||
|
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||||
|
entityTreeElement->getEntities(args->frustum, args->entities);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: assumes caller has handled locking
|
||||||
|
void EntityTree::findEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities) {
|
||||||
|
FindInFrustumArgs args = { frustum, QVector<EntityItemPointer>() };
|
||||||
|
// NOTE: This should use recursion, since this is a spatial operation
|
||||||
|
recurseTreeWithOperation(findInFrustumOperation, &args);
|
||||||
|
// swap the two lists of entity pointers instead of copy
|
||||||
|
foundEntities.swap(args.entities);
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
||||||
EntityItemID entityID(id);
|
EntityItemID entityID(id);
|
||||||
return findEntityByEntityItemID(entityID);
|
return findEntityByEntityItemID(entityID);
|
||||||
|
|
|
@ -153,6 +153,11 @@ public:
|
||||||
/// \remark Side effect: any initial contents in entities will be lost
|
/// \remark Side effect: any initial contents in entities will be lost
|
||||||
void findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
void findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
|
/// finds all entities within a frustum
|
||||||
|
/// \parameter frustum the query frustum
|
||||||
|
/// \param foundEntities[out] vector of EntityItemPointer
|
||||||
|
void findEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||||
|
|
||||||
|
@ -276,6 +281,7 @@ protected:
|
||||||
static bool findInSphereOperation(OctreeElementPointer element, void* extraData);
|
static bool findInSphereOperation(OctreeElementPointer element, void* extraData);
|
||||||
static bool findInCubeOperation(OctreeElementPointer element, void* extraData);
|
static bool findInCubeOperation(OctreeElementPointer element, void* extraData);
|
||||||
static bool findInBoxOperation(OctreeElementPointer element, void* extraData);
|
static bool findInBoxOperation(OctreeElementPointer element, void* extraData);
|
||||||
|
static bool findInFrustumOperation(OctreeElementPointer element, void* extraData);
|
||||||
static bool sendEntitiesOperation(OctreeElementPointer element, void* extraData);
|
static bool sendEntitiesOperation(OctreeElementPointer element, void* extraData);
|
||||||
|
|
||||||
void notifyNewlyCreatedEntity(const EntityItem& newEntity, const SharedNodePointer& senderNode);
|
void notifyNewlyCreatedEntity(const EntityItem& newEntity, const SharedNodePointer& senderNode);
|
||||||
|
|
|
@ -796,6 +796,17 @@ void EntityTreeElement::getEntities(const AABox& box, QVector<EntityItemPointer>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTreeElement::getEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities) {
|
||||||
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
|
bool success;
|
||||||
|
AABox entityBox = entity->getAABox(success);
|
||||||
|
// FIXME - See FIXMEs for similar methods above.
|
||||||
|
if (!success || frustum.boxIntersectsFrustum(entityBox) || frustum.boxIntersectsKeyhole(entityBox)) {
|
||||||
|
foundEntities.push_back(entity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
||||||
EntityItemPointer foundEntity = NULL;
|
EntityItemPointer foundEntity = NULL;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
|
|
|
@ -194,6 +194,11 @@ public:
|
||||||
/// \param entities[out] vector of non-const EntityItemPointer
|
/// \param entities[out] vector of non-const EntityItemPointer
|
||||||
void getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
void getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
|
/// finds all entities that touch a frustum
|
||||||
|
/// \param frustum the query frustum
|
||||||
|
/// \param entities[out] vector of non-const EntityItemPointer
|
||||||
|
void getEntities(const ViewFrustum& frustum, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
||||||
EntityItemPointer getEntityWithID(uint32_t id) const;
|
EntityItemPointer getEntityWithID(uint32_t id) const;
|
||||||
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
||||||
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||||
|
|
|
@ -77,6 +77,7 @@ void MeshPartPayload::updateMaterial(model::MaterialPointer drawMaterial) {
|
||||||
bool MeshPartPayload::calculateMaterialSize() {
|
bool MeshPartPayload::calculateMaterialSize() {
|
||||||
bool allTextures = true; // assume we got this...
|
bool allTextures = true; // assume we got this...
|
||||||
_materialTextureSize = 0;
|
_materialTextureSize = 0;
|
||||||
|
_materialTextureCount = 0;
|
||||||
auto textureMaps = _drawMaterial->getTextureMaps();
|
auto textureMaps = _drawMaterial->getTextureMaps();
|
||||||
for (auto const &textureMapItem : textureMaps) {
|
for (auto const &textureMapItem : textureMaps) {
|
||||||
auto textureMap = textureMapItem.second;
|
auto textureMap = textureMapItem.second;
|
||||||
|
@ -88,6 +89,7 @@ bool MeshPartPayload::calculateMaterialSize() {
|
||||||
//auto storedSize = texture->getStoredSize();
|
//auto storedSize = texture->getStoredSize();
|
||||||
auto size = texture->getSize();
|
auto size = texture->getSize();
|
||||||
_materialTextureSize += size;
|
_materialTextureSize += size;
|
||||||
|
_materialTextureCount++;
|
||||||
} else {
|
} else {
|
||||||
allTextures = false;
|
allTextures = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,10 +67,12 @@ public:
|
||||||
|
|
||||||
size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; }
|
size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; }
|
||||||
size_t getMaterialTextureSize() { return _materialTextureSize; }
|
size_t getMaterialTextureSize() { return _materialTextureSize; }
|
||||||
|
int getMaterialTextureCount() { return _materialTextureCount; }
|
||||||
bool calculateMaterialSize();
|
bool calculateMaterialSize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t _materialTextureSize { 0 };
|
size_t _materialTextureSize { 0 };
|
||||||
|
int _materialTextureCount { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
|
@ -161,22 +161,33 @@ void Model::setOffset(const glm::vec3& offset) {
|
||||||
_snappedToRegistrationPoint = false;
|
_snappedToRegistrationPoint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Model::getRenderInfoTextureSize() {
|
void Model::calculateTextureInfo() {
|
||||||
if (!_hasCalculatedTextureSize && isLoaded() && getGeometry()->areTexturesLoaded()) {
|
if (!_hasCalculatedTextureInfo && isLoaded() && getGeometry()->areTexturesLoaded() && !_modelMeshRenderItems.isEmpty()) {
|
||||||
size_t textureSize = 0;
|
size_t textureSize = 0;
|
||||||
|
int textureCount = 0;
|
||||||
bool allTexturesLoaded = true;
|
bool allTexturesLoaded = true;
|
||||||
foreach(auto renderItem, _modelMeshRenderItemsSet) {
|
foreach(auto renderItem, _modelMeshRenderItemsSet) {
|
||||||
auto meshPart = renderItem.get();
|
auto meshPart = renderItem.get();
|
||||||
bool allTexturesForThisMesh = meshPart->calculateMaterialSize();
|
bool allTexturesForThisMesh = meshPart->calculateMaterialSize();
|
||||||
allTexturesLoaded = allTexturesLoaded & allTexturesForThisMesh;
|
allTexturesLoaded = allTexturesLoaded & allTexturesForThisMesh;
|
||||||
textureSize += meshPart->getMaterialTextureSize();
|
textureSize += meshPart->getMaterialTextureSize();
|
||||||
|
textureCount += meshPart->getMaterialTextureCount();
|
||||||
}
|
}
|
||||||
_renderInfoTextureSize = textureSize;
|
_renderInfoTextureSize = textureSize;
|
||||||
_hasCalculatedTextureSize = allTexturesLoaded; // only do this once
|
_renderInfoTextureCount = textureCount;
|
||||||
|
_hasCalculatedTextureInfo = allTexturesLoaded; // only do this once
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Model::getRenderInfoTextureSize() {
|
||||||
|
calculateTextureInfo();
|
||||||
return _renderInfoTextureSize;
|
return _renderInfoTextureSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Model::getRenderInfoTextureCount() {
|
||||||
|
calculateTextureInfo();
|
||||||
|
return _renderInfoTextureCount;
|
||||||
|
}
|
||||||
|
|
||||||
void Model::updateRenderItems() {
|
void Model::updateRenderItems() {
|
||||||
if (!_addedToScene) {
|
if (!_addedToScene) {
|
||||||
|
|
|
@ -233,8 +233,8 @@ public:
|
||||||
void setLoadingPriority(float priority) { _loadingPriority = priority; }
|
void setLoadingPriority(float priority) { _loadingPriority = priority; }
|
||||||
|
|
||||||
size_t getRenderInfoVertexCount() const { return _renderInfoVertexCount; }
|
size_t getRenderInfoVertexCount() const { return _renderInfoVertexCount; }
|
||||||
int getRenderInfoTextureCount() const { return _renderInfoTextureCount; }
|
|
||||||
size_t getRenderInfoTextureSize();
|
size_t getRenderInfoTextureSize();
|
||||||
|
int getRenderInfoTextureCount();
|
||||||
int getRenderInfoDrawCalls() const { return _renderInfoDrawCalls; }
|
int getRenderInfoDrawCalls() const { return _renderInfoDrawCalls; }
|
||||||
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
|
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
|
||||||
|
|
||||||
|
@ -409,13 +409,14 @@ protected:
|
||||||
size_t _renderInfoVertexCount { 0 };
|
size_t _renderInfoVertexCount { 0 };
|
||||||
int _renderInfoTextureCount { 0 };
|
int _renderInfoTextureCount { 0 };
|
||||||
size_t _renderInfoTextureSize { 0 };
|
size_t _renderInfoTextureSize { 0 };
|
||||||
bool _hasCalculatedTextureSize { false };
|
bool _hasCalculatedTextureInfo { false };
|
||||||
int _renderInfoDrawCalls { 0 };
|
int _renderInfoDrawCalls { 0 };
|
||||||
int _renderInfoHasTransparent { false };
|
int _renderInfoHasTransparent { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _loadingPriority { 0.0f };
|
float _loadingPriority { 0.0f };
|
||||||
|
|
||||||
|
void calculateTextureInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ModelPointer)
|
Q_DECLARE_METATYPE(ModelPointer)
|
||||||
|
|
|
@ -62,3 +62,48 @@ void qListtoRgbColor(const QVariant& q, rgbColor& returnValue) {
|
||||||
returnValue[GREEN_INDEX] = qList[GREEN_INDEX].toInt();
|
returnValue[GREEN_INDEX] = qList[GREEN_INDEX].toInt();
|
||||||
returnValue[BLUE_INDEX] = qList[BLUE_INDEX].toInt();
|
returnValue[BLUE_INDEX] = qList[BLUE_INDEX].toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glm::vec3 qMapToGlmVec3(const QVariant& q) {
|
||||||
|
QVariantMap qMap = q.toMap();
|
||||||
|
if (qMap.contains("x") && qMap.contains("y") && qMap.contains("y")) {
|
||||||
|
return glm::vec3(
|
||||||
|
qMap["x"].toFloat(),
|
||||||
|
qMap["y"].toFloat(),
|
||||||
|
qMap["z"].toFloat()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return glm::vec3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat qMapToGlmQuat(const QVariant& q) {
|
||||||
|
QVariantMap qMap = q.toMap();
|
||||||
|
if (qMap.contains("w") && qMap.contains("x") && qMap.contains("y") && qMap.contains("z")) {
|
||||||
|
return glm::quat(
|
||||||
|
qMap["w"].toFloat(),
|
||||||
|
qMap["x"].toFloat(),
|
||||||
|
qMap["y"].toFloat(),
|
||||||
|
qMap["z"].toFloat()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 qMapToGlmMat4(const QVariant& q) {
|
||||||
|
QVariantMap qMap = q.toMap();
|
||||||
|
if (qMap.contains("r0c0") && qMap.contains("r1c0") && qMap.contains("r2c0") && qMap.contains("r3c0")
|
||||||
|
&& qMap.contains("r0c1") && qMap.contains("r1c1") && qMap.contains("r2c1") && qMap.contains("r3c1")
|
||||||
|
&& qMap.contains("r0c2") && qMap.contains("r1c2") && qMap.contains("r2c2") && qMap.contains("r3c2")
|
||||||
|
&& qMap.contains("r0c3") && qMap.contains("r1c3") && qMap.contains("r2c3") && qMap.contains("r3c3")) {
|
||||||
|
return glm::mat4(
|
||||||
|
qMap["r0c0"].toFloat(), qMap["r1c0"].toFloat(), qMap["r2c0"].toFloat(), qMap["r3c0"].toFloat(),
|
||||||
|
qMap["r0c1"].toFloat(), qMap["r1c1"].toFloat(), qMap["r2c1"].toFloat(), qMap["r3c1"].toFloat(),
|
||||||
|
qMap["r0c2"].toFloat(), qMap["r1c2"].toFloat(), qMap["r2c2"].toFloat(), qMap["r3c2"].toFloat(),
|
||||||
|
qMap["r0c3"].toFloat(), qMap["r1c3"].toFloat(), qMap["r2c3"].toFloat(), qMap["r3c3"].toFloat()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return glm::mat4();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,3 +27,7 @@ QVariantMap glmToQMap(const glm::quat& glmQuat);
|
||||||
glm::vec3 qListToGlmVec3(const QVariant& q);
|
glm::vec3 qListToGlmVec3(const QVariant& q);
|
||||||
glm::quat qListToGlmQuat(const QVariant& q);
|
glm::quat qListToGlmQuat(const QVariant& q);
|
||||||
void qListtoRgbColor(const QVariant& q, rgbColor& returnValue);
|
void qListtoRgbColor(const QVariant& q, rgbColor& returnValue);
|
||||||
|
|
||||||
|
glm::vec3 qMapToGlmVec3(const QVariant& q);
|
||||||
|
glm::quat qMapToGlmQuat(const QVariant& q);
|
||||||
|
glm::mat4 qMapToGlmMat4(const QVariant& q);
|
||||||
|
|
|
@ -366,6 +366,10 @@ input[type=button]:disabled {
|
||||||
background: linear-gradient(#575757 20%, #252525 100%);
|
background: linear-gradient(#575757 20%, #252525 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type=button][pressed=pressed] {
|
||||||
|
color: #00b4ef;
|
||||||
|
}
|
||||||
|
|
||||||
input[type=checkbox] {
|
input[type=checkbox] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -861,13 +865,8 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
position: relative; /* New positioning context. */
|
position: relative; /* New positioning context. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#entity-list .glyph {
|
|
||||||
font-family: HiFi-Glyphs;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#search-area {
|
#search-area {
|
||||||
padding-right: 148px;
|
padding-right: 168px;
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,13 +874,23 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
width: 98%;
|
width: 98%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#in-view {
|
||||||
|
position: absolute;
|
||||||
|
right: 126px;
|
||||||
|
}
|
||||||
|
|
||||||
#radius-and-unit {
|
#radius-and-unit {
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: -148px;
|
margin-right: -168px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -17px;
|
top: -17px;
|
||||||
}
|
}
|
||||||
|
#radius-and-unit label {
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
#radius-and-unit input {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
#entity-table-scroll {
|
#entity-table-scroll {
|
||||||
/* Height is set by JavaScript. */
|
/* Height is set by JavaScript. */
|
||||||
|
@ -896,6 +905,10 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
background-color: #1c1c1c;
|
background-color: #1c1c1c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#entity-table-scroll .glyph {
|
||||||
|
font-family: HiFi-Glyphs;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
#entity-table {
|
#entity-table {
|
||||||
margin-top: -28px;
|
margin-top: -28px;
|
||||||
|
@ -905,19 +918,6 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
background-color: #1c1c1c;
|
background-color: #1c1c1c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#col-type {
|
|
||||||
width: 16%;
|
|
||||||
}
|
|
||||||
#col-name {
|
|
||||||
width: 34%;
|
|
||||||
}
|
|
||||||
#col-url {
|
|
||||||
width: 34%;
|
|
||||||
}
|
|
||||||
#col-locked, #col-visible {
|
|
||||||
width: 8%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#entity-table thead tr, #entity-table thead tr th,
|
#entity-table thead tr, #entity-table thead tr th,
|
||||||
#entity-table tfoot tr, #entity-table tfoot tr td {
|
#entity-table tfoot tr, #entity-table tfoot tr td {
|
||||||
background: none;
|
background: none;
|
||||||
|
@ -938,12 +938,22 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
top: 49px;
|
top: 49px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
word-wrap: nowrap;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#entity-table thead th {
|
.verticesCount, .texturesCount, .texturesSize, .drawCalls {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#entity-table th {
|
||||||
|
display: inline-block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 0 0 8px;
|
padding: 5px 0 0 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
#entity-table th:focus {
|
#entity-table th:focus {
|
||||||
|
@ -952,17 +962,54 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
|
|
||||||
#entity-table th .glyph {
|
#entity-table th .glyph {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: 0;
|
left: 4px;
|
||||||
|
}
|
||||||
|
#entity-table th .glyph + .sort-order {
|
||||||
|
position: relative;
|
||||||
|
left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#entity-table th#entity-hasScript {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
#entity-table th#entity-hasScript .glyph {
|
||||||
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#entity-table thead .sort-order {
|
#entity-table thead .sort-order {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
margin: -5px 0 -3px 0;
|
margin: -5px 0 -3px 0;
|
||||||
text-align: right;
|
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#entity-table th #info-toggle {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
left: initial;
|
||||||
|
right: 0;
|
||||||
|
width: 11px;
|
||||||
|
background-color: #1c1c1c;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
#entity-table th #info-toggle span {
|
||||||
|
position: relative;
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th#entity-hasTransparent .glyph {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 24px !important;
|
||||||
|
margin: -6px;
|
||||||
|
position: relative;
|
||||||
|
top: -6px;
|
||||||
|
}
|
||||||
|
th#entity-hasTransparent .sort-order {
|
||||||
|
position: relative;
|
||||||
|
top: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
#entity-table td {
|
#entity-table td {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
@ -971,6 +1018,11 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
#entity-table td.hasTransparent.glyph {
|
||||||
|
font-size: 22px;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
#entity-table tfoot {
|
#entity-table tfoot {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -984,6 +1036,82 @@ textarea:enabled[scrolling="true"]::-webkit-resizer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#col-type {
|
||||||
|
width: 16%;
|
||||||
|
}
|
||||||
|
#col-name {
|
||||||
|
width: 34%;
|
||||||
|
}
|
||||||
|
#col-url {
|
||||||
|
width: 34%;
|
||||||
|
}
|
||||||
|
#col-locked, #col-visible {
|
||||||
|
width: 9%;
|
||||||
|
}
|
||||||
|
#col-verticesCount, #col-texturesCount, #col-texturesSize, #col-hasTransparent, #col-drawCalls, #col-hasScript {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showExtraInfo #col-type {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-name {
|
||||||
|
width: 19%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-url {
|
||||||
|
width: 19%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-locked, .showExtraInfo #col-visible {
|
||||||
|
width: 4%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-verticesCount {
|
||||||
|
width: 8%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-texturesCount {
|
||||||
|
width: 8%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-texturesSize {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-hasTransparent {
|
||||||
|
width: 4%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-drawCalls {
|
||||||
|
width: 8%;
|
||||||
|
}
|
||||||
|
.showExtraInfo #col-hasScript {
|
||||||
|
width: 6%;
|
||||||
|
}
|
||||||
|
|
||||||
|
th#entity-verticesCount, th#entity-texturesCount, th#entity-texturesSize, th#entity-hasTransparent, th#entity-drawCalls,
|
||||||
|
th#entity-hasScript {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verticesCount, .texturesCount, .texturesSize, .hasTransparent, .drawCalls, .hasScript {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#entity-visible {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showExtraInfo #entity-verticesCount, .showExtraInfo #entity-texturesCount, .showExtraInfo #entity-texturesSize,
|
||||||
|
.showExtraInfo #entity-hasTransparent, .showExtraInfo #entity-drawCalls, .showExtraInfo #entity-hasScript {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showExtraInfo .verticesCount, .showExtraInfo .texturesCount, .showExtraInfo .texturesSize, .showExtraInfo .hasTransparent,
|
||||||
|
.showExtraInfo .drawCalls, .showExtraInfo .hasScript {
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showExtraInfo #entity-visible {
|
||||||
|
border-right: 1px solid #575757;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#no-entities {
|
#no-entities {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -1102,4 +1230,4 @@ input#reset-to-natural-dimensions {
|
||||||
margin-top:5px;
|
margin-top:5px;
|
||||||
font-size:16px;
|
font-size:16px;
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<div id="entity-list">
|
<div id="entity-list">
|
||||||
<div id="search-area">
|
<div id="search-area">
|
||||||
<span class="icon-input"><input type="text" class="search" id="filter" placeholder="Filter" /><span>Y</span></span>
|
<span class="icon-input"><input type="text" class="search" id="filter" placeholder="Filter" /><span>Y</span></span>
|
||||||
|
<input type="button" id="in-view" class="glyph" value="" />
|
||||||
<div id="radius-and-unit" class="number">
|
<div id="radius-and-unit" class="number">
|
||||||
<label for="radius">Search radius <span class="unit">m</span></label>
|
<label for="radius">Search radius <span class="unit">m</span></label>
|
||||||
<input type="number" id="radius" value="100" />
|
<input type="number" id="radius" value="100" />
|
||||||
|
@ -37,39 +38,57 @@
|
||||||
<div id="entity-table-scroll">
|
<div id="entity-table-scroll">
|
||||||
<table id="entity-table">
|
<table id="entity-table">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col span="1" id="col-type" />
|
<col span="1" id="col-type" />
|
||||||
<col span="1" id="col-name" />
|
<col span="1" id="col-name" />
|
||||||
<col span="1" id="col-url" />
|
<col span="1" id="col-url" />
|
||||||
<col span="1" id="col-locked" />
|
<col span="1" id="col-locked" />
|
||||||
<col span="1" id="col-visible" />
|
<col span="1" id="col-visible" />
|
||||||
|
<col span="1" id="col-verticesCount" />
|
||||||
|
<col span="1" id="col-texturesCount" />
|
||||||
|
<col span="1" id="col-texturesSize" />
|
||||||
|
<col span="1" id="col-hasTransparent" />
|
||||||
|
<col span="1" id="col-drawCalls" />
|
||||||
|
<col span="1" id="col-hasScript" />
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th id="entity-type" data-sort="type">Type<span class="sort-order"></span></th>
|
<th id="entity-type">Type<span class="sort-order"></span><span id="info-toggle"><span class="glyph">D</span></span></th>
|
||||||
<th id="entity-name" data-sort="type">Name<span class="sort-order"></span></th>
|
<th id="entity-name">Name<span class="sort-order"></span></th>
|
||||||
<th id="entity-url" data-sort="url">File<span class="sort-order"></span></th>
|
<th id="entity-url">File<span class="sort-order"></span></th>
|
||||||
<th id="entity-locked" data-sort="locked"><span class="glyph"></span><span class="sort-order"></span></th>
|
<th id="entity-locked"><span class="glyph"></span><span class="sort-order"></span></th>
|
||||||
<th colspan="2" id="entity-visible" data-sort="visible"><span class="glyph"></span><span class="sort-order"></span></th>
|
<th id="entity-visible"><span class="glyph"></span><span class="sort-order"></span></th>
|
||||||
|
<th id="entity-verticesCount">Verts<span class="sort-order"></span></th>
|
||||||
|
<th id="entity-texturesCount">Texts<span class="sort-order"></span></th>
|
||||||
|
<th id="entity-texturesSize">Text MB<span class="sort-order"></span></th>
|
||||||
|
<th id="entity-hasTransparent"><span class="glyph"></span><span class="sort-order"></span></th>
|
||||||
|
<th id="entity-drawCalls">Draws<span class="sort-order"></span></th>
|
||||||
|
<th colspan="1" id="entity-hasScript"><span class="glyph">k</span><span class="sort-order"></span></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list" id="entity-table-body">
|
<tbody class="list" id="entity-table-body">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="type">Type</td>
|
<td class="type"></td>
|
||||||
<td class="name">Name</td>
|
<td class="name"></td>
|
||||||
<td class="url"><div class='outer'><div class='inner'>URL</div></div></td>
|
<td class="url"><div class='outer'><div class='inner'></div></div></td>
|
||||||
<td class="locked glyph">?</td>
|
<td class="locked glyph"></td>
|
||||||
<td class="visible glyph">?</td>
|
<td class="visible glyph"></td>
|
||||||
<td class="id" style="display: none">ID</td>
|
<td class="verticesCount"></td>
|
||||||
|
<td class="texturesCount"></td>
|
||||||
|
<td class="texturesSize"></td>
|
||||||
|
<td class="hasTransparent glyph"></td>
|
||||||
|
<td class="drawCalls"></td>
|
||||||
|
<td class="hasScript glyph"></td>
|
||||||
|
<td class="id" style="display: none"></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td id="footer-text" colspan="5"> </td>
|
<td id="footer-text" colspan="11"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
<div id="no-entities">
|
<div id="no-entities">
|
||||||
No entities found within a <span id="no-entities-radius">100</span> meter radius. Try moving to a different location and refreshing.
|
No entities found <span id="no-entities-in-view">in view</span> within a <span id="no-entities-radius">100</span> meter radius. Try moving to a different location and refreshing.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,10 +12,12 @@ var currentSortColumn = 'type';
|
||||||
var currentSortOrder = 'des';
|
var currentSortOrder = 'des';
|
||||||
var entityList = null;
|
var entityList = null;
|
||||||
var refreshEntityListTimer = null;
|
var refreshEntityListTimer = null;
|
||||||
const ASCENDING_STRING = '▾';
|
const ASCENDING_STRING = '▴';
|
||||||
const DESCENDING_STRING = '▴';
|
const DESCENDING_STRING = '▾';
|
||||||
const LOCKED_GLYPH = "";
|
const LOCKED_GLYPH = "";
|
||||||
const VISIBLE_GLYPH = "";
|
const VISIBLE_GLYPH = "";
|
||||||
|
const TRANSPARENCY_GLYPH = "";
|
||||||
|
const SCRIPT_GLYPH = "k";
|
||||||
const DELETE = 46; // Key code for the delete key.
|
const DELETE = 46; // Key code for the delete key.
|
||||||
const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities.
|
const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities.
|
||||||
|
|
||||||
|
@ -33,10 +35,16 @@ function loaded() {
|
||||||
elToggleLocked = document.getElementById("locked");
|
elToggleLocked = document.getElementById("locked");
|
||||||
elToggleVisible = document.getElementById("visible");
|
elToggleVisible = document.getElementById("visible");
|
||||||
elDelete = document.getElementById("delete");
|
elDelete = document.getElementById("delete");
|
||||||
elTeleport = document.getElementById("teleport");
|
elFilter = document.getElementById("filter");
|
||||||
|
elInView = document.getElementById("in-view")
|
||||||
elRadius = document.getElementById("radius");
|
elRadius = document.getElementById("radius");
|
||||||
|
elTeleport = document.getElementById("teleport");
|
||||||
|
elEntityTable = document.getElementById("entity-table");
|
||||||
|
elInfoToggle = document.getElementById("info-toggle");
|
||||||
|
elInfoToggleGlyph = elInfoToggle.firstChild;
|
||||||
elFooter = document.getElementById("footer-text");
|
elFooter = document.getElementById("footer-text");
|
||||||
elNoEntitiesMessage = document.getElementById("no-entities");
|
elNoEntitiesMessage = document.getElementById("no-entities");
|
||||||
|
elNoEntitiesInView = document.getElementById("no-entities-in-view");
|
||||||
elNoEntitiesRadius = document.getElementById("no-entities-radius");
|
elNoEntitiesRadius = document.getElementById("no-entities-radius");
|
||||||
elEntityTableScroll = document.getElementById("entity-table-scroll");
|
elEntityTableScroll = document.getElementById("entity-table-scroll");
|
||||||
|
|
||||||
|
@ -55,7 +63,25 @@ function loaded() {
|
||||||
document.getElementById("entity-visible").onclick = function () {
|
document.getElementById("entity-visible").onclick = function () {
|
||||||
setSortColumn('visible');
|
setSortColumn('visible');
|
||||||
};
|
};
|
||||||
|
document.getElementById("entity-verticesCount").onclick = function () {
|
||||||
|
setSortColumn('verticesCount');
|
||||||
|
};
|
||||||
|
document.getElementById("entity-texturesCount").onclick = function () {
|
||||||
|
setSortColumn('texturesCount');
|
||||||
|
};
|
||||||
|
document.getElementById("entity-texturesSize").onclick = function () {
|
||||||
|
setSortColumn('texturesSize');
|
||||||
|
};
|
||||||
|
document.getElementById("entity-hasTransparent").onclick = function () {
|
||||||
|
setSortColumn('hasTransparent');
|
||||||
|
};
|
||||||
|
document.getElementById("entity-drawCalls").onclick = function () {
|
||||||
|
setSortColumn('drawCalls');
|
||||||
|
};
|
||||||
|
document.getElementById("entity-hasScript").onclick = function () {
|
||||||
|
setSortColumn('hasScript');
|
||||||
|
};
|
||||||
|
|
||||||
function onRowClicked(clickEvent) {
|
function onRowClicked(clickEvent) {
|
||||||
var id = this.dataset.entityId;
|
var id = this.dataset.entityId;
|
||||||
var selection = [this.dataset.entityId];
|
var selection = [this.dataset.entityId];
|
||||||
|
@ -106,12 +132,29 @@ function loaded() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEntity(id, name, type, url, locked, visible) {
|
const BYTES_PER_MEGABYTE = 1024 * 1024;
|
||||||
|
|
||||||
|
function decimalMegabytes(number) {
|
||||||
|
return number ? (number / BYTES_PER_MEGABYTE).toFixed(1) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayIfNonZero(number) {
|
||||||
|
return number ? number : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function addEntity(id, name, type, url, locked, visible, verticesCount, texturesCount, texturesSize, hasTransparent,
|
||||||
|
drawCalls, hasScript) {
|
||||||
|
|
||||||
var urlParts = url.split('/');
|
var urlParts = url.split('/');
|
||||||
var filename = urlParts[urlParts.length - 1];
|
var filename = urlParts[urlParts.length - 1];
|
||||||
|
|
||||||
if (entities[id] === undefined) {
|
if (entities[id] === undefined) {
|
||||||
entityList.add([{ id: id, name: name, type: type, url: filename, locked: locked, visible: visible }],
|
entityList.add([{
|
||||||
|
id: id, name: name, type: type, url: filename, locked: locked, visible: visible,
|
||||||
|
verticesCount: displayIfNonZero(verticesCount), texturesCount: displayIfNonZero(texturesCount),
|
||||||
|
texturesSize: decimalMegabytes(texturesSize), hasTransparent: hasTransparent,
|
||||||
|
drawCalls: displayIfNonZero(drawCalls), hasScript: hasScript
|
||||||
|
}],
|
||||||
function (items) {
|
function (items) {
|
||||||
var currentElement = items[0].elm;
|
var currentElement = items[0].elm;
|
||||||
var id = items[0]._values.id;
|
var id = items[0]._values.id;
|
||||||
|
@ -148,7 +191,13 @@ function loaded() {
|
||||||
type: document.querySelector('#entity-type .sort-order'),
|
type: document.querySelector('#entity-type .sort-order'),
|
||||||
url: document.querySelector('#entity-url .sort-order'),
|
url: document.querySelector('#entity-url .sort-order'),
|
||||||
locked: document.querySelector('#entity-locked .sort-order'),
|
locked: document.querySelector('#entity-locked .sort-order'),
|
||||||
visible: document.querySelector('#entity-visible .sort-order')
|
visible: document.querySelector('#entity-visible .sort-order'),
|
||||||
|
verticesCount: document.querySelector('#entity-verticesCount .sort-order'),
|
||||||
|
texturesCount: document.querySelector('#entity-texturesCount .sort-order'),
|
||||||
|
texturesSize: document.querySelector('#entity-texturesSize .sort-order'),
|
||||||
|
hasTransparent: document.querySelector('#entity-hasTransparent .sort-order'),
|
||||||
|
drawCalls: document.querySelector('#entity-drawCalls .sort-order'),
|
||||||
|
hasScript: document.querySelector('#entity-hasScript .sort-order'),
|
||||||
}
|
}
|
||||||
function setSortColumn(column) {
|
function setSortColumn(column) {
|
||||||
if (currentSortColumn == column) {
|
if (currentSortColumn == column) {
|
||||||
|
@ -168,10 +217,23 @@ function loaded() {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' }));
|
EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshFooter() {
|
||||||
|
if (selectedEntities.length > 1) {
|
||||||
|
elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected";
|
||||||
|
} else if (selectedEntities.length === 1) {
|
||||||
|
elFooter.firstChild.nodeValue = "1 entity selected";
|
||||||
|
} else if (entityList.visibleItems.length === 1) {
|
||||||
|
elFooter.firstChild.nodeValue = "1 entity found";
|
||||||
|
} else {
|
||||||
|
elFooter.firstChild.nodeValue = entityList.visibleItems.length + " entities found";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function refreshEntityListObject() {
|
function refreshEntityListObject() {
|
||||||
refreshEntityListTimer = null;
|
refreshEntityListTimer = null;
|
||||||
entityList.sort(currentSortColumn, { order: currentSortOrder });
|
entityList.sort(currentSortColumn, { order: currentSortOrder });
|
||||||
entityList.search(document.getElementById("filter").value);
|
entityList.search(elFilter.value);
|
||||||
|
refreshFooter();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSelectedEntities(selectedEntities) {
|
function updateSelectedEntities(selectedEntities) {
|
||||||
|
@ -189,16 +251,6 @@ function loaded() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedEntities.length > 1) {
|
|
||||||
elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected";
|
|
||||||
} else if (selectedEntities.length === 1) {
|
|
||||||
elFooter.firstChild.nodeValue = "1 entity selected";
|
|
||||||
} else if (entityList.visibleItems.length === 1) {
|
|
||||||
elFooter.firstChild.nodeValue = "1 entity found";
|
|
||||||
} else {
|
|
||||||
elFooter.firstChild.nodeValue = entityList.visibleItems.length + " entities found";
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: Fixes the footer and header text sometimes not displaying after adding or deleting entities.
|
// HACK: Fixes the footer and header text sometimes not displaying after adding or deleting entities.
|
||||||
// The problem appears to be a bug in the Qt HTML/CSS rendering (Qt 5.5).
|
// The problem appears to be a bug in the Qt HTML/CSS rendering (Qt 5.5).
|
||||||
document.getElementById("radius").focus();
|
document.getElementById("radius").focus();
|
||||||
|
@ -235,13 +287,29 @@ function loaded() {
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
|
var isFilterInView = false;
|
||||||
|
var FILTER_IN_VIEW_ATTRIBUTE = "pressed";
|
||||||
|
elNoEntitiesInView.style.display = "none";
|
||||||
|
elInView.onclick = function () {
|
||||||
|
isFilterInView = !isFilterInView;
|
||||||
|
if (isFilterInView) {
|
||||||
|
elInView.setAttribute(FILTER_IN_VIEW_ATTRIBUTE, FILTER_IN_VIEW_ATTRIBUTE);
|
||||||
|
elNoEntitiesInView.style.display = "inline";
|
||||||
|
} else {
|
||||||
|
elInView.removeAttribute(FILTER_IN_VIEW_ATTRIBUTE);
|
||||||
|
elNoEntitiesInView.style.display = "none";
|
||||||
|
}
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({ type: "filterInView", filterInView: isFilterInView }));
|
||||||
|
refreshEntities();
|
||||||
|
}
|
||||||
|
|
||||||
elRadius.onchange = function () {
|
elRadius.onchange = function () {
|
||||||
elRadius.value = Math.max(elRadius.value, 0);
|
elRadius.value = Math.max(elRadius.value, 0);
|
||||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elRadius.value }));
|
EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elRadius.value }));
|
||||||
refreshEntities();
|
refreshEntities();
|
||||||
elNoEntitiesRadius.firstChild.nodeValue = elRadius.value;
|
elNoEntitiesRadius.firstChild.nodeValue = elRadius.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.EventBridge !== undefined) {
|
if (window.EventBridge !== undefined) {
|
||||||
EventBridge.scriptEventReceived.connect(function(data) {
|
EventBridge.scriptEventReceived.connect(function(data) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
@ -264,7 +332,11 @@ function loaded() {
|
||||||
var id = newEntities[i].id;
|
var id = newEntities[i].id;
|
||||||
addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url,
|
addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url,
|
||||||
newEntities[i].locked ? LOCKED_GLYPH : null,
|
newEntities[i].locked ? LOCKED_GLYPH : null,
|
||||||
newEntities[i].visible ? VISIBLE_GLYPH : null);
|
newEntities[i].visible ? VISIBLE_GLYPH : null,
|
||||||
|
newEntities[i].verticesCount, newEntities[i].texturesCount, newEntities[i].texturesSize,
|
||||||
|
newEntities[i].hasTransparent ? TRANSPARENCY_GLYPH : null,
|
||||||
|
newEntities[i].drawCalls,
|
||||||
|
newEntities[i].hasScript ? SCRIPT_GLYPH : null);
|
||||||
}
|
}
|
||||||
updateSelectedEntities(data.selectedIDs);
|
updateSelectedEntities(data.selectedIDs);
|
||||||
resize();
|
resize();
|
||||||
|
@ -278,6 +350,7 @@ function loaded() {
|
||||||
// Take up available window space
|
// Take up available window space
|
||||||
elEntityTableScroll.style.height = window.innerHeight - 207;
|
elEntityTableScroll.style.height = window.innerHeight - 207;
|
||||||
|
|
||||||
|
var SCROLLABAR_WIDTH = 21;
|
||||||
var tds = document.querySelectorAll("#entity-table-body tr:first-child td");
|
var tds = document.querySelectorAll("#entity-table-body tr:first-child td");
|
||||||
var ths = document.querySelectorAll("#entity-table thead th");
|
var ths = document.querySelectorAll("#entity-table thead th");
|
||||||
if (tds.length >= ths.length) {
|
if (tds.length >= ths.length) {
|
||||||
|
@ -287,16 +360,53 @@ function loaded() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Reasonable widths if nothing is displayed
|
// Reasonable widths if nothing is displayed
|
||||||
var tableWidth = document.getElementById("entity-table").offsetWidth;
|
var tableWidth = document.getElementById("entity-table").offsetWidth - SCROLLABAR_WIDTH;
|
||||||
ths[0].width = 0.16 * tableWidth;
|
if (showExtraInfo) {
|
||||||
ths[1].width = 0.34 * tableWidth;
|
ths[0].width = 0.10 * tableWidth;
|
||||||
ths[2].width = 0.34 * tableWidth;
|
ths[1].width = 0.20 * tableWidth;
|
||||||
ths[3].width = 0.08 * tableWidth;
|
ths[2].width = 0.20 * tableWidth;
|
||||||
ths[4].width = 0.08 * tableWidth;
|
ths[3].width = 0.04 * tableWidth;
|
||||||
|
ths[4].width = 0.04 * tableWidth;
|
||||||
|
ths[5].width = 0.08 * tableWidth;
|
||||||
|
ths[6].width = 0.08 * tableWidth;
|
||||||
|
ths[7].width = 0.10 * tableWidth;
|
||||||
|
ths[8].width = 0.04 * tableWidth;
|
||||||
|
ths[9].width = 0.08 * tableWidth;
|
||||||
|
ths[10].width = 0.04 * tableWidth + SCROLLABAR_WIDTH;
|
||||||
|
} else {
|
||||||
|
ths[0].width = 0.16 * tableWidth;
|
||||||
|
ths[1].width = 0.34 * tableWidth;
|
||||||
|
ths[2].width = 0.34 * tableWidth;
|
||||||
|
ths[3].width = 0.08 * tableWidth;
|
||||||
|
ths[4].width = 0.08 * tableWidth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onresize = resize;
|
window.onresize = resize;
|
||||||
|
elFilter.onchange = resize;
|
||||||
|
elFilter.onblur = refreshFooter;
|
||||||
|
|
||||||
|
|
||||||
|
var showExtraInfo = false;
|
||||||
|
var COLLAPSE_EXTRA_INFO = "E";
|
||||||
|
var EXPAND_EXTRA_INFO = "D";
|
||||||
|
|
||||||
|
function toggleInfo(event) {
|
||||||
|
showExtraInfo = !showExtraInfo;
|
||||||
|
if (showExtraInfo) {
|
||||||
|
elEntityTable.className = "showExtraInfo";
|
||||||
|
elInfoToggleGlyph.innerHTML = COLLAPSE_EXTRA_INFO;
|
||||||
|
} else {
|
||||||
|
elEntityTable.className = "";
|
||||||
|
elInfoToggleGlyph.innerHTML = EXPAND_EXTRA_INFO;
|
||||||
|
}
|
||||||
|
resize();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
elInfoToggle.addEventListener("click", toggleInfo, true);
|
||||||
|
|
||||||
|
|
||||||
resize();
|
resize();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ EntityListTool = function(opts) {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var filterInView = false;
|
||||||
var searchRadius = 100;
|
var searchRadius = 100;
|
||||||
|
|
||||||
var visible = false;
|
var visible = false;
|
||||||
|
@ -48,20 +48,41 @@ EntityListTool = function(opts) {
|
||||||
webView.emitScriptEvent(JSON.stringify(data));
|
webView.emitScriptEvent(JSON.stringify(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function valueIfDefined(value) {
|
||||||
|
return value !== undefined ? value : "";
|
||||||
|
}
|
||||||
|
|
||||||
that.sendUpdate = function() {
|
that.sendUpdate = function() {
|
||||||
var entities = [];
|
var entities = [];
|
||||||
var ids = Entities.findEntities(MyAvatar.position, searchRadius);
|
|
||||||
|
var ids;
|
||||||
|
if (filterInView) {
|
||||||
|
ids = Entities.findEntitiesInFrustum(Camera.frustum);
|
||||||
|
} else {
|
||||||
|
ids = Entities.findEntities(MyAvatar.position, searchRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
var cameraPosition = Camera.position;
|
||||||
for (var i = 0; i < ids.length; i++) {
|
for (var i = 0; i < ids.length; i++) {
|
||||||
var id = ids[i];
|
var id = ids[i];
|
||||||
var properties = Entities.getEntityProperties(id);
|
var properties = Entities.getEntityProperties(id);
|
||||||
entities.push({
|
|
||||||
id: id,
|
if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) {
|
||||||
name: properties.name,
|
entities.push({
|
||||||
type: properties.type,
|
id: id,
|
||||||
url: properties.type == "Model" ? properties.modelURL : "",
|
name: properties.name,
|
||||||
locked: properties.locked,
|
type: properties.type,
|
||||||
visible: properties.visible
|
url: properties.type == "Model" ? properties.modelURL : "",
|
||||||
});
|
locked: properties.locked,
|
||||||
|
visible: properties.visible,
|
||||||
|
verticesCount: valueIfDefined(properties.renderInfo.verticesCount),
|
||||||
|
texturesCount: valueIfDefined(properties.renderInfo.texturesCount),
|
||||||
|
texturesSize: valueIfDefined(properties.renderInfo.texturesSize),
|
||||||
|
hasTransparent: valueIfDefined(properties.renderInfo.hasTransparent),
|
||||||
|
drawCalls: valueIfDefined(properties.renderInfo.drawCalls),
|
||||||
|
hasScript: properties.script !== ""
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedIDs = [];
|
var selectedIDs = [];
|
||||||
|
@ -105,9 +126,10 @@ EntityListTool = function(opts) {
|
||||||
toggleSelectedEntitiesLocked();
|
toggleSelectedEntitiesLocked();
|
||||||
} else if (data.type == "toggleVisible") {
|
} else if (data.type == "toggleVisible") {
|
||||||
toggleSelectedEntitiesVisible();
|
toggleSelectedEntitiesVisible();
|
||||||
|
} else if (data.type === "filterInView") {
|
||||||
|
filterInView = data.filterInView === true;
|
||||||
} else if (data.type === "radius") {
|
} else if (data.type === "radius") {
|
||||||
searchRadius = data.radius;
|
searchRadius = data.radius;
|
||||||
that.sendUpdate();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue