NavigationFocused
hmdRollControlEnabled
is enabled.
- * @property hmdRollControlRate {number} If hmdRollControlEnabled is true, this value determines the maximum turn rate of
+ * @property {number} hmdRollControlRate If hmdRollControlEnabled is true, this value determines the maximum turn rate of
* your avatar when rolling your HMD in degrees per second.
* @property {number} userHeight=1.75 - The height of the user in sensor space.
* @property {number} userEyeHeight=1.65 - The estimated height of the user's eyes in sensor space. Read-only.
@@ -1159,7 +1159,7 @@ public slots:
* @function MyAvatar.getEnableMeshVisible
* @returns {boolean} true
if your avatar's mesh is visible, otherwise false
.
*/
- bool getEnableMeshVisible() const { return _skeletonModel->isVisible(); }
+ bool getEnableMeshVisible() const override;
/**jsdoc
* Set whether or not your avatar mesh is visible.
@@ -1171,7 +1171,7 @@ public slots:
* MyAvatar.setEnableMeshVisible(true);
* }, 10000);
*/
- void setEnableMeshVisible(bool isEnabled);
+ virtual void setEnableMeshVisible(bool isEnabled) override;
/**jsdoc
* @function MyAvatar.setEnableInverseKinematics
@@ -1402,7 +1402,7 @@ private:
SharedSoundPointer _collisionSound;
MyCharacterController _characterController;
- int16_t _previousCollisionGroup { BULLET_COLLISION_GROUP_MY_AVATAR };
+ int32_t _previousCollisionGroup { BULLET_COLLISION_GROUP_MY_AVATAR };
AvatarWeakPointer _lookAtTargetAvatar;
glm::vec3 _targetAvatarPosition;
diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h
index a39aa3a4a1..5ef5d27d74 100644
--- a/interface/src/raypick/PickScriptingInterface.h
+++ b/interface/src/raypick/PickScriptingInterface.h
@@ -22,21 +22,22 @@
* @hifi-interface
* @hifi-client-entity
*
- * @property PICK_NOTHING {number} A filter flag. Don't intersect with anything. Read-only.
- * @property PICK_ENTITIES {number} A filter flag. Include entities when intersecting. Read-only.
- * @property PICK_OVERLAYS {number} A filter flag. Include overlays when intersecting. Read-only.
- * @property PICK_AVATARS {number} A filter flag. Include avatars when intersecting. Read-only.
- * @property PICK_HUD {number} A filter flag. Include the HUD sphere when intersecting in HMD mode. Read-only.
- * @property PICK_COARSE {number} A filter flag. Pick against coarse meshes, instead of exact meshes. Read-only.
- * @property PICK_INCLUDE_INVISIBLE {number} A filter flag. Include invisible objects when intersecting. Read-only.
- * @property PICK_INCLUDE_NONCOLLIDABLE {number} A filter flag. Include non-collidable objects when intersecting.
+ * @property {number} PICK_NOTHING A filter flag. Don't intersect with anything. Read-only.
+ * @property {number} PICK_ENTITIES A filter flag. Include entities when intersecting. Read-only.
+ * @property {number} PICK_OVERLAYS A filter flag. Include overlays when intersecting. Read-only.
+ * @property {number} PICK_AVATARS A filter flag. Include avatars when intersecting. Read-only.
+ * @property {number} PICK_HUD A filter flag. Include the HUD sphere when intersecting in HMD mode. Read-only.
+ * @property {number} PICK_COARSE A filter flag. Pick against coarse meshes, instead of exact meshes. Read-only.
+ * @property {number} PICK_INCLUDE_INVISIBLE A filter flag. Include invisible objects when intersecting. Read-only.
+ * @property {number} PICK_INCLUDE_NONCOLLIDABLE A filter flag. Include non-collidable objects when intersecting.
* Read-only.
- * @property PICK_ALL_INTERSECTIONS {number} Read-only.
- * @property INTERSECTED_NONE {number} An intersection type. Intersected nothing with the given filter flags. Read-only.
- * @property INTERSECTED_ENTITY {number} An intersection type. Intersected an entity. Read-only.
- * @property INTERSECTED_OVERLAY {number} An intersection type. Intersected an overlay. Read-only.
- * @property INTERSECTED_AVATAR {number} An intersection type. Intersected an avatar. Read-only.
- * @property INTERSECTED_HUD {number} An intersection type. Intersected the HUD sphere. Read-only.
+ * @property {number} PICK_ALL_INTERSECTIONS Read-only.
+ * @property {number} INTERSECTED_NONE An intersection type. Intersected nothing with the given filter flags.
+ * Read-only.
+ * @property {number} INTERSECTED_ENTITY An intersection type. Intersected an entity. Read-only.
+ * @property {number} INTERSECTED_OVERLAY An intersection type. Intersected an overlay. Read-only.
+ * @property {number} INTERSECTED_AVATAR An intersection type. Intersected an avatar. Read-only.
+ * @property {number} INTERSECTED_HUD An intersection type. Intersected the HUD sphere. Read-only.
* @property {number} perFrameTimeBudget - The max number of usec to spend per frame updating Pick results. Read-only.
*/
@@ -99,7 +100,7 @@ public:
/**jsdoc
* An intersection result for a Ray Pick.
*
- * @typedef {Object} RayPickResult
+ * @typedef {object} RayPickResult
* @property {number} type The intersection type.
* @property {boolean} intersects If there was a valid intersection (type != INTERSECTED_NONE)
* @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections.
@@ -113,7 +114,7 @@ public:
/**jsdoc
* An intersection result for a Stylus Pick.
*
- * @typedef {Object} StylusPickResult
+ * @typedef {object} StylusPickResult
* @property {number} type The intersection type.
* @property {boolean} intersects If there was a valid intersection (type != INTERSECTED_NONE)
* @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections.
diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp
index b7ac899c8d..4e953a5cb8 100644
--- a/interface/src/raypick/PointerScriptingInterface.cpp
+++ b/interface/src/raypick/PointerScriptingInterface.cpp
@@ -68,14 +68,14 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
* A set of properties used to define the visual aspect of a Ray Pointer in the case that the Pointer is not intersecting something. Same as a {@link Pointers.RayPointerRenderState},
* but with an additional distance field.
*
- * @typedef {Object} Pointers.DefaultRayPointerRenderState
+ * @typedef {object} Pointers.DefaultRayPointerRenderState
* @augments Pointers.RayPointerRenderState
* @property {number} distance The distance at which to render the end of this Ray Pointer, if one is defined.
*/
/**jsdoc
* A set of properties used to define the visual aspect of a Ray Pointer in the case that the Pointer is intersecting something.
*
- * @typedef {Object} Pointers.RayPointerRenderState
+ * @typedef {object} Pointers.RayPointerRenderState
* @property {string} name The name of this render state, used by {@link Pointers.setRenderState} and {@link Pointers.editRenderState}
* @property {Overlays.OverlayProperties} [start] All of the properties you would normally pass to {@link Overlays.addOverlay}, plus the type (as a type
field).
* An overlay to represent the beginning of the Ray Pointer, if desired.
@@ -87,7 +87,7 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
/**jsdoc
* A trigger mechanism for Ray Pointers.
*
- * @typedef {Object} Pointers.Trigger
+ * @typedef {object} Pointers.Trigger
* @property {Controller.Standard|Controller.Actions|function} action This can be a built-in Controller action, like Controller.Standard.LTClick, or a function that evaluates to >= 1.0 when you want to trigger button
.
* @property {string} button Which button to trigger. "Primary", "Secondary", "Tertiary", and "Focus" are currently supported. Only "Primary" will trigger clicks on web surfaces. If "Focus" is triggered,
* it will try to set the entity or overlay focus to the object at which the Pointer is aimed. Buttons besides the first three will still trigger events, but event.button will be "None".
diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp
index 700994c517..430441226f 100644
--- a/interface/src/scripting/TestScriptingInterface.cpp
+++ b/interface/src/scripting/TestScriptingInterface.cpp
@@ -14,6 +14,7 @@
#include 0x8000000
hifi://
then that URL is navigated to in Interface, otherwise the URL is opened in the application the OS
+ * associates with the URL's scheme (e.g., a Web browser for http://
).
* @function Window.openUrl
- * @param {string} url - The resource to open
+ * @param {string} url - The URL to open.
*/
void openUrl(const QUrl& url);
/**jsdoc
- * (Android only) Open the requested Activity and optionally back to the scene when the activity is done
+ * Open an Android activity and optionally return back to the scene when the activity is completed. Android only.
* @function Window.openAndroidActivity
- * @param {string} activityName - The name of the activity to open. One of "Home", "Login" or "Privacy Policy"
+ * @param {string} activityName - The name of the activity to open: one of "Home"
, "Login"
, or
+ * "Privacy Policy"
.
+ * @param {boolean} backToScene - If true
, the user is automatically returned back to the scene when the
+ * activity is completed.
*/
void openAndroidActivity(const QString& activityName, const bool backToScene);
diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp
index 960f0de095..ecade70ef8 100644
--- a/interface/src/ui/overlays/Billboard3DOverlay.cpp
+++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp
@@ -46,6 +46,13 @@ bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) {
return transformChanged;
}
+void Billboard3DOverlay::update(float duration) {
+ if (isFacingAvatar()) {
+ _renderVariableDirty = true;
+ }
+ Parent::update(duration);
+}
+
Transform Billboard3DOverlay::evalRenderTransform() {
Transform transform = getTransform();
bool transformChanged = applyTransformTo(transform, true);
diff --git a/interface/src/ui/overlays/Billboard3DOverlay.h b/interface/src/ui/overlays/Billboard3DOverlay.h
index 6b3aa40451..174bc23bc8 100644
--- a/interface/src/ui/overlays/Billboard3DOverlay.h
+++ b/interface/src/ui/overlays/Billboard3DOverlay.h
@@ -18,6 +18,7 @@
class Billboard3DOverlay : public Planar3DOverlay, public PanelAttachable, public Billboardable {
Q_OBJECT
+ using Parent = Planar3DOverlay;
public:
Billboard3DOverlay() {}
@@ -26,6 +27,8 @@ public:
void setProperties(const QVariantMap& properties) override;
QVariant getProperty(const QString& property) override;
+ void update(float duration) override;
+
protected:
virtual bool applyTransformTo(Transform& transform, bool force = false) override;
diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp
index df93245922..6e9946e935 100644
--- a/interface/src/ui/overlays/Image3DOverlay.cpp
+++ b/interface/src/ui/overlays/Image3DOverlay.cpp
@@ -51,11 +51,6 @@ void Image3DOverlay::update(float deltatime) {
_texture = DependencyManager::gettrue
if an overlay with the given ID exists, false
otherwise.
*/
diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp
index 185547a333..901dd1df3e 100644
--- a/interface/src/ui/overlays/OverlaysPayload.cpp
+++ b/interface/src/ui/overlays/OverlaysPayload.cpp
@@ -35,14 +35,18 @@ namespace render {
auto builder = ItemKey::Builder().withTypeShape();
if (overlay->is3D()) {
auto overlay3D = std::static_pointer_castController.Hardware
properties.true
then the
* entity's properties other than locked
cannot be changed, and the entity cannot be deleted.
* @property {boolean} visible=true - Whether or not the entity is rendered. If true
then the entity is rendered.
- * @property {boolean} canCastShadows=true - Whether or not the entity casts shadows. Currently applicable only to
+ * @property {boolean} canCastShadow=true - Whether or not the entity can cast a shadow. Currently applicable only to
* {@link Entities.EntityType|Model} and {@link Entities.EntityType|Shape} entities. Shadows are cast if inside a
* {@link Entities.EntityType|Zone} entity with castShadows
enabled in its
* {@link Entities.EntityProperties-Zone|keyLight} property.
+ * @property {boolean} isVisibleInSecondaryCamera=true - Whether or not the entity is rendered in the secondary camera. If true
then the entity is rendered.
*
* @property {Vec3} position=0,0,0 - The position of the entity.
* @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to world coordinates.
@@ -1400,7 +1401,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
/**jsdoc
* The axis-aligned bounding box of an entity.
- * @typedef Entities.BoundingBox
+ * @typedef {object} Entities.BoundingBox
* @property {Vec3} brn - The bottom right near (minimum axes values) corner of the AA box.
* @property {Vec3} tfl - The top far left (maximum axes values) corner of the AA box.
* @property {Vec3} center - The center of the AA box.
@@ -1522,7 +1523,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(localRenderAlpha, float, setLocalRenderAlpha);
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionless, bool, setCollisionless);
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(ignoreForCollisions, bool, setCollisionless, getCollisionless); // legacy support
- COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionMask, uint8_t, setCollisionMask);
+ COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionMask, uint16_t, setCollisionMask);
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(collidesWith, CollisionMask);
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(collisionsWillMove, bool, setDynamic, getDynamic); // legacy support
COPY_PROPERTY_FROM_QSCRIPTVALUE(dynamic, bool, setDynamic);
@@ -2581,7 +2582,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISIONLESS, bool, setCollisionless);
- READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_MASK, uint8_t, setCollisionMask);
+ READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_MASK, uint16_t, setCollisionMask);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DYNAMIC, bool, setDynamic);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_USER_DATA, QString, setUserData);
diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h
index f69a096a31..e46eb73910 100644
--- a/libraries/entities/src/EntityItemProperties.h
+++ b/libraries/entities/src/EntityItemProperties.h
@@ -148,7 +148,7 @@ public:
DEFINE_PROPERTY_REF(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3, ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
DEFINE_PROPERTY(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float, ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING);
DEFINE_PROPERTY(PROP_COLLISIONLESS, Collisionless, collisionless, bool, ENTITY_ITEM_DEFAULT_COLLISIONLESS);
- DEFINE_PROPERTY(PROP_COLLISION_MASK, CollisionMask, collisionMask, uint8_t, ENTITY_COLLISION_MASK_DEFAULT);
+ DEFINE_PROPERTY(PROP_COLLISION_MASK, CollisionMask, collisionMask, uint16_t, ENTITY_COLLISION_MASK_DEFAULT);
DEFINE_PROPERTY(PROP_DYNAMIC, Dynamic, dynamic, bool, ENTITY_ITEM_DEFAULT_DYNAMIC);
DEFINE_PROPERTY(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool, LightEntityItem::DEFAULT_IS_SPOTLIGHT);
DEFINE_PROPERTY(PROP_INTENSITY, Intensity, intensity, float, LightEntityItem::DEFAULT_INTENSITY);
diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp
index f751a4f8ed..98407a74c6 100644
--- a/libraries/entities/src/EntityScriptingInterface.cpp
+++ b/libraries/entities/src/EntityScriptingInterface.cpp
@@ -1688,15 +1688,21 @@ QVectorparentID
- * entity. Does not include children's children, etc. The array is empty if no children can be found or
+ * entity, overlay, or avatar. Does not include children's children, etc. The array is empty if no children can be found or
* parentID
cannot be found.
* @example true
then shadows are cast. Shadows are cast by avatars, plus
* {@link Entities.EntityType|Model} and {@link Entities.EntityType|Shape} entities that have their
- * {@link Entities.EntityProperties|canCastShadows}
property set to true
.
+ * {@link Entities.EntityProperties|canCastShadow}
property set to true
.
*/
class KeyLightPropertyGroup : public PropertyGroup {
public:
diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h
index 239908f86c..fc94236c96 100644
--- a/libraries/fbx/src/FBX.h
+++ b/libraries/fbx/src/FBX.h
@@ -258,6 +258,11 @@ public:
QHash"hifi:/" address, an IP address (e.g.,
+ * @param {string} address - The address to go to: a "hifi://" address, an IP address (e.g.,
* "127.0.0.1"
or "localhost"
), a domain name, a named path on a domain (starts with
* "/"
), a position or position and orientation, or a user (starts with "@"
).
* @param {boolean} fromSuggestions=false - Set to true
if the address is obtained from the "Goto" dialog.
diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h
index 08908dbaf6..4d98391104 100644
--- a/libraries/networking/src/DomainHandler.h
+++ b/libraries/networking/src/DomainHandler.h
@@ -137,7 +137,7 @@ public:
*
*
*
- * @typedef Window.ConnectionRefusedReason
+ * @typedef {number} Window.ConnectionRefusedReason
*/
enum class ConnectionRefusedReason : uint8_t {
Unknown,
diff --git a/libraries/networking/src/RSAKeypairGenerator.cpp b/libraries/networking/src/RSAKeypairGenerator.cpp
index 8ca8b81ea3..e83615e3df 100644
--- a/libraries/networking/src/RSAKeypairGenerator.cpp
+++ b/libraries/networking/src/RSAKeypairGenerator.cpp
@@ -25,7 +25,10 @@
RSAKeypairGenerator::RSAKeypairGenerator(QObject* parent) :
QObject(parent)
{
-
+}
+
+void RSAKeypairGenerator::run() {
+ generateKeypair();
}
void RSAKeypairGenerator::generateKeypair() {
@@ -92,5 +95,5 @@ void RSAKeypairGenerator::generateKeypair() {
OPENSSL_free(publicKeyDER);
OPENSSL_free(privateKeyDER);
- emit generatedKeypair();
+ emit generatedKeypair(_publicKey, _privateKey);
}
diff --git a/libraries/networking/src/RSAKeypairGenerator.h b/libraries/networking/src/RSAKeypairGenerator.h
index 36f4a9550b..552f12395b 100644
--- a/libraries/networking/src/RSAKeypairGenerator.h
+++ b/libraries/networking/src/RSAKeypairGenerator.h
@@ -13,25 +13,20 @@
#define hifi_RSAKeypairGenerator_h
#include
+#include
#include
-class RSAKeypairGenerator : public QObject {
+class RSAKeypairGenerator : public QObject, public QRunnable {
Q_OBJECT
public:
- RSAKeypairGenerator(QObject* parent = 0);
+ RSAKeypairGenerator(QObject* parent = nullptr);
- void setDomainID(const QUuid& domainID) { _domainID = domainID; }
- const QUuid& getDomainID() const { return _domainID; }
-
- const QByteArray& getPublicKey() const { return _publicKey; }
- const QByteArray& getPrivateKey() const { return _privateKey; }
-
-public slots:
+ virtual void run() override;
void generateKeypair();
signals:
void errorGeneratingKeypair();
- void generatedKeypair();
+ void generatedKeypair(QByteArray publicKey, QByteArray privateKey);
private:
QUuid _domainID;
diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp
index 28266d0a7f..18e60ef5ef 100644
--- a/libraries/networking/src/ResourceCache.cpp
+++ b/libraries/networking/src/ResourceCache.cpp
@@ -218,8 +218,8 @@ ScriptableResource* ResourceCache::prefetch(const QUrl& url, void* extra) {
}
ResourceCache::ResourceCache(QObject* parent) : QObject(parent) {
- auto nodeList = DependencyManager::get();
- if (nodeList) {
+ if (DependencyManager::isSet()) {
+ auto nodeList = DependencyManager::get();
auto& domainHandler = nodeList->getDomainHandler();
connect(&domainHandler, &DomainHandler::disconnectedFromDomain,
this, &ResourceCache::clearATPAssets, Qt::DirectConnection);
diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h
index 18840cd11e..a4bd352563 100644
--- a/libraries/networking/src/ResourceCache.h
+++ b/libraries/networking/src/ResourceCache.h
@@ -87,7 +87,7 @@ private:
class ScriptableResource : public QObject {
/**jsdoc
- * @constructor Resource
+ * @class ResourceObject
*
* @hifi-interface
* @hifi-client-entity
@@ -97,11 +97,6 @@ class ScriptableResource : public QObject {
* @property {string} url - URL of this resource.
* @property {Resource.State} state - Current loading state.
*/
- /**jsdoc
- * @namespace Resource
- * @variation 0
- * @property {Resource.State} State
- */
Q_OBJECT
Q_PROPERTY(QUrl url READ getURL)
Q_PROPERTY(int state READ getState NOTIFY stateChanged)
@@ -109,8 +104,7 @@ class ScriptableResource : public QObject {
public:
/**jsdoc
- * @name Resource.State
- * @static
+ * @typedef {object} Resource.State
* @property {number} QUEUED - The resource is queued up, waiting to be loaded.
* @property {number} LOADING - The resource is downloading.
* @property {number} LOADED - The resource has finished downloaded by is not complete.
@@ -131,7 +125,7 @@ public:
/**jsdoc
* Release this resource.
- * @function Resource#release
+ * @function ResourceObject#release
*/
Q_INVOKABLE void release();
@@ -146,7 +140,7 @@ signals:
/**jsdoc
* Triggered when download progress for this resource has changed.
- * @function Resource#progressChanged
+ * @function ResourceObject#progressChanged
* @param {number} bytesReceived - Byytes downloaded so far.
* @param {number} bytesTotal - Total number of bytes in the resource.
* @returns {Signal}
@@ -155,7 +149,7 @@ signals:
/**jsdoc
* Triggered when resource loading state has changed.
- * @function Resource#stateChanged
+ * @function ResourceObject#stateChanged
* @param {Resource.State} state - New state.
* @returns {Signal}
*/
@@ -262,7 +256,7 @@ protected slots:
* @function ResourceCache.prefetch
* @param {string} url - URL of the resource to prefetch.
* @param {object} [extra=null]
- * @returns {Resource}
+ * @returns {ResourceObject}
*/
// Prefetches a resource to be held by the QScriptEngine.
// Left as a protected member so subclasses can overload prefetch
@@ -275,8 +269,9 @@ protected slots:
* @param {string} url - URL of the resource to load.
* @param {string} [fallback=""] - Fallback URL if load of the desired URL fails.
* @param {} [extra=null]
- * @returns {Resource}
+ * @returns {object}
*/
+ // FIXME: The return type is not recognized by JavaScript.
/// Loads a resource from the specified URL and returns it.
/// If the caller is on a different thread than the ResourceCache,
/// returns an empty smart pointer and loads its asynchronously.
diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp
index c07c5905f6..b69733c18d 100644
--- a/libraries/networking/src/udt/PacketHeaders.cpp
+++ b/libraries/networking/src/udt/PacketHeaders.cpp
@@ -33,7 +33,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityEdit:
case PacketType::EntityData:
case PacketType::EntityPhysics:
- return static_cast(EntityVersion::CloneableData);
+ return static_cast(EntityVersion::CollisionMask16Bytes);
case PacketType::EntityQuery:
return static_cast(EntityQueryPacketVersion::ConicalFrustums);
case PacketType::AvatarIdentity:
diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h
index 29d4efed42..5203a9d178 100644
--- a/libraries/networking/src/udt/PacketHeaders.h
+++ b/libraries/networking/src/udt/PacketHeaders.h
@@ -235,7 +235,8 @@ enum class EntityVersion : PacketVersion {
MaterialEntities,
ShadowControl,
MaterialData,
- CloneableData
+ CloneableData,
+ CollisionMask16Bytes
};
enum class EntityScriptCallMethodVersion : PacketVersion {
diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp
index 9b6e9fe7a0..64eda975cf 100755
--- a/libraries/physics/src/CharacterController.cpp
+++ b/libraries/physics/src/CharacterController.cpp
@@ -109,7 +109,7 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) {
}
_dynamicsWorld = nullptr;
}
- int16_t collisionGroup = computeCollisionGroup();
+ int32_t collisionGroup = computeCollisionGroup();
if (_rigidBody) {
updateMassProperties();
}
@@ -325,7 +325,7 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar
_ghost.setWorldTransform(_rigidBody->getWorldTransform());
}
-void CharacterController::jump() {
+void CharacterController::jump(const btVector3& dir) {
_pendingFlags |= PENDING_FLAG_JUMP;
}
@@ -352,7 +352,7 @@ static const char* stateToStr(CharacterController::State state) {
#endif // #ifdef DEBUG_STATE_CHANGE
void CharacterController::updateCurrentGravity() {
- int16_t collisionGroup = computeCollisionGroup();
+ int32_t collisionGroup = computeCollisionGroup();
if (_state == State::Hover || collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS) {
_currentGravity = 0.0f;
} else {
@@ -433,7 +433,7 @@ void CharacterController::setCollisionless(bool collisionless) {
}
}
-int16_t CharacterController::computeCollisionGroup() const {
+int32_t CharacterController::computeCollisionGroup() const {
if (_collisionless) {
return _collisionlessAllowed ? BULLET_COLLISION_GROUP_COLLISIONLESS : BULLET_COLLISION_GROUP_MY_AVATAR;
} else {
@@ -446,7 +446,7 @@ void CharacterController::handleChangedCollisionGroup() {
// ATM the easiest way to update collision groups is to remove/re-add the RigidBody
if (_dynamicsWorld) {
_dynamicsWorld->removeRigidBody(_rigidBody);
- int16_t collisionGroup = computeCollisionGroup();
+ int32_t collisionGroup = computeCollisionGroup();
_dynamicsWorld->addRigidBody(_rigidBody, collisionGroup, BULLET_COLLISION_MASK_MY_AVATAR);
}
_pendingFlags &= ~PENDING_FLAG_UPDATE_COLLISION_GROUP;
@@ -538,7 +538,7 @@ void CharacterController::applyMotor(int index, btScalar dt, btVector3& worldVel
btScalar angle = motor.rotation.getAngle();
btVector3 velocity = worldVelocity.rotate(axis, -angle);
- int16_t collisionGroup = computeCollisionGroup();
+ int32_t collisionGroup = computeCollisionGroup();
if (collisionGroup == BULLET_COLLISION_GROUP_COLLISIONLESS ||
_state == State::Hover || motor.hTimescale == motor.vTimescale) {
// modify velocity
@@ -679,7 +679,7 @@ void CharacterController::updateState() {
btVector3 rayStart = _position;
btScalar rayLength = _radius;
- int16_t collisionGroup = computeCollisionGroup();
+ int32_t collisionGroup = computeCollisionGroup();
if (collisionGroup == BULLET_COLLISION_GROUP_MY_AVATAR) {
rayLength += _scaleFactor * DEFAULT_AVATAR_FALL_HEIGHT;
} else {
diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h
index 96e479dcad..50db2bea12 100644
--- a/libraries/physics/src/CharacterController.h
+++ b/libraries/physics/src/CharacterController.h
@@ -70,7 +70,7 @@ public:
virtual void preStep(btCollisionWorld *collisionWorld) override;
virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) override;
virtual bool canJump() const override { assert(false); return false; } // never call this
- virtual void jump() override;
+ virtual void jump(const btVector3& dir = btVector3(0.0f, 0.0f, 0.0f)) override;
virtual bool onGround() const override;
void clearMotors();
@@ -120,7 +120,7 @@ public:
bool isStuck() const { return _isStuck; }
void setCollisionless(bool collisionless);
- int16_t computeCollisionGroup() const;
+ int32_t computeCollisionGroup() const;
void handleChangedCollisionGroup();
bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
diff --git a/libraries/physics/src/CharacterGhostObject.cpp b/libraries/physics/src/CharacterGhostObject.cpp
index 331485dd01..a771a52384 100755
--- a/libraries/physics/src/CharacterGhostObject.cpp
+++ b/libraries/physics/src/CharacterGhostObject.cpp
@@ -29,13 +29,13 @@ CharacterGhostObject::~CharacterGhostObject() {
}
}
-void CharacterGhostObject::setCollisionGroupAndMask(int16_t group, int16_t mask) {
+void CharacterGhostObject::setCollisionGroupAndMask(int32_t group, int32_t mask) {
_collisionFilterGroup = group;
_collisionFilterMask = mask;
// TODO: if this probe is in the world reset ghostObject overlap cache
}
-void CharacterGhostObject::getCollisionGroupAndMask(int16_t& group, int16_t& mask) const {
+void CharacterGhostObject::getCollisionGroupAndMask(int32_t& group, int32_t& mask) const {
group = _collisionFilterGroup;
mask = _collisionFilterMask;
}
diff --git a/libraries/physics/src/CharacterGhostObject.h b/libraries/physics/src/CharacterGhostObject.h
index 1e4625c6f6..44ab5c938a 100755
--- a/libraries/physics/src/CharacterGhostObject.h
+++ b/libraries/physics/src/CharacterGhostObject.h
@@ -28,8 +28,8 @@ public:
CharacterGhostObject() { }
~CharacterGhostObject();
- void setCollisionGroupAndMask(int16_t group, int16_t mask);
- void getCollisionGroupAndMask(int16_t& group, int16_t& mask) const;
+ void setCollisionGroupAndMask(int32_t group, int32_t mask);
+ void getCollisionGroupAndMask(int32_t& group, int32_t& mask) const;
void setRadiusAndHalfHeight(btScalar radius, btScalar halfHeight);
void setUpDirection(const btVector3& up);
@@ -54,8 +54,8 @@ protected:
btScalar _radius { 0.0f };
btConvexHullShape* _characterShape { nullptr }; // input, shape of character
CharacterGhostShape* _ghostShape { nullptr }; // internal, shape whose Aabb is used for overlap cache
- int16_t _collisionFilterGroup { 0 };
- int16_t _collisionFilterMask { 0 };
+ int32_t _collisionFilterGroup { 0 };
+ int32_t _collisionFilterMask { 0 };
bool _inWorld { false }; // internal, was added to world
};
diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp
index 7a0ead3e0d..deb779b1f8 100644
--- a/libraries/physics/src/EntityMotionState.cpp
+++ b/libraries/physics/src/EntityMotionState.cpp
@@ -252,11 +252,9 @@ void EntityMotionState::getWorldTransform(btTransform& worldTrans) const {
uint32_t thisStep = ObjectMotionState::getWorldSimulationStep();
float dt = (thisStep - _lastKinematicStep) * PHYSICS_ENGINE_FIXED_SUBSTEP;
+ _lastKinematicStep = thisStep;
_entity->stepKinematicMotion(dt);
- // bypass const-ness so we can remember the step
- const_cast(this)->_lastKinematicStep = thisStep;
-
// and set the acceleration-matches-gravity count high so that if we send an update
// it will use the correct acceleration for remote simulations
_accelerationNearlyGravityCount = (uint8_t)(-1);
@@ -779,7 +777,7 @@ QString EntityMotionState::getName() const {
}
// virtual
-void EntityMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const {
+void EntityMotionState::computeCollisionGroupAndMask(int32_t& group, int32_t& mask) const {
_entity->computeCollisionGroupAndFinalMask(group, mask);
}
diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h
index 376cc5afe2..603130b5ff 100644
--- a/libraries/physics/src/EntityMotionState.h
+++ b/libraries/physics/src/EntityMotionState.h
@@ -84,7 +84,7 @@ public:
virtual QString getName() const override;
- virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override;
+ virtual void computeCollisionGroupAndMask(int32_t& group, int32_t& mask) const override;
bool shouldSendBid();
bool isLocallyOwned() const override;
diff --git a/libraries/physics/src/ObjectDynamic.cpp b/libraries/physics/src/ObjectDynamic.cpp
index 3341025a8f..28323a8b92 100644
--- a/libraries/physics/src/ObjectDynamic.cpp
+++ b/libraries/physics/src/ObjectDynamic.cpp
@@ -159,6 +159,13 @@ void ObjectDynamic::removeFromSimulation(EntitySimulationPointer simulation) con
simulation->removeDynamic(myID);
}
+void ObjectDynamic::setOwnerEntity(const EntityItemPointer ownerEntity) {
+ if (!ownerEntity) {
+ activateBody();
+ }
+ _ownerEntity = ownerEntity;
+}
+
EntityItemPointer ObjectDynamic::getEntityByID(EntityItemID entityID) const {
EntityItemPointer ownerEntity;
withReadLock([&]{
diff --git a/libraries/physics/src/ObjectDynamic.h b/libraries/physics/src/ObjectDynamic.h
index 7fdf2e323a..bfee79aca9 100644
--- a/libraries/physics/src/ObjectDynamic.h
+++ b/libraries/physics/src/ObjectDynamic.h
@@ -33,7 +33,7 @@ public:
virtual void removeFromSimulation(EntitySimulationPointer simulation) const override;
virtual EntityItemWeakPointer getOwnerEntity() const override { return _ownerEntity; }
- virtual void setOwnerEntity(const EntityItemPointer ownerEntity) override { _ownerEntity = ownerEntity; }
+ virtual void setOwnerEntity(const EntityItemPointer ownerEntity) override;
virtual void invalidate() {};
diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h
index e1cf5a4285..bb3c00bd5d 100644
--- a/libraries/physics/src/ObjectMotionState.h
+++ b/libraries/physics/src/ObjectMotionState.h
@@ -154,7 +154,7 @@ public:
virtual QString getName() const { return ""; }
- virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const = 0;
+ virtual void computeCollisionGroupAndMask(int32_t& group, int32_t& mask) const = 0;
bool isActive() const { return _body ? _body->isActive() : false; }
@@ -184,7 +184,7 @@ protected:
btRigidBody* _body { nullptr };
float _density { 1.0f };
- uint32_t _lastKinematicStep;
+ mutable uint32_t _lastKinematicStep;
bool _hasInternalKinematicChanges { false };
};
diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp
index 83ffa21a55..21b5b38b13 100644
--- a/libraries/physics/src/PhysicsEngine.cpp
+++ b/libraries/physics/src/PhysicsEngine.cpp
@@ -71,8 +71,8 @@ void PhysicsEngine::init() {
}
}
-uint32_t PhysicsEngine::getNumSubsteps() {
- return _numSubsteps;
+uint32_t PhysicsEngine::getNumSubsteps() const {
+ return _dynamicsWorld->getNumSubsteps();
}
// private
@@ -148,7 +148,7 @@ void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) {
body->setFlags(BT_DISABLE_WORLD_GRAVITY);
motionState->updateBodyMaterialProperties();
- int16_t group, mask;
+ int32_t group, mask;
motionState->computeCollisionGroupAndMask(group, mask);
_dynamicsWorld->addRigidBody(body, group, mask);
@@ -329,13 +329,9 @@ void PhysicsEngine::stepSimulation() {
PHYSICS_ENGINE_FIXED_SUBSTEP, onSubStep);
if (numSubsteps > 0) {
BT_PROFILE("postSimulation");
- _numSubsteps += (uint32_t)numSubsteps;
- ObjectMotionState::setWorldSimulationStep(_numSubsteps);
-
if (_myAvatarController) {
_myAvatarController->postSimulation();
}
-
_hasOutgoingChanges = true;
}
diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h
index 0dfe3a7a7c..2ac195956a 100644
--- a/libraries/physics/src/PhysicsEngine.h
+++ b/libraries/physics/src/PhysicsEngine.h
@@ -52,7 +52,7 @@ public:
~PhysicsEngine();
void init();
- uint32_t getNumSubsteps();
+ uint32_t getNumSubsteps() const;
void removeObjects(const VectorOfMotionStates& objects);
void removeSetOfObjects(const SetOfMotionStates& objects); // only called during teardown
@@ -135,7 +135,6 @@ private:
CharacterController* _myAvatarController;
uint32_t _numContactFrames = 0;
- uint32_t _numSubsteps;
bool _dumpNextStats { false };
bool _saveNextStats { false };
diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp
index 3f24851dce..07d5ceb9ac 100644
--- a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp
+++ b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp
@@ -59,14 +59,11 @@ int ThreadSafeDynamicsWorld::stepSimulationWithSubstepCallback(btScalar timeStep
}
}
- /*//process some debugging flags
- if (getDebugDrawer()) {
- btIDebugDraw* debugDrawer = getDebugDrawer();
- gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
- }*/
if (subSteps) {
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
int clampedSimulationSteps = (subSteps > maxSubSteps)? maxSubSteps : subSteps;
+ _numSubsteps += clampedSimulationSteps;
+ ObjectMotionState::setWorldSimulationStep(_numSubsteps);
saveKinematicState(fixedTimeStep*clampedSimulationSteps);
@@ -98,28 +95,24 @@ int ThreadSafeDynamicsWorld::stepSimulationWithSubstepCallback(btScalar timeStep
// call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState()
void ThreadSafeDynamicsWorld::synchronizeMotionState(btRigidBody* body) {
btAssert(body);
- if (body->getMotionState() && !body->isStaticObject()) {
- //we need to call the update at least once, even for sleeping objects
- //otherwise the 'graphics' transform never updates properly
- ///@todo: add 'dirty' flag
- //if (body->getActivationState() != ISLAND_SLEEPING)
- {
- if (body->isKinematicObject()) {
- ObjectMotionState* objectMotionState = static_cast(body->getMotionState());
- if (objectMotionState->hasInternalKinematicChanges()) {
- objectMotionState->clearInternalKinematicChanges();
- body->getMotionState()->setWorldTransform(body->getWorldTransform());
- }
- return;
- }
- btTransform interpolatedTransform;
- btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
- body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),
- (m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime*body->getHitFraction(),
- interpolatedTransform);
- body->getMotionState()->setWorldTransform(interpolatedTransform);
+ btAssert(body->getMotionState());
+
+ if (body->isKinematicObject()) {
+ ObjectMotionState* objectMotionState = static_cast(body->getMotionState());
+ if (objectMotionState->hasInternalKinematicChanges()) {
+ // this is a special case where the kinematic motion has been updated by an Action
+ // so we supply the body's current transform to the MotionState
+ objectMotionState->clearInternalKinematicChanges();
+ body->getMotionState()->setWorldTransform(body->getWorldTransform());
}
+ return;
}
+ btTransform interpolatedTransform;
+ btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
+ body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),
+ (m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime*body->getHitFraction(),
+ interpolatedTransform);
+ body->getMotionState()->setWorldTransform(interpolatedTransform);
}
void ThreadSafeDynamicsWorld::synchronizeMotionStates() {
@@ -164,24 +157,12 @@ void ThreadSafeDynamicsWorld::synchronizeMotionStates() {
}
void ThreadSafeDynamicsWorld::saveKinematicState(btScalar timeStep) {
-///would like to iterate over m_nonStaticRigidBodies, but unfortunately old API allows
-///to switch status _after_ adding kinematic objects to the world
-///fix it for Bullet 3.x release
DETAILED_PROFILE_RANGE(simulation_physics, "saveKinematicState");
BT_PROFILE("saveKinematicState");
- for (int i=0;igetActivationState() != ISLAND_SLEEPING)
- {
- if (body->isKinematicObject())
- {
- //to calculate velocities next frame
- body->saveKinematicState(timeStep);
- }
+ for (int i=0;iisKinematicObject() && body->getActivationState() != ISLAND_SLEEPING) {
+ body->saveKinematicState(timeStep);
}
}
}
-
-
diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.h b/libraries/physics/src/ThreadSafeDynamicsWorld.h
index 54c3ddb756..d8cee4d2de 100644
--- a/libraries/physics/src/ThreadSafeDynamicsWorld.h
+++ b/libraries/physics/src/ThreadSafeDynamicsWorld.h
@@ -37,6 +37,7 @@ public:
btConstraintSolver* constraintSolver,
btCollisionConfiguration* collisionConfiguration);
+ int getNumSubsteps() const { return _numSubsteps; }
int stepSimulationWithSubstepCallback(btScalar timeStep, int maxSubSteps = 1,
btScalar fixedTimeStep = btScalar(1.)/btScalar(60.),
SubStepCallback onSubStep = []() { });
@@ -61,6 +62,7 @@ private:
VectorOfMotionStates _deactivatedStates;
SetOfMotionStates _activeStates;
SetOfMotionStates _lastActiveStates;
+ int _numSubsteps { 0 };
};
#endif // hifi_ThreadSafeDynamicsWorld_h
diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h
index 3643e608ed..b3a93ab1de 100644
--- a/libraries/render-utils/src/AmbientOcclusionEffect.h
+++ b/libraries/render-utils/src/AmbientOcclusionEffect.h
@@ -181,7 +181,7 @@ class DebugAmbientOcclusionConfig : public render::Job::Config {
Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
public:
- DebugAmbientOcclusionConfig() : render::Job::Config(true) {}
+ DebugAmbientOcclusionConfig() : render::Job::Config(false) {}
bool showCursorPixel{ false };
glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f };
diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp
index 1596f7ba83..79e0637af4 100644
--- a/libraries/render-utils/src/CauterizedModel.cpp
+++ b/libraries/render-utils/src/CauterizedModel.cpp
@@ -215,10 +215,7 @@ void CauterizedModel::updateRenderItems() {
modelTransform.setRotation(self->getRotation());
bool isWireframe = self->isWireframe();
- bool isVisible = self->isVisible();
- bool canCastShadow = self->canCastShadow();
- bool isLayeredInFront = self->isLayeredInFront();
- bool isLayeredInHUD = self->isLayeredInHUD();
+ auto renderItemKeyGlobalFlags = self->getRenderItemKeyGlobalFlags();
bool enableCauterization = self->getEnableCauterization();
render::Transaction transaction;
@@ -234,7 +231,7 @@ void CauterizedModel::updateRenderItems() {
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
transaction.updateItem(itemID, [modelTransform, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey,
- isWireframe, isVisible, isLayeredInFront, isLayeredInHUD, canCastShadow, enableCauterization](CauterizedMeshPartPayload& data) {
+ isWireframe, renderItemKeyGlobalFlags, enableCauterization](CauterizedMeshPartPayload& data) {
if (useDualQuaternionSkinning) {
data.updateClusterBuffer(meshState.clusterDualQuaternions,
cauterizedMeshState.clusterDualQuaternions);
@@ -276,8 +273,7 @@ void CauterizedModel::updateRenderItems() {
data.updateTransformForCauterizedMesh(renderTransform);
data.setEnableCauterization(enableCauterization);
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, render::ItemKey::TAG_BITS_ALL);
- data.setLayer(isLayeredInFront, isLayeredInHUD);
+ data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, isWireframe, useDualQuaternionSkinning);
});
}
diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp
index 0d8561ad21..f8f49921a3 100644
--- a/libraries/render-utils/src/GeometryCache.cpp
+++ b/libraries/render-utils/src/GeometryCache.cpp
@@ -122,6 +122,9 @@ static const gpu::Element TEXCOORD4_ELEMENT { gpu::VEC4, gpu::FLOAT, gpu::XYZW }
static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT;
static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT;
static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT;
+static gpu::Stream::FormatPointer WIRE_STREAM_FORMAT;
+static gpu::Stream::FormatPointer INSTANCED_WIRE_STREAM_FORMAT;
+static gpu::Stream::FormatPointer INSTANCED_WIRE_FADE_STREAM_FORMAT;
static const uint SHAPE_VERTEX_STRIDE = sizeof(GeometryCache::ShapeVertex); // position, normal, texcoords, tangent
static const uint SHAPE_NORMALS_OFFSET = offsetof(GeometryCache::ShapeVertex, normal);
@@ -690,6 +693,38 @@ gpu::Stream::FormatPointer& getInstancedSolidFadeStreamFormat() {
return INSTANCED_SOLID_FADE_STREAM_FORMAT;
}
+gpu::Stream::FormatPointer& getWireStreamFormat() {
+ if (!WIRE_STREAM_FORMAT) {
+ WIRE_STREAM_FORMAT = std::make_shared(); // 1 for everyone
+ WIRE_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
+ WIRE_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
+ }
+ return WIRE_STREAM_FORMAT;
+}
+
+gpu::Stream::FormatPointer& getInstancedWireStreamFormat() {
+ if (!INSTANCED_WIRE_STREAM_FORMAT) {
+ INSTANCED_WIRE_STREAM_FORMAT = std::make_shared(); // 1 for everyone
+ INSTANCED_WIRE_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
+ INSTANCED_WIRE_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
+ INSTANCED_WIRE_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
+ }
+ return INSTANCED_WIRE_STREAM_FORMAT;
+}
+
+gpu::Stream::FormatPointer& getInstancedWireFadeStreamFormat() {
+ if (!INSTANCED_WIRE_FADE_STREAM_FORMAT) {
+ INSTANCED_WIRE_FADE_STREAM_FORMAT = std::make_shared(); // 1 for everyone
+ INSTANCED_WIRE_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT);
+ INSTANCED_WIRE_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT);
+ INSTANCED_WIRE_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
+ INSTANCED_WIRE_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD2, gpu::Stream::TEXCOORD2, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
+ INSTANCED_WIRE_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD3, gpu::Stream::TEXCOORD3, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
+ INSTANCED_WIRE_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD4, gpu::Stream::TEXCOORD4, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE);
+ }
+ return INSTANCED_WIRE_FADE_STREAM_FORMAT;
+}
+
QHash GeometryCache::_simplePrograms;
gpu::ShaderPointer GeometryCache::_simpleShader;
@@ -827,7 +862,7 @@ void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) {
}
void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) {
- batch.setInputFormat(getSolidStreamFormat());
+ batch.setInputFormat(getWireStreamFormat());
_shapes[shape].drawWire(batch);
}
@@ -839,7 +874,7 @@ void GeometryCache::renderShape(gpu::Batch& batch, Shape shape, const glm::vec4&
}
void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape, const glm::vec4& color) {
- batch.setInputFormat(getSolidStreamFormat());
+ batch.setInputFormat(getWireStreamFormat());
// Color must be set after input format
batch._glColor4f(color.r, color.g, color.b, color.a);
_shapes[shape].drawWire(batch);
@@ -857,7 +892,7 @@ void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t
}
void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer) {
- batch.setInputFormat(getInstancedSolidStreamFormat());
+ batch.setInputFormat(getInstancedWireStreamFormat());
setupBatchInstance(batch, colorBuffer);
_shapes[shape].drawWireInstances(batch, count);
}
@@ -883,7 +918,7 @@ void GeometryCache::renderFadeShapeInstances(gpu::Batch& batch, Shape shape, siz
void GeometryCache::renderWireFadeShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer,
gpu::BufferPointer& fadeBuffer1, gpu::BufferPointer& fadeBuffer2, gpu::BufferPointer& fadeBuffer3) {
- batch.setInputFormat(getInstancedSolidFadeStreamFormat());
+ batch.setInputFormat(getInstancedWireFadeStreamFormat());
setupBatchFadeInstance(batch, colorBuffer, fadeBuffer1, fadeBuffer2, fadeBuffer3);
_shapes[shape].drawWireInstances(batch, count);
}
diff --git a/libraries/render-utils/src/LightClusters.h b/libraries/render-utils/src/LightClusters.h
index f495dabebb..fa054c304a 100644
--- a/libraries/render-utils/src/LightClusters.h
+++ b/libraries/render-utils/src/LightClusters.h
@@ -195,7 +195,7 @@ class DebugLightClustersConfig : public render::Job::Config {
Q_PROPERTY(bool doDrawClusterFromDepth MEMBER doDrawClusterFromDepth NOTIFY dirty)
Q_PROPERTY(bool doDrawContent MEMBER doDrawContent NOTIFY dirty)
public:
- DebugLightClustersConfig() : render::Job::Config(true){}
+ DebugLightClustersConfig() : render::Job::Config(false){}
bool doDrawGrid{ false };
diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp
index 72a4b7e0a4..7cf8bc8297 100644
--- a/libraries/render-utils/src/MeshPartPayload.cpp
+++ b/libraries/render-utils/src/MeshPartPayload.cpp
@@ -79,28 +79,10 @@ void MeshPartPayload::removeMaterial(graphics::MaterialPointer material) {
_drawMaterials.remove(material);
}
-void MeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled) {
- ItemKey::Builder builder;
+void MeshPartPayload::updateKey(const render::ItemKey& key) {
+ ItemKey::Builder builder(key);
builder.withTypeShape();
- if (!isVisible) {
- builder.withInvisible();
- }
-
- builder.withTagBits(tagBits);
-
- if (isLayered) {
- builder.withLayered();
- }
-
- if (canCastShadow) {
- builder.withShadowCaster();
- }
-
- if (isGroupCulled) {
- builder.withSubMetaCulled();
- }
-
if (topMaterialExists()) {
auto matKey = _drawMaterials.top().material->getKey();
if (matKey.isTranslucent()) {
@@ -200,12 +182,6 @@ template <> const Item::Bound payloadGetBound(const ModelMeshPartPayload::Pointe
}
return Item::Bound();
}
-template <> int payloadGetLayer(const ModelMeshPartPayload::Pointer& payload) {
- if (payload) {
- return payload->getLayer();
- }
- return 0;
-}
template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload) {
if (payload) {
@@ -332,28 +308,10 @@ void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& render
}
// Note that this method is called for models but not for shapes
-void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled) {
- ItemKey::Builder builder;
+void ModelMeshPartPayload::updateKey(const render::ItemKey& key) {
+ ItemKey::Builder builder(key);
builder.withTypeShape();
- if (!isVisible) {
- builder.withInvisible();
- }
-
- builder.withTagBits(tagBits);
-
- if (isLayered) {
- builder.withLayered();
- }
-
- if (canCastShadow) {
- builder.withShadowCaster();
- }
-
- if (isGroupCulled) {
- builder.withSubMetaCulled();
- }
-
if (_isBlendShaped || _isSkinned) {
builder.withDeformed();
}
@@ -368,20 +326,6 @@ void ModelMeshPartPayload::updateKey(bool isVisible, bool isLayered, bool canCas
_itemKey = builder.build();
}
-void ModelMeshPartPayload::setLayer(bool isLayeredInFront, bool isLayeredInHUD) {
- if (isLayeredInFront) {
- _layer = Item::LAYER_3D_FRONT;
- } else if (isLayeredInHUD) {
- _layer = Item::LAYER_3D_HUD;
- } else {
- _layer = Item::LAYER_3D;
- }
-}
-
-int ModelMeshPartPayload::getLayer() const {
- return _layer;
-}
-
void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe, bool useDualQuaternionSkinning) {
if (invalidateShapeKey) {
_shapeKey = ShapeKey::Builder::invalid();
diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h
index 08ad7a8311..5c7177e890 100644
--- a/libraries/render-utils/src/MeshPartPayload.h
+++ b/libraries/render-utils/src/MeshPartPayload.h
@@ -32,7 +32,7 @@ public:
typedef render::Payload Payload;
typedef Payload::DataPointer Pointer;
- virtual void updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled = false);
+ virtual void updateKey(const render::ItemKey& key);
virtual void updateMeshPart(const std::shared_ptr& drawMesh, int partIndex);
@@ -95,7 +95,7 @@ public:
void notifyLocationChanged() override;
- void updateKey(bool isVisible, bool isLayered, bool canCastShadow, uint8_t tagBits, bool isGroupCulled = false) override;
+ void updateKey(const render::ItemKey& key) override;
// matrix palette skinning
void updateClusterBuffer(const std::vector& clusterMatrices);
@@ -105,11 +105,9 @@ public:
void updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform);
// Render Item interface
- int getLayer() const;
render::ShapeKey getShapeKey() const override; // shape interface
void render(RenderArgs* args) override;
- void setLayer(bool isLayeredInFront, bool isLayeredInHUD);
void setShapeKey(bool invalidateShapeKey, bool isWireframe, bool useDualQuaternionSkinning);
// ModelMeshPartPayload functions to perform render
@@ -139,13 +137,11 @@ private:
gpu::BufferPointer _blendedVertexBuffer;
render::ShapeKey _shapeKey { render::ShapeKey::Builder::invalid() };
- int _layer { render::Item::LAYER_3D };
};
namespace render {
template <> const ItemKey payloadGetKey(const ModelMeshPartPayload::Pointer& payload);
template <> const Item::Bound payloadGetBound(const ModelMeshPartPayload::Pointer& payload);
- template <> int payloadGetLayer(const ModelMeshPartPayload::Pointer& payload);
template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload);
template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args);
}
diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp
index 65b12ac0d4..7cfb1f6bc8 100644
--- a/libraries/render-utils/src/Model.cpp
+++ b/libraries/render-utils/src/Model.cpp
@@ -103,11 +103,10 @@ Model::Model(QObject* parent, SpatiallyNestable* spatiallyNestableOverride) :
_snapModelToRegistrationPoint(false),
_snappedToRegistrationPoint(false),
_url(HTTP_INVALID_COM),
- _isVisible(true),
- _canCastShadow(false),
_blendNumber(0),
_appliedBlendNumber(0),
- _isWireframe(false)
+ _isWireframe(false),
+ _renderItemKeyGlobalFlags(render::ItemKey::Builder().withVisible().withTagBits(render::hifi::TAG_ALL_VIEWS).build())
{
// we may have been created in the network thread, but we live in the main thread
if (_viewState) {
@@ -268,12 +267,7 @@ void Model::updateRenderItems() {
modelTransform.setScale(glm::vec3(1.0f));
bool isWireframe = self->isWireframe();
- bool isVisible = self->isVisible();
- bool canCastShadow = self->canCastShadow();
- uint8_t viewTagBits = self->getViewTagBits();
- bool isLayeredInFront = self->isLayeredInFront();
- bool isLayeredInHUD = self->isLayeredInHUD();
- bool isGroupCulled = self->isGroupCulled();
+ auto renderItemKeyGlobalFlags = self->getRenderItemKeyGlobalFlags();
render::Transaction transaction;
for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) {
@@ -287,9 +281,7 @@ void Model::updateRenderItems() {
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
transaction.updateItem(itemID, [modelTransform, meshState, useDualQuaternionSkinning,
- invalidatePayloadShapeKey, isWireframe, isVisible,
- canCastShadow, viewTagBits, isLayeredInFront,
- isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
+ invalidatePayloadShapeKey, isWireframe, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
if (useDualQuaternionSkinning) {
data.updateClusterBuffer(meshState.clusterDualQuaternions);
} else {
@@ -313,8 +305,7 @@ void Model::updateRenderItems() {
}
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
- data.setLayer(isLayeredInFront, isLayeredInHUD);
+ data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, isWireframe, useDualQuaternionSkinning);
});
}
@@ -322,8 +313,9 @@ void Model::updateRenderItems() {
Transform collisionMeshOffset;
collisionMeshOffset.setIdentity();
foreach(auto itemID, self->_collisionRenderItemsMap.keys()) {
- transaction.updateItem(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) {
+ transaction.updateItem(itemID, [renderItemKeyGlobalFlags, modelTransform, collisionMeshOffset](MeshPartPayload& data) {
// update the model transform for this render item.
+ data.updateKey(renderItemKeyGlobalFlags);
data.updateTransform(modelTransform, collisionMeshOffset);
});
}
@@ -773,110 +765,100 @@ void Model::calculateTriangleSets(const FBXGeometry& geometry) {
}
}
-void Model::setVisibleInScene(bool isVisible, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled) {
- if (_isVisible != isVisible || _viewTagBits != viewTagBits || _isGroupCulled != isGroupCulled) {
- _isVisible = isVisible;
- _viewTagBits = viewTagBits;
- _isGroupCulled = isGroupCulled;
+void Model::updateRenderItemsKey(const render::ScenePointer& scene) {
+ if (!scene) {
+ _needsFixupInScene = true;
+ return;
+ }
+ auto renderItemsKey = _renderItemKeyGlobalFlags;
+ render::Transaction transaction;
+ foreach(auto item, _modelMeshRenderItemsMap.keys()) {
+ transaction.updateItem(item, [renderItemsKey](ModelMeshPartPayload& data) {
+ data.updateKey(renderItemsKey);
+ });
+ }
+ foreach(auto item, _collisionRenderItemsMap.keys()) {
+ transaction.updateItem(item, [renderItemsKey](ModelMeshPartPayload& data) {
+ data.updateKey(renderItemsKey);
+ });
+ }
+ scene->enqueueTransaction(transaction);
+}
- bool isLayeredInFront = _isLayeredInFront;
- bool isLayeredInHUD = _isLayeredInHUD;
- bool canCastShadow = _canCastShadow;
- render::Transaction transaction;
- foreach (auto item, _modelMeshRenderItemsMap.keys()) {
- transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
- isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
- });
- }
- foreach(auto item, _collisionRenderItemsMap.keys()) {
- transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
- isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
- });
- }
- scene->enqueueTransaction(transaction);
+void Model::setVisibleInScene(bool visible, const render::ScenePointer& scene) {
+ if (Model::isVisible() != visible) {
+ auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
+ _renderItemKeyGlobalFlags = (visible ? keyBuilder.withVisible() : keyBuilder.withInvisible());
+ updateRenderItemsKey(scene);
}
}
-void Model::setCanCastShadow(bool canCastShadow, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled) {
- if (_canCastShadow != canCastShadow) {
- _canCastShadow = canCastShadow;
+bool Model::isVisible() const {
+ return _renderItemKeyGlobalFlags.isVisible();
+}
- bool isVisible = _isVisible;
- bool isLayeredInFront = _isLayeredInFront;
- bool isLayeredInHUD = _isLayeredInHUD;
-
- render::Transaction transaction;
- foreach (auto item, _modelMeshRenderItemsMap.keys()) {
- transaction.updateItem(item,
- [isVisible, viewTagBits, canCastShadow, isLayeredInFront, isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
- data.updateKey(isVisible, viewTagBits, canCastShadow, isLayeredInFront || isLayeredInHUD, isGroupCulled);
- });
- }
-
- scene->enqueueTransaction(transaction);
+void Model::setCanCastShadow(bool castShadow, const render::ScenePointer& scene) {
+ if (Model::canCastShadow() != castShadow) {
+ auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
+ _renderItemKeyGlobalFlags = (castShadow ? keyBuilder.withShadowCaster() : keyBuilder.withoutShadowCaster());
+ updateRenderItemsKey(scene);
}
}
-void Model::setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene) {
- if (_isLayeredInFront != isLayeredInFront) {
- _isLayeredInFront = isLayeredInFront;
+bool Model::canCastShadow() const {
+ return _renderItemKeyGlobalFlags.isShadowCaster();
+}
- bool isVisible = _isVisible;
- bool canCastShadow = _canCastShadow;
- uint8_t viewTagBits = _viewTagBits;
- bool isLayeredInHUD = _isLayeredInHUD;
- bool isGroupCulled = _isGroupCulled;
-
- render::Transaction transaction;
- foreach(auto item, _modelMeshRenderItemsMap.keys()) {
- transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
- isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
- data.setLayer(isLayeredInFront, isLayeredInHUD);
- });
- }
- foreach(auto item, _collisionRenderItemsMap.keys()) {
- transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
- isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
- data.setLayer(isLayeredInFront, isLayeredInHUD);
- });
- }
- scene->enqueueTransaction(transaction);
+void Model::setLayeredInFront(bool layeredInFront, const render::ScenePointer& scene) {
+ if (Model::isLayeredInFront() != layeredInFront) {
+ auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
+ _renderItemKeyGlobalFlags = (layeredInFront ? keyBuilder.withLayer(render::hifi::LAYER_3D_FRONT) : keyBuilder.withoutLayer());
+ updateRenderItemsKey(scene);
}
}
-void Model::setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene) {
- if (_isLayeredInHUD != isLayeredInHUD) {
- _isLayeredInHUD = isLayeredInHUD;
+bool Model::isLayeredInFront() const {
+ return _renderItemKeyGlobalFlags.isLayer(render::hifi::LAYER_3D_FRONT);
+}
- bool isVisible = _isVisible;
- bool canCastShadow = _canCastShadow;
- uint8_t viewTagBits = _viewTagBits;
- bool isLayeredInFront = _isLayeredInFront;
- bool isGroupCulled = _isGroupCulled;
-
- render::Transaction transaction;
- foreach(auto item, _modelMeshRenderItemsMap.keys()) {
- transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
- isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
- data.setLayer(isLayeredInFront, isLayeredInHUD);
- });
- }
- foreach(auto item, _collisionRenderItemsMap.keys()) {
- transaction.updateItem(item, [isVisible, viewTagBits, isLayeredInFront, canCastShadow,
- isLayeredInHUD, isGroupCulled](ModelMeshPartPayload& data) {
- data.updateKey(isVisible, isLayeredInFront || isLayeredInHUD, canCastShadow, viewTagBits, isGroupCulled);
- data.setLayer(isLayeredInFront, isLayeredInHUD);
- });
- }
- scene->enqueueTransaction(transaction);
+void Model::setLayeredInHUD(bool layeredInHUD, const render::ScenePointer& scene) {
+ if (Model::isLayeredInHUD() != layeredInHUD) {
+ auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
+ _renderItemKeyGlobalFlags = (layeredInHUD ? keyBuilder.withLayer(render::hifi::LAYER_3D_HUD) : keyBuilder.withoutLayer());
+ updateRenderItemsKey(scene);
}
}
+bool Model::isLayeredInHUD() const {
+ return _renderItemKeyGlobalFlags.isLayer(render::hifi::LAYER_3D_HUD);
+}
+
+void Model::setTagMask(uint8_t mask, const render::ScenePointer& scene) {
+ if (Model::getTagMask() != mask) {
+ auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
+ _renderItemKeyGlobalFlags = keyBuilder.withTagBits(mask);
+ updateRenderItemsKey(scene);
+ }
+}
+render::hifi::Tag Model::getTagMask() const {
+ return (render::hifi::Tag) _renderItemKeyGlobalFlags.getTagBits();
+}
+
+void Model::setGroupCulled(bool groupCulled, const render::ScenePointer& scene) {
+ if (Model::isGroupCulled() != groupCulled) {
+ auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
+ _renderItemKeyGlobalFlags = (groupCulled ? keyBuilder.withSubMetaCulled() : keyBuilder.withoutSubMetaCulled());
+ updateRenderItemsKey(scene);
+ }
+}
+bool Model::isGroupCulled() const {
+ return _renderItemKeyGlobalFlags.isSubMetaCulled();
+}
+
+const render::ItemKey Model::getRenderItemKeyGlobalFlags() const {
+ return _renderItemKeyGlobalFlags;
+}
+
bool Model::addToScene(const render::ScenePointer& scene,
render::Transaction& transaction,
render::Item::Status::Getters& statusGetters) {
@@ -1676,20 +1658,16 @@ void Model::addMaterial(graphics::MaterialLayer material, const std::string& par
for (auto shapeID : shapeIDs) {
if (shapeID < _modelMeshRenderItemIDs.size()) {
auto itemID = _modelMeshRenderItemIDs[shapeID];
- bool visible = isVisible();
- uint8_t viewTagBits = getViewTagBits();
- bool layeredInFront = isLayeredInFront();
- bool layeredInHUD = isLayeredInHUD();
- bool canCastShadow = _canCastShadow;
+ auto renderItemsKey = _renderItemKeyGlobalFlags;
bool wireframe = isWireframe();
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
- transaction.updateItem(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, canCastShadow,
+ transaction.updateItem(itemID, [material, renderItemsKey,
invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
data.addMaterial(material);
// if the material changed, we might need to update our item key or shape key
- data.updateKey(visible, layeredInFront || layeredInHUD, canCastShadow, viewTagBits);
+ data.updateKey(renderItemsKey);
data.setShapeKey(invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning);
});
}
@@ -1704,19 +1682,16 @@ void Model::removeMaterial(graphics::MaterialPointer material, const std::string
if (shapeID < _modelMeshRenderItemIDs.size()) {
auto itemID = _modelMeshRenderItemIDs[shapeID];
bool visible = isVisible();
- uint8_t viewTagBits = getViewTagBits();
- bool layeredInFront = isLayeredInFront();
- bool layeredInHUD = isLayeredInHUD();
- bool canCastShadow = _canCastShadow;
+ auto renderItemsKey = _renderItemKeyGlobalFlags;
bool wireframe = isWireframe();
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
- transaction.updateItem(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, canCastShadow,
+ transaction.updateItem(itemID, [material, visible, renderItemsKey,
invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
data.removeMaterial(material);
// if the material changed, we might need to update our item key or shape key
- data.updateKey(visible, layeredInFront || layeredInHUD, canCastShadow, viewTagBits);
+ data.updateKey(renderItemsKey);
data.setShapeKey(invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning);
});
}
diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h
index 2b14a7c055..4180288106 100644
--- a/libraries/render-utils/src/Model.h
+++ b/libraries/render-utils/src/Model.h
@@ -33,6 +33,7 @@
#include
#include
+#include "RenderHifi.h"
#include "GeometryCache.h"
#include "TextureCache.h"
#include "Rig.h"
@@ -87,13 +88,27 @@ public:
const QUrl& getURL() const { return _url; }
// new Scene/Engine rendering support
- void setVisibleInScene(bool isVisible, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled);
+ void setVisibleInScene(bool isVisible, const render::ScenePointer& scene = nullptr);
+ bool isVisible() const;
- bool canCastShadow() const { return _canCastShadow; }
- void setCanCastShadow(bool canCastShadow, const render::ScenePointer& scene, uint8_t viewTagBits, bool isGroupCulled);
+ render::hifi::Tag getTagMask() const;
+ void setTagMask(uint8_t mask, const render::ScenePointer& scene = nullptr);
+
+ bool isGroupCulled() const;
+ void setGroupCulled(bool isGroupCulled, const render::ScenePointer& scene = nullptr);
+
+ bool canCastShadow() const;
+ void setCanCastShadow(bool canCastShadow, const render::ScenePointer& scene = nullptr);
+
+ void setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene = nullptr);
+ void setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene = nullptr);
+
+ bool isLayeredInFront() const;
+ bool isLayeredInHUD() const;
+
+ // Access the current RenderItemKey Global Flags used by the model and applied to the render items representing the parts of the model.
+ const render::ItemKey getRenderItemKeyGlobalFlags() const;
- void setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene);
- void setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene);
bool needsFixupInScene() const;
bool needsReload() const { return _needsReload; }
@@ -108,13 +123,7 @@ public:
void removeFromScene(const render::ScenePointer& scene, render::Transaction& transaction);
bool isRenderable() const;
- bool isVisible() const { return _isVisible; }
- uint8_t getViewTagBits() const { return _viewTagBits; }
-
- bool isLayeredInFront() const { return _isLayeredInFront; }
- bool isLayeredInHUD() const { return _isLayeredInHUD; }
-
- bool isGroupCulled() const { return _isGroupCulled; }
+ void updateRenderItemsKey(const render::ScenePointer& scene);
virtual void updateRenderItems();
void setRenderItemsNeedUpdate();
@@ -404,10 +413,6 @@ protected:
QVector _blendshapeCoefficients;
QUrl _url;
- bool _isVisible;
- uint8_t _viewTagBits{ render::ItemKey::TAG_BITS_ALL };
-
- bool _canCastShadow;
gpu::Buffers _blendedVertexBuffers;
@@ -471,10 +476,16 @@ protected:
int _renderInfoDrawCalls { 0 };
int _renderInfoHasTransparent { false };
- bool _isLayeredInFront { false };
- bool _isLayeredInHUD { false };
-
- bool _isGroupCulled{ false };
+ // This Render ItemKey Global Flags capture the Model wide global set of flags that should be communicated to all the render items representing the Model.
+ // The flags concerned are:
+ // - isVisible: if true the Model is visible globally in the scene, regardless of the other flags in the item keys (tags or layer or shadow caster).
+ // - TagBits: the view mask defined through the TagBits telling in which view the Model is rendered if visible.
+ // - Layer: In which Layer this Model lives.
+ // - CastShadow: if true and visible and rendered in the view, the Model cast shadows if in a Light volume casting shadows.
+ // - CullGroup: if true, the render items representing the parts of the Model are culled by a single Meta render item that knows about them, they are not culled individually.
+ // For this to work, a Meta RI must exists and knows about the RIs of this Model.
+ //
+ render::ItemKey _renderItemKeyGlobalFlags;
bool shouldInvalidatePayloadShapeKey(int meshIndex);
diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp
index 3ea56f8542..47cab54d09 100644
--- a/libraries/render-utils/src/RenderDeferredTask.cpp
+++ b/libraries/render-utils/src/RenderDeferredTask.cpp
@@ -27,6 +27,7 @@
#include
#include
+#include "RenderHifi.h"
#include "RenderCommonTask.h"
#include "LightingModel.h"
#include "StencilMaskPass.h"
@@ -200,8 +201,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
const auto overlaysInFrontRangeTimer = task.addJob("BeginOverlaysInFrontRangeTimer", "BeginOverlaysInFrontRangeTimer");
// Layered Overlays
- const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT);
- const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT);
+ const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, render::hifi::LAYER_3D_FRONT);
+ const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, render::hifi::LAYER_3D_FRONT);
const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN(0);
const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN(0);
diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp
index 4388a39cf3..09a2afb711 100755
--- a/libraries/render-utils/src/RenderForwardTask.cpp
+++ b/libraries/render-utils/src/RenderForwardTask.cpp
@@ -23,6 +23,7 @@
#include
+#include "RenderHifi.h"
#include "StencilMaskPass.h"
#include "ZoneRenderer.h"
#include "FadeEffect.h"
@@ -79,8 +80,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
task.addJob("PrepareStencil", framebuffer);
// Layered Overlays
- const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT);
- const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT);
+ const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, render::hifi::LAYER_3D_FRONT);
+ const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, render::hifi::LAYER_3D_FRONT);
const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN(0);
const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN(0);
diff --git a/libraries/render-utils/src/RenderHifi.h b/libraries/render-utils/src/RenderHifi.h
new file mode 100644
index 0000000000..c489a0ad1d
--- /dev/null
+++ b/libraries/render-utils/src/RenderHifi.h
@@ -0,0 +1,43 @@
+//
+// RenderHifi.h
+// libraries/render-utils/src
+//
+// Created by Sam Gateau on 5/30/2018.
+// Copyright 2018 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+#ifndef hifi_RenderHifi_h
+#define hifi_RenderHifi_h
+
+#include
+
+
+
+// In the library render-utils we are specializing the generic components of the render library to create the custom hifi render engine
+// Objects and types serving this goal are define in the namespace render.hifi
+// TODO: extend the namespace to all the classes where it make sense in render-utils
+namespace render {
+ namespace hifi {
+
+ // Tag is the alias names of render::ItemKey::Tag combinations used in the Hifi Render Engine
+ enum Tag : uint8_t {
+ TAG_NONE = render::ItemKey::TAG_BITS_NONE, // No Tags at all
+ TAG_MAIN_VIEW = render::ItemKey::TAG_BITS_0, // Main view
+ TAG_SECONDARY_VIEW = render::ItemKey::TAG_BITS_1, // Secondary View
+ TAG_ALL_VIEWS = TAG_MAIN_VIEW | TAG_SECONDARY_VIEW, // All views
+ };
+
+ // Layer is the alias names of the render::ItemKey::Layer used in the Hifi Render Engine
+ enum Layer : uint8_t {
+ LAYER_3D = render::ItemKey::LAYER_DEFAULT,
+ LAYER_3D_FRONT = render::ItemKey::LAYER_1,
+ LAYER_3D_HUD = render::ItemKey::LAYER_2,
+ LAYER_2D = render::ItemKey::LAYER_3,
+ LAYER_BACKGROUND = render::ItemKey::LAYER_BACKGROUND,
+ };
+ }
+}
+
+#endif // hifi_RenderHifi_h
diff --git a/libraries/render-utils/src/SubsurfaceScattering.h b/libraries/render-utils/src/SubsurfaceScattering.h
index 30021fae40..780ce34d7f 100644
--- a/libraries/render-utils/src/SubsurfaceScattering.h
+++ b/libraries/render-utils/src/SubsurfaceScattering.h
@@ -149,7 +149,7 @@ class DebugSubsurfaceScatteringConfig : public render::Job::Config {
Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
public:
- DebugSubsurfaceScatteringConfig() : render::Job::Config(true) {}
+ DebugSubsurfaceScatteringConfig() : render::Job::Config(false) {}
bool showProfile{ false };
bool showLUT{ false };
diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp
index b5819f114f..3f55e6dedc 100644
--- a/libraries/render/src/render/CullTask.cpp
+++ b/libraries/render/src/render/CullTask.cpp
@@ -368,9 +368,9 @@ void CullShapeBounds::run(const RenderContextPointer& renderContext, const Input
RenderArgs* args = renderContext->args;
const auto& inShapes = inputs.get0();
- const auto& cullFilter = inputs.get1();
- const auto& boundsFilter = inputs.get2();
- const auto& antiFrustum = inputs.get3();
+ const auto& cullFilter = inputs.get1();
+ const auto& boundsFilter = inputs.get2();
+ const auto& antiFrustum = inputs.get3();
auto& outShapes = outputs.edit0();
auto& outBounds = outputs.edit1();
@@ -380,7 +380,7 @@ void CullShapeBounds::run(const RenderContextPointer& renderContext, const Input
if (!cullFilter.selectsNothing() || !boundsFilter.selectsNothing()) {
auto& details = args->_details.edit(_detailType);
Test test(_cullFunctor, args, details, antiFrustum);
- auto scene = args->_scene;
+ auto scene = args->_scene;
for (auto& inItems : inShapes) {
auto key = inItems.first;
@@ -395,26 +395,26 @@ void CullShapeBounds::run(const RenderContextPointer& renderContext, const Input
if (antiFrustum == nullptr) {
for (auto& item : inItems.second) {
if (test.solidAngleTest(item.bound) && test.frustumTest(item.bound)) {
- const auto shapeKey = scene->getItem(item.id).getKey();
- if (cullFilter.test(shapeKey)) {
- outItems->second.emplace_back(item);
- }
- if (boundsFilter.test(shapeKey)) {
- outBounds += item.bound;
- }
+ const auto shapeKey = scene->getItem(item.id).getKey();
+ if (cullFilter.test(shapeKey)) {
+ outItems->second.emplace_back(item);
+ }
+ if (boundsFilter.test(shapeKey)) {
+ outBounds += item.bound;
+ }
}
}
} else {
for (auto& item : inItems.second) {
if (test.solidAngleTest(item.bound) && test.frustumTest(item.bound) && test.antiFrustumTest(item.bound)) {
- const auto shapeKey = scene->getItem(item.id).getKey();
- if (cullFilter.test(shapeKey)) {
- outItems->second.emplace_back(item);
- }
- if (boundsFilter.test(shapeKey)) {
- outBounds += item.bound;
- }
- }
+ const auto shapeKey = scene->getItem(item.id).getKey();
+ if (cullFilter.test(shapeKey)) {
+ outItems->second.emplace_back(item);
+ }
+ if (boundsFilter.test(shapeKey)) {
+ outBounds += item.bound;
+ }
+ }
}
}
details._rendered += (int)outItems->second.size();
@@ -487,6 +487,7 @@ void FetchSpatialSelection::run(const RenderContextPointer& renderContext,
if (filter.test(item.getKey())) {
ItemBound itemBound(id, item.getBound());
outItems.emplace_back(itemBound);
+
}
}
}
diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp
index b0842d63cd..da8e60d40a 100644
--- a/libraries/render/src/render/Engine.cpp
+++ b/libraries/render/src/render/Engine.cpp
@@ -36,12 +36,11 @@ public:
}
};
-Engine::Engine() : Task(EngineTask::JobModel::create("Engine")),
- _renderContext(std::make_shared())
+RenderEngine::RenderEngine() : Engine(EngineTask::JobModel::create("Engine"), std::make_shared())
{
}
-void Engine::load() {
+void RenderEngine::load() {
auto config = getConfiguration();
const QString configFile= "config/render.json";
diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h
index 0271c71529..130ed6533f 100644
--- a/libraries/render/src/render/Engine.h
+++ b/libraries/render/src/render/Engine.h
@@ -25,7 +25,7 @@ namespace render {
class RenderContext : public task::JobContext {
public:
- RenderContext() : task::JobContext(trace_render()) {}
+ RenderContext() : task::JobContext() {}
virtual ~RenderContext() {}
RenderArgs* args;
@@ -33,7 +33,9 @@ namespace render {
};
using RenderContextPointer = std::shared_ptr;
- Task_DeclareTypeAliases(RenderContext)
+ Task_DeclareCategoryTimeProfilerClass(RenderTimeProfiler, trace_render);
+
+ Task_DeclareTypeAliases(RenderContext, RenderTimeProfiler)
// Versions of the COnfig integrating a gpu & batch timer
class GPUJobConfig : public JobConfig {
@@ -57,10 +59,10 @@ namespace render {
class GPUTaskConfig : public TaskConfig {
Q_OBJECT
- Q_PROPERTY(double gpuRunTime READ getGPURunTime)
- Q_PROPERTY(double batchRunTime READ getBatchRunTime)
+ Q_PROPERTY(double gpuRunTime READ getGPURunTime)
+ Q_PROPERTY(double batchRunTime READ getBatchRunTime)
- double _msGPURunTime { 0.0 };
+ double _msGPURunTime { 0.0 };
double _msBatchRunTime { 0.0 };
public:
@@ -80,32 +82,25 @@ namespace render {
// The render engine holds all render tasks, and is itself a render task.
// State flows through tasks to jobs via the render and scene contexts -
// the engine should not be known from its jobs.
- class Engine : public Task {
+ class RenderEngine : public Engine {
public:
- Engine();
- ~Engine() = default;
+ RenderEngine();
+ ~RenderEngine() = default;
// Load any persisted settings, and set up the presets
// This should be run after adding all jobs, and before building ui
void load();
// Register the scene
- void registerScene(const ScenePointer& scene) { _renderContext->_scene = scene; }
+ void registerScene(const ScenePointer& scene) { _context->_scene = scene; }
// acces the RenderContext
- RenderContextPointer getRenderContext() const { return _renderContext; }
-
- // Render a frame
- // Must have a scene registered and a context set
- void run() { assert(_renderContext); Task::run(_renderContext); }
+ RenderContextPointer getRenderContext() const { return _context; }
protected:
- RenderContextPointer _renderContext;
-
- void run(const RenderContextPointer& context) override { assert(_renderContext); Task::run(_renderContext); }
};
- using EnginePointer = std::shared_ptr;
+ using EnginePointer = std::shared_ptr;
}
diff --git a/libraries/render/src/render/Item.cpp b/libraries/render/src/render/Item.cpp
index 9c5efb9fa7..532964777f 100644
--- a/libraries/render/src/render/Item.cpp
+++ b/libraries/render/src/render/Item.cpp
@@ -29,25 +29,9 @@ const float Item::Status::Value::CYAN = 180.0f;
const float Item::Status::Value::BLUE = 240.0f;
const float Item::Status::Value::MAGENTA = 300.0f;
-const int Item::LAYER_2D = 0;
-const int Item::LAYER_3D = 1;
-const int Item::LAYER_3D_FRONT = 2;
-const int Item::LAYER_3D_HUD = 3;
-
-const uint8_t ItemKey::TAG_BITS_ALL { 0xFF };
-const uint8_t ItemKey::TAG_BITS_NONE { 0x00 };
-const uint8_t ItemKey::TAG_BITS_0 { 0x01 };
-const uint8_t ItemKey::TAG_BITS_1 { 0x02 };
-const uint8_t ItemKey::TAG_BITS_2 { 0x04 };
-const uint8_t ItemKey::TAG_BITS_3 { 0x08 };
-const uint8_t ItemKey::TAG_BITS_4 { 0x10 };
-const uint8_t ItemKey::TAG_BITS_5 { 0x20 };
-const uint8_t ItemKey::TAG_BITS_6 { 0x40 };
-const uint8_t ItemKey::TAG_BITS_7 { 0x80 };
-
const uint32_t ItemKey::KEY_TAG_BITS_MASK = ((uint32_t) ItemKey::TAG_BITS_ALL) << FIRST_TAG_BIT;
-
+const uint32_t ItemKey::KEY_LAYER_BITS_MASK = ((uint32_t)ItemKey::LAYER_BITS_ALL) << FIRST_LAYER_BIT;
void Item::Status::Value::setScale(float scale) {
_scale = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), 0.0f));
diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h
index e4dcc7ee03..1dfef73686 100644
--- a/libraries/render/src/render/Item.h
+++ b/libraries/render/src/render/Item.h
@@ -52,23 +52,45 @@ public:
TAG_6,
TAG_7,
- NUM_TAGS
+ NUM_TAGS,
+
+ // Tag bits are derived from the Tag enum
+ TAG_BITS_ALL = 0xFF,
+ TAG_BITS_NONE = 0x00,
+ TAG_BITS_0 = 0x01,
+ TAG_BITS_1 = 0x02,
+ TAG_BITS_2 = 0x04,
+ TAG_BITS_3 = 0x08,
+ TAG_BITS_4 = 0x10,
+ TAG_BITS_5 = 0x20,
+ TAG_BITS_6 = 0x40,
+ TAG_BITS_7 = 0x80,
+ };
+
+ // Items are organized in layers, an item belongs to one of the 8 Layers available.
+ // By default an item is in the 'LAYER_DEFAULT' meaning that it is NOT layered.
+ // THere is NO ordering relationship between layers.
+ enum Layer : uint8_t {
+ LAYER_DEFAULT = 0, // layer 0 aka Default is a 'NOT' layer, items are not considered layered, this is the default value
+ LAYER_1,
+ LAYER_2,
+ LAYER_3,
+ LAYER_4,
+ LAYER_5,
+ LAYER_6,
+ LAYER_BACKGROUND, // Last Layer is the background by convention
+
+ NUM_LAYERS,
+
+ // Layer bits are derived from the Layer enum, the number of bits needed to represent integer 0 to NUM_LAYERS
+ NUM_LAYER_BITS = 3,
+ LAYER_BITS_ALL = 0x07,
};
- // Tag bits are derived from the Tag enum
- const static uint8_t TAG_BITS_ALL;
- const static uint8_t TAG_BITS_NONE;
- const static uint8_t TAG_BITS_0;
- const static uint8_t TAG_BITS_1;
- const static uint8_t TAG_BITS_2;
- const static uint8_t TAG_BITS_3;
- const static uint8_t TAG_BITS_4;
- const static uint8_t TAG_BITS_5;
- const static uint8_t TAG_BITS_6;
- const static uint8_t TAG_BITS_7;
enum FlagBit : uint32_t {
- TYPE_SHAPE = 0, // Item is a Shape
- TYPE_LIGHT, // Item is a Light
+ TYPE_SHAPE = 0, // Item is a Shape: Implements the Shape Interface that draw a Geometry rendered with a Material
+ TYPE_LIGHT, // Item is a Light: Implements the Light Interface that
+ TYPE_CAMERA, // Item is a Camera: Implements the Camera Interface
TYPE_META, // Item is a Meta: meanning it s used to represent a higher level object, potentially represented by other render items
TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work...
@@ -77,13 +99,15 @@ public:
DEFORMED, // Deformed within bound, not solid
INVISIBLE, // Visible or not in the scene?
SHADOW_CASTER, // Item cast shadows
- LAYERED, // Item belongs to one of the layers different from the default layer
META_CULL_GROUP, // As a meta item, the culling of my sub items is based solely on my bounding box and my visibility in the view
SUB_META_CULLED, // As a sub item of a meta render item set as cull group, need to be set to my culling to the meta render it
FIRST_TAG_BIT, // 8 Tags available to organize the items and filter them against
LAST_TAG_BIT = FIRST_TAG_BIT + NUM_TAGS,
+ FIRST_LAYER_BIT, // 8 Exclusive Layers (encoded in 3 bits) available to organize the items in layers, an item can only belong to ONE layer
+ LAST_LAYER_BIT = FIRST_LAYER_BIT + NUM_LAYER_BITS,
+
__SMALLER, // Reserved bit for spatialized item to indicate that it is smaller than expected in the cell in which it belongs (probably because it overlaps over several smaller cells)
NUM_FLAGS, // Not a valid flag
@@ -96,6 +120,12 @@ public:
return (keyBits & ~KEY_TAG_BITS_MASK) | (((uint32_t)tagBits) << FIRST_TAG_BIT);
}
+ // All the bits touching layer bits sets to true
+ const static uint32_t KEY_LAYER_BITS_MASK;
+ static uint32_t evalLayerBitsWithKeyBits(uint8_t layer, const uint32_t keyBits) {
+ return (keyBits & ~KEY_LAYER_BITS_MASK) | (((uint32_t)layer & LAYER_BITS_ALL) << FIRST_LAYER_BIT);
+ }
+
// The key is the Flags
Flags _flags;
@@ -122,20 +152,26 @@ public:
Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); }
Builder& withDeformed() { _flags.set(DEFORMED); return (*this); }
Builder& withInvisible() { _flags.set(INVISIBLE); return (*this); }
+ Builder& withVisible() { _flags.reset(INVISIBLE); return (*this); }
Builder& withShadowCaster() { _flags.set(SHADOW_CASTER); return (*this); }
- Builder& withLayered() { _flags.set(LAYERED); return (*this); }
+ Builder& withoutShadowCaster() { _flags.reset(SHADOW_CASTER); return (*this); }
Builder& withMetaCullGroup() { _flags.set(META_CULL_GROUP); return (*this); }
+ Builder& withoutMetaCullGroup() { _flags.reset(META_CULL_GROUP); return (*this); }
Builder& withSubMetaCulled() { _flags.set(SUB_META_CULLED); return (*this); }
+ Builder& withoutSubMetaCulled() { _flags.reset(SUB_META_CULLED); return (*this); }
Builder& withTag(Tag tag) { _flags.set(FIRST_TAG_BIT + tag); return (*this); }
// Set ALL the tags in one call using the Tag bits
Builder& withTagBits(uint8_t tagBits) { _flags = evalTagBitsWithKeyBits(tagBits, _flags.to_ulong()); return (*this); }
+ Builder& withLayer(uint8_t layer) { _flags = evalLayerBitsWithKeyBits(layer, _flags.to_ulong()); return (*this); }
+ Builder& withoutLayer() { return withLayer(LAYER_DEFAULT); }
+
// Convenient standard keys that we will keep on using all over the place
static Builder opaqueShape() { return Builder().withTypeShape(); }
static Builder transparentShape() { return Builder().withTypeShape().withTransparent(); }
static Builder light() { return Builder().withTypeLight(); }
- static Builder background() { return Builder().withViewSpace().withLayered(); }
+ static Builder background() { return Builder().withViewSpace().withLayer(LAYER_BACKGROUND); }
};
ItemKey(const Builder& builder) : ItemKey(builder._flags) {}
@@ -160,9 +196,6 @@ public:
bool isShadowCaster() const { return _flags[SHADOW_CASTER]; }
- bool isLayered() const { return _flags[LAYERED]; }
- bool isSpatial() const { return !isLayered(); }
-
bool isMetaCullGroup() const { return _flags[META_CULL_GROUP]; }
void setMetaCullGroup(bool cullGroup) { (cullGroup ? _flags.set(META_CULL_GROUP) : _flags.reset(META_CULL_GROUP)); }
@@ -172,6 +205,11 @@ public:
bool isTag(Tag tag) const { return _flags[FIRST_TAG_BIT + tag]; }
uint8_t getTagBits() const { return ((_flags.to_ulong() & KEY_TAG_BITS_MASK) >> FIRST_TAG_BIT); }
+ uint8_t getLayer() const { return ((_flags.to_ulong() & KEY_LAYER_BITS_MASK) >> FIRST_LAYER_BIT); }
+ bool isLayer(uint8_t layer) const { return getLayer() == layer; }
+ bool isLayered() const { return getLayer() != LAYER_DEFAULT; }
+ bool isSpatial() const { return !isLayered(); }
+
// Probably not public, flags used by the scene
bool isSmall() const { return _flags[__SMALLER]; }
void setSmaller(bool smaller) { (smaller ? _flags.set(__SMALLER) : _flags.reset(__SMALLER)); }
@@ -229,9 +267,6 @@ public:
Builder& withNoShadowCaster() { _value.reset(ItemKey::SHADOW_CASTER); _mask.set(ItemKey::SHADOW_CASTER); return (*this); }
Builder& withShadowCaster() { _value.set(ItemKey::SHADOW_CASTER); _mask.set(ItemKey::SHADOW_CASTER); return (*this); }
- Builder& withoutLayered() { _value.reset(ItemKey::LAYERED); _mask.set(ItemKey::LAYERED); return (*this); }
- Builder& withLayered() { _value.set(ItemKey::LAYERED); _mask.set(ItemKey::LAYERED); return (*this); }
-
Builder& withoutMetaCullGroup() { _value.reset(ItemKey::META_CULL_GROUP); _mask.set(ItemKey::META_CULL_GROUP); return (*this); }
Builder& withMetaCullGroup() { _value.set(ItemKey::META_CULL_GROUP); _mask.set(ItemKey::META_CULL_GROUP); return (*this); }
@@ -243,6 +278,9 @@ public:
// Set ALL the tags in one call using the Tag bits and the Tag bits touched
Builder& withTagBits(uint8_t tagBits, uint8_t tagMask) { _value = ItemKey::evalTagBitsWithKeyBits(tagBits, _value.to_ulong()); _mask = ItemKey::evalTagBitsWithKeyBits(tagMask, _mask.to_ulong()); return (*this); }
+ Builder& withoutLayered() { _value = ItemKey::evalLayerBitsWithKeyBits(ItemKey::LAYER_DEFAULT, _value.to_ulong()); _mask |= ItemKey::KEY_LAYER_BITS_MASK; return (*this); }
+ Builder& withLayer(uint8_t layer) { _value = ItemKey::evalLayerBitsWithKeyBits(layer, _value.to_ulong()); _mask |= ItemKey::KEY_LAYER_BITS_MASK; return (*this); }
+
Builder& withNothing() { _value.reset(); _mask.reset(); return (*this); }
// Convenient standard keys that we will keep on using all over the place
@@ -251,9 +289,7 @@ public:
static Builder transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace(); }
static Builder light() { return Builder().withTypeLight(); }
static Builder meta() { return Builder().withTypeMeta(); }
- static Builder background() { return Builder().withViewSpace().withLayered(); }
- static Builder opaqueShapeLayered() { return Builder().withTypeShape().withOpaque().withWorldSpace().withLayered(); }
- static Builder transparentShapeLayered() { return Builder().withTypeShape().withTransparent().withWorldSpace().withLayered(); }
+ static Builder background() { return Builder().withViewSpace().withLayer(ItemKey::LAYER_BACKGROUND); }
static Builder nothing() { return Builder().withNothing(); }
};
@@ -376,7 +412,6 @@ public:
public:
virtual const ItemKey getKey() const = 0;
virtual const Bound getBound() const = 0;
- virtual int getLayer() const = 0;
virtual void render(RenderArgs* args) = 0;
virtual const ShapeKey getShapeKey() const = 0;
@@ -421,13 +456,8 @@ public:
// Get the bound of the item expressed in world space (or eye space depending on the key.isWorldSpace())
const Bound getBound() const { return _payload->getBound(); }
- // Get the layer where the item belongs.
- int getLayer() const { return _payload->getLayer(); }
-
- static const int LAYER_2D;
- static const int LAYER_3D;
- static const int LAYER_3D_FRONT;
- static const int LAYER_3D_HUD;
+ // Get the layer where the item belongs, simply reflecting the key.
+ int getLayer() const { return _key.getLayer(); }
// Render call for the item
void render(RenderArgs* args) const { _payload->render(args); }
@@ -477,7 +507,6 @@ inline QDebug operator<<(QDebug debug, const Item& item) {
// Item shared interface supported by the payload
template const ItemKey payloadGetKey(const std::shared_ptr& payloadData) { return ItemKey(); }
template const Item::Bound payloadGetBound(const std::shared_ptr& payloadData) { return Item::Bound(); }
-template int payloadGetLayer(const std::shared_ptr& payloadData) { return 0; }
template void payloadRender(const std::shared_ptr& payloadData, RenderArgs* args) { }
// Shape type interface
@@ -504,7 +533,6 @@ public:
// Payload general interface
virtual const ItemKey getKey() const override { return payloadGetKey(_data); }
virtual const Item::Bound getBound() const override { return payloadGetBound(_data); }
- virtual int getLayer() const override { return payloadGetLayer(_data); }
virtual void render(RenderArgs* args) override { payloadRender(_data, args); }
diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h
index 2d8bc7f4dd..68acfe8d0f 100644
--- a/libraries/render/src/render/Scene.h
+++ b/libraries/render/src/render/Scene.h
@@ -21,7 +21,7 @@
namespace render {
-class Engine;
+class RenderEngine;
class Scene;
// Transaction is the mechanism to make any change to the scene.
@@ -236,7 +236,7 @@ protected:
StageMap _stages;
- friend class Engine;
+ friend class RenderEngine;
};
typedef std::shared_ptr ScenePointer;
diff --git a/libraries/script-engine/src/AssetScriptingInterface.h b/libraries/script-engine/src/AssetScriptingInterface.h
index 7f7a3a68b0..72d6901fb5 100644
--- a/libraries/script-engine/src/AssetScriptingInterface.h
+++ b/libraries/script-engine/src/AssetScriptingInterface.h
@@ -121,7 +121,7 @@ public:
/**jsdoc
* A set of properties that can be passed to {@link Assets.getAsset}.
- * @typedef {Object} Assets.GetOptions
+ * @typedef {object} Assets.GetOptions
* @property {string} [url] an "atp:" style URL, hash, or relative mapped path to fetch
* @property {string} [responseType=text] the desired reponse type (text | arraybuffer | json)
* @property {boolean} [decompress=false] whether to attempt gunzip decompression on the fetched data
@@ -137,7 +137,7 @@ public:
/**jsdoc
* Result value returned by {@link Assets.getAsset}.
- * @typedef {Object} Assets~getAssetResult
+ * @typedef {object} Assets~getAssetResult
* @property {string} [url] the resolved "atp:" style URL for the fetched asset
* @property {string} [hash] the resolved hash for the fetched asset
* @property {string|ArrayBuffer|Object} [response] response data (possibly converted per .responseType value)
@@ -159,7 +159,7 @@ public:
/**jsdoc
* A set of properties that can be passed to {@link Assets.putAsset}.
- * @typedef {Object} Assets.PutOptions
+ * @typedef {object} Assets.PutOptions
* @property {ArrayBuffer|string} [data] byte buffer or string value representing the new asset's content
* @property {string} [path=null] ATP path mapping to automatically create (upon successful upload to hash)
* @property {boolean} [compress=false] whether to gzip compress data before uploading
@@ -174,7 +174,7 @@ public:
/**jsdoc
* Result value returned by {@link Assets.putAsset}.
- * @typedef {Object} Assets~putAssetResult
+ * @typedef {object} Assets~putAssetResult
* @property {string} [url] the resolved "atp:" style URL for the uploaded asset (based on .path if specified, otherwise on the resulting ATP hash)
* @property {string} [path] the uploaded asset's resulting ATP path (or undefined if no path mapping was assigned)
* @property {string} [hash] the uploaded asset's resulting ATP hash
diff --git a/libraries/script-engine/src/Quat.h b/libraries/script-engine/src/Quat.h
index 1ccdfdbf31..76b7ac45e3 100644
--- a/libraries/script-engine/src/Quat.h
+++ b/libraries/script-engine/src/Quat.h
@@ -43,7 +43,7 @@
* @hifi-server-entity
* @hifi-assignment-client
*
- * @property IDENTITY {Quat} { x: 0, y: 0, z: 0, w: 1 }
: The identity rotation, i.e., no rotation.
+ * @property {Quat} IDENTITY - { x: 0, y: 0, z: 0, w: 1 }
: The identity rotation, i.e., no rotation.
* Read-only.
* @example Print the IDENTITY
value.
* print(JSON.stringify(Quat.IDENTITY)); // { x: 0, y: 0, z: 0, w: 1 }
diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h
index fdfbc6f6c0..da42cf2df3 100644
--- a/libraries/script-engine/src/SceneScriptingInterface.h
+++ b/libraries/script-engine/src/SceneScriptingInterface.h
@@ -21,7 +21,7 @@
namespace SceneScripting {
/**jsdoc
- * @typedef Scene.Stage.Location
+ * @typedef {object} Scene.Stage.Location
* @property {number} longitude
* @property {number} latitude
* @property {number} altitude
@@ -49,7 +49,7 @@ namespace SceneScripting {
using LocationPointer = std::unique_ptr;
/**jsdoc
- * @typedef Scene.Stage.Time
+ * @typedef {object} Scene.Stage.Time
* @property {number} hour
* @property {number} day
*/
@@ -73,7 +73,7 @@ namespace SceneScripting {
using TimePointer = std::unique_ptr