Getting there.

This commit is contained in:
Zach Fox 2017-07-26 11:41:27 -07:00
parent 9020607ccf
commit 9147bc21d0
12 changed files with 76 additions and 53 deletions

View file

@ -36,6 +36,8 @@ ContextOverlayInterface::ContextOverlayInterface() {
auto entityTreeRenderer = DependencyManager::get<EntityTreeRenderer>().data();
connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&)));
connect(entityTreeRenderer, SIGNAL(hoverEnterEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(highlightEntity(const EntityItemID&, const PointerEvent&)));
connect(entityTreeRenderer, SIGNAL(hoverLeaveEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(unHighlightEntity(const EntityItemID&, const PointerEvent&)));
connect(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"), &TabletProxy::tabletShownChanged, this, [&]() {
if (_contextOverlayJustClicked && _hmdScriptingInterface->isMounted()) {
QUuid tabletFrameID = _hmdScriptingInterface->getCurrentTabletFrameID();
@ -76,13 +78,18 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
glm::vec3 cameraPosition = qApp->getCamera().getPosition();
float distanceFromCameraToEntity = glm::distance(entityProperties.getPosition(), cameraPosition);
glm::vec3 entityDimensions = entityProperties.getDimensions();
glm::vec3 contextOverlayPosition;
glm::vec3 entityPosition = entityProperties.getPosition();
glm::vec3 contextOverlayPosition = entityProperties.getPosition();
glm::vec2 contextOverlayDimensions;
// Draw the outline overlay
// This also gives us the centerpoint of the entity even if
// the the entity doesn't use the default registration point.
glm::vec3 entityCenterPoint = drawOutlineOverlay(entityItemID);
// Update the position of the overlay if the registration point of the entity
// isn't default
if (entityProperties.getRegistrationPoint() != glm::vec3(0.5f)) {
glm::vec3 adjustPos = entityProperties.getRegistrationPoint() - glm::vec3(0.5f);
entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityProperties.getDimensions()));
}
AABox boundingBox = AABox(entityPosition - (entityDimensions / 2.0f), entityDimensions * 2.0f);
// Update the cached Entity Marketplace ID
_entityMarketplaceID = entityProperties.getMarketplaceID();
@ -91,7 +98,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
setCurrentEntityWithContextOverlay(entityItemID);
// Here, we determine the position and dimensions of the Context Overlay.
if (AABox(entityCenterPoint - (entityDimensions / 2.0f), entityDimensions * 2.0f).contains(cameraPosition)) {
if (boundingBox.contains(cameraPosition)) {
// If the camera is inside the box...
// ...position the Context Overlay 1 meter in front of the camera.
contextOverlayPosition = cameraPosition + CONTEXT_OVERLAY_INSIDE_DISTANCE * (qApp->getCamera().getOrientation() * Vectors::FRONT);
@ -104,17 +111,17 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
if (event.getID() == LEFT_HAND_HW_ID) {
offsetAngle *= -1;
}
contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f))) * (entityProperties.getPosition() - cameraPosition)) + cameraPosition;
contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f))) * (entityPosition - cameraPosition)) + cameraPosition;
contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_CLOSE_SIZE, CONTEXT_OVERLAY_CLOSE_SIZE) * glm::distance(contextOverlayPosition, cameraPosition);
} else {
// Else, place the Context Overlay some offset away from the entity's bounding
// box in the direction of the camera.
auto direction = glm::normalize(entityProperties.getPosition() - cameraPosition);
PickRay pickRay(cameraPosition, direction);
_bbOverlay->setIgnoreRayIntersection(false);
auto result = qApp->getOverlays().findRayIntersection(pickRay);
_bbOverlay->setIgnoreRayIntersection(true);
contextOverlayPosition = result.intersection - direction * CONTEXT_OVERLAY_FAR_OFFSET;
glm::vec3 direction = glm::normalize(entityPosition - cameraPosition);
float distance;
BoxFace face;
glm::vec3 normal;
bool intersectionExists = boundingBox.findRayIntersection(cameraPosition, direction, distance, face, normal);
contextOverlayPosition = (cameraPosition + direction * distance) - direction * CONTEXT_OVERLAY_FAR_OFFSET;
contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_FAR_SIZE, CONTEXT_OVERLAY_FAR_SIZE) * glm::distance(contextOverlayPosition, cameraPosition);
}
@ -149,33 +156,6 @@ bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& ent
return (entityProperties.getMarketplaceID().length() != 0);
}
glm::vec3 ContextOverlayInterface::drawOutlineOverlay(const EntityItemID& entityItemID) {
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags);
glm::vec3 bbPosition = entityProperties.getPosition();
if (entityProperties.getRegistrationPoint() != glm::vec3(0.5f)) {
glm::vec3 adjustPos = entityProperties.getRegistrationPoint() - glm::vec3(0.5f);
bbPosition = bbPosition - (entityProperties.getRotation() * (adjustPos * entityProperties.getDimensions()));
}
// Setup and draw the bounding box around the entity
if (_bbOverlayID == UNKNOWN_OVERLAY_ID || !qApp->getOverlays().isAddedOverlay(_bbOverlayID)) {
_bbOverlay = std::make_shared<Cube3DOverlay>();
_bbOverlay->setIsSolid(false);
_bbOverlay->setColor(BB_OVERLAY_COLOR);
_bbOverlay->setDrawInFront(true);
_bbOverlay->setIgnoreRayIntersection(true);
_bbOverlayID = qApp->getOverlays().addOverlay(_bbOverlay);
}
_bbOverlay->setParentID(entityItemID);
_bbOverlay->setDimensions(entityProperties.getDimensions());
_bbOverlay->setRotation(entityProperties.getRotation());
_bbOverlay->setPosition(bbPosition);
_bbOverlay->setVisible(true);
// This returned position should always be the center of the entity
// even if the registration point isn't the default.
return bbPosition;
}
bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) {
if (_contextOverlayID != UNKNOWN_OVERLAY_ID) {
qCDebug(context_overlay) << "Destroying Context Overlay on top of entity with ID: " << entityItemID;
@ -185,10 +165,6 @@ bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityIt
qApp->getOverlays().deleteOverlay(_contextOverlayID);
_contextOverlay = NULL;
_contextOverlayID = UNKNOWN_OVERLAY_ID;
// Destroy the outline overlay
qApp->getOverlays().deleteOverlay(_bbOverlayID);
_bbOverlay = NULL;
_bbOverlayID = UNKNOWN_OVERLAY_ID;
return true;
}
return false;
@ -227,6 +203,18 @@ void ContextOverlayInterface::hoverLeaveContextOverlay(const OverlayID& overlayI
}
}
void ContextOverlayInterface::highlightEntity(const EntityItemID& entityID, const PointerEvent& event) {
//if (contextOverlayFilterPassed(entityID)) {
qCDebug(context_overlay) << "Setting 'shouldHighlight' to 'true' for Entity ID:" << entityID;
qApp->getEntities()->getTree()->findEntityByEntityItemID(entityID)->setShouldHighlight(true);
//}
}
void ContextOverlayInterface::unHighlightEntity(const EntityItemID& entityID, const PointerEvent& event) {
qCDebug(context_overlay) << "Setting 'shouldHighlight' to 'false' for Entity ID:" << entityID;
qApp->getEntities()->getTree()->findEntityByEntityItemID(entityID)->setShouldHighlight(false);
}
static const QString MARKETPLACE_BASE_URL = "http://metaverse.highfidelity.com/marketplace/items/";
void ContextOverlayInterface::openMarketplace() {

View file

@ -23,7 +23,6 @@
#include "EntityScriptingInterface.h"
#include "ui/overlays/Image3DOverlay.h"
#include "ui/overlays/Cube3DOverlay.h"
#include "ui/overlays/Overlays.h"
#include "scripting/HMDScriptingInterface.h"
@ -44,9 +43,7 @@ class ContextOverlayInterface : public QObject, public Dependency {
QSharedPointer<HMDScriptingInterface> _hmdScriptingInterface;
QSharedPointer<TabletScriptingInterface> _tabletScriptingInterface;
OverlayID _contextOverlayID { UNKNOWN_OVERLAY_ID };
OverlayID _bbOverlayID { UNKNOWN_OVERLAY_ID };
std::shared_ptr<Image3DOverlay> _contextOverlay { nullptr };
std::shared_ptr<Cube3DOverlay> _bbOverlay { nullptr };
public:
ContextOverlayInterface();
@ -64,6 +61,8 @@ public slots:
void clickContextOverlay(const OverlayID& overlayID, const PointerEvent& event);
void hoverEnterContextOverlay(const OverlayID& overlayID, const PointerEvent& event);
void hoverLeaveContextOverlay(const OverlayID& overlayID, const PointerEvent& event);
void highlightEntity(const EntityItemID& entityID, const PointerEvent& event);
void unHighlightEntity(const EntityItemID& entityID, const PointerEvent& event);
private:
bool _verboseLogging { true };
@ -76,7 +75,6 @@ private:
bool _isInMarketplaceInspectionMode { false };
bool contextOverlayFilterPassed(const EntityItemID& entityItemID);
glm::vec3 drawOutlineOverlay(const EntityItemID& entityItemID);
};
#endif // hifi_ContextOverlayInterface_h

View file

@ -372,8 +372,8 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
_model->updateRenderItems();
}
bool showingEntityHighlight = (bool)(args->_outlineFlags & (int)RenderArgs::RENDER_OUTLINE_WIREFRAMES);
if (getMarketplaceID().length() != 0 && showingEntityHighlight) {
bool showingEntityHighlight = ((bool)(args->_outlineFlags & (int)RenderArgs::RENDER_OUTLINE_WIREFRAMES) && getMarketplaceID().length() != 0) || getShouldHighlight();
if (showingEntityHighlight) {
static glm::vec4 yellowColor(1.0f, 1.0f, 0.0f, 1.0f);
gpu::Batch& batch = *args->_batch;
bool success;

View file

@ -133,6 +133,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
requestedProperties += PROP_LOCKED;
requestedProperties += PROP_USER_DATA;
requestedProperties += PROP_MARKETPLACE_ID;
requestedProperties += PROP_SHOULD_HIGHLIGHT;
requestedProperties += PROP_NAME;
requestedProperties += PROP_HREF;
requestedProperties += PROP_DESCRIPTION;
@ -277,6 +278,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked());
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, getUserData());
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, getMarketplaceID());
APPEND_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, getShouldHighlight());
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
APPEND_ENTITY_PROPERTY(PROP_HREF, getHref());
@ -828,6 +830,10 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
}
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT) {
READ_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, bool, setShouldHighlight);
}
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref);
@ -2807,6 +2813,20 @@ void EntityItem::setMarketplaceID(const QString& value) {
});
}
bool EntityItem::getShouldHighlight() const {
bool result;
withReadLock([&] {
result = _shouldHighlight;
});
return result;
}
void EntityItem::setShouldHighlight(const bool value) {
withWriteLock([&] {
_shouldHighlight = value;
});
}
uint32_t EntityItem::getDirtyFlags() const {
uint32_t result;
withReadLock([&] {

View file

@ -316,6 +316,9 @@ public:
QString getMarketplaceID() const;
void setMarketplaceID(const QString& value);
bool getShouldHighlight() const;
void setShouldHighlight(const bool value);
// TODO: get rid of users of getRadius()...
float getRadius() const;
@ -532,6 +535,7 @@ protected:
QString _userData;
SimulationOwner _simulationOwner;
QString _marketplaceID;
bool _shouldHighlight { false };
QString _name;
QString _href; //Hyperlink href
QString _description; //Hyperlink description

View file

@ -289,6 +289,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_RADIUS_START, radiusStart);
CHECK_PROPERTY_CHANGE(PROP_RADIUS_FINISH, radiusFinish);
CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID);
CHECK_PROPERTY_CHANGE(PROP_SHOULD_HIGHLIGHT, shouldHighlight);
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
CHECK_PROPERTY_CHANGE(PROP_SOURCE_URL, sourceUrl);
@ -406,6 +407,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCKED, locked);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USER_DATA, userData);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MARKETPLACE_ID, marketplaceID);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SHOULD_HIGHLIGHT, shouldHighlight);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL);
@ -982,6 +984,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
ADD_PROPERTY_TO_MAP(PROP_RADIUS_START, RadiusStart, radiusStart, float);
ADD_PROPERTY_TO_MAP(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float);
ADD_PROPERTY_TO_MAP(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString);
ADD_PROPERTY_TO_MAP(PROP_SHOULD_HIGHLIGHT, ShouldHighlight, shouldHighlight, bool);
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor);
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_AMBIENT_INTENSITY, KeyLightAmbientIntensity, keyLightAmbientIntensity, float);
@ -1334,6 +1337,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
APPEND_ENTITY_PROPERTY(PROP_SHAPE, properties.getShape());
}
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
APPEND_ENTITY_PROPERTY(PROP_SHOULD_HIGHLIGHT, properties.getShouldHighlight());
APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName());
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL());
APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, properties.getActionData());
@ -1632,6 +1636,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
}
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHOULD_HIGHLIGHT, bool, setShouldHighlight);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACTION_DATA, QByteArray, setActionData);
@ -1746,6 +1751,7 @@ void EntityItemProperties::markAllChanged() {
//_alphaFinishChanged = true;
_marketplaceIDChanged = true;
_shouldHighlightChanged = true;
_keyLight.markAllChanged();

View file

@ -170,6 +170,7 @@ public:
DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float, ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH);
DEFINE_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, EmitterShouldTrail, emitterShouldTrail, bool, ParticleEffectEntityItem::DEFAULT_EMITTER_SHOULD_TRAIL);
DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID);
DEFINE_PROPERTY_REF(PROP_SHOULD_HIGHLIGHT, ShouldHighlight, shouldHighlight, bool, ENTITY_ITEM_DEFAULT_SHOULD_HIGHLIGHT);
DEFINE_PROPERTY_GROUP(KeyLight, keyLight, KeyLightPropertyGroup);
DEFINE_PROPERTY_REF(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3, PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE);
DEFINE_PROPERTY_REF(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray, PolyVoxEntityItem::DEFAULT_VOXEL_DATA);

View file

@ -27,6 +27,7 @@ const glm::vec3 ENTITY_ITEM_HALF_VEC3 = glm::vec3(0.5f);
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
const QString ENTITY_ITEM_DEFAULT_MARKETPLACE_ID = QString("");
const bool ENTITY_ITEM_DEFAULT_SHOULD_HIGHLIGHT = false;
const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid();
const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f;

View file

@ -78,6 +78,7 @@ enum EntityPropertyList {
PROP_COMPOUND_SHAPE_URL, // used by Model + zones entities
PROP_MARKETPLACE_ID, // all entities
PROP_SHOULD_HIGHLIGHT, // all entities
PROP_ACCELERATION, // all entities
PROP_SIMULATION_OWNER, // formerly known as PROP_SIMULATOR_ID
PROP_NAME, // all entities

View file

@ -62,7 +62,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityEdit:
case PacketType::EntityData:
case PacketType::EntityPhysics:
return VERSION_ENTITIES_BULLET_DYNAMICS;
return VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT;
case PacketType::EntityQuery:
return static_cast<PacketVersion>(EntityQueryPacketVersion::JSONFilterWithFamilyTree);
case PacketType::AvatarIdentity:

View file

@ -218,6 +218,7 @@ const PacketVersion VERSION_ENTITIES_PHYSICS_PACKET = 67;
const PacketVersion VERSION_ENTITIES_ZONE_FILTERS = 68;
const PacketVersion VERSION_ENTITIES_HINGE_CONSTRAINT = 69;
const PacketVersion VERSION_ENTITIES_BULLET_DYNAMICS = 70;
const PacketVersion VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT = 71;
enum class EntityQueryPacketVersion: PacketVersion {
JSONFilter = 18,

View file

@ -116,12 +116,10 @@
if (onMarketplaceScreen) {
// for toolbar-mode: go back to home screen, this will close the window.
tablet.gotoHomeScreen();
ContextOverlay.isInMarketplaceInspectionMode = false;
} else {
var entity = HMD.tabletID;
Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
showMarketplace();
ContextOverlay.isInMarketplaceInspectionMode = true;
}
}
@ -129,6 +127,11 @@
onMarketplaceScreen = type === "Web" && url === MARKETPLACE_URL_INITIAL
// for toolbar mode: change button to active when window is first openend, false otherwise.
marketplaceButton.editProperties({ isActive: onMarketplaceScreen });
if (onMarketplaceScreen) {
ContextOverlay.isInMarketplaceInspectionMode = true;
} else {
ContextOverlay.isInMarketplaceInspectionMode = false;
}
}
marketplaceButton.clicked.connect(onClick);