mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-05 03:00:45 +02:00
518 lines
23 KiB
C++
518 lines
23 KiB
C++
//
|
|
// EntityItem.h
|
|
// libraries/entities/src
|
|
//
|
|
// Created by Brad Hefta-Gaub on 12/4/13.
|
|
// Copyright 2013 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_EntityItem_h
|
|
#define hifi_EntityItem_h
|
|
|
|
#include <memory>
|
|
#include <stdint.h>
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <AnimationCache.h> // for Animation, AnimationCache, and AnimationPointer classes
|
|
#include <Octree.h> // for EncodeBitstreamParams class
|
|
#include <OctreeElement.h> // for OctreeElement::AppendState
|
|
#include <OctreePacketData.h>
|
|
#include <ShapeInfo.h>
|
|
#include <Transform.h>
|
|
|
|
#include "EntityItemID.h"
|
|
#include "EntityItemProperties.h"
|
|
#include "EntityItemPropertiesDefaults.h"
|
|
#include "EntityTypes.h"
|
|
#include "SimulationOwner.h"
|
|
|
|
class EntitySimulation;
|
|
class EntityTreeElement;
|
|
class EntityTreeElementExtraEncodeData;
|
|
|
|
class EntityActionInterface;
|
|
typedef std::shared_ptr<EntityActionInterface> EntityActionPointer;
|
|
|
|
|
|
namespace render {
|
|
class Scene;
|
|
class PendingChanges;
|
|
}
|
|
|
|
// these thesholds determine what updates will be ignored (client and server)
|
|
const float IGNORE_POSITION_DELTA = 0.0001f;
|
|
const float IGNORE_DIMENSIONS_DELTA = 0.0005f;
|
|
const float IGNORE_ALIGNMENT_DOT = 0.99997f;
|
|
const float IGNORE_LINEAR_VELOCITY_DELTA = 0.001f;
|
|
const float IGNORE_DAMPING_DELTA = 0.001f;
|
|
const float IGNORE_GRAVITY_DELTA = 0.001f;
|
|
const float IGNORE_ANGULAR_VELOCITY_DELTA = 0.0002f;
|
|
|
|
// these thresholds determine what updates will activate the physical object
|
|
const float ACTIVATION_POSITION_DELTA = 0.005f;
|
|
const float ACTIVATION_DIMENSIONS_DELTA = 0.005f;
|
|
const float ACTIVATION_ALIGNMENT_DOT = 0.99990f;
|
|
const float ACTIVATION_LINEAR_VELOCITY_DELTA = 0.01f;
|
|
const float ACTIVATION_GRAVITY_DELTA = 0.1f;
|
|
const float ACTIVATION_ANGULAR_VELOCITY_DELTA = 0.03f;
|
|
|
|
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
|
|
#define ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() { };
|
|
|
|
#define debugTime(T, N) qPrintable(QString("%1 [ %2 ago]").arg(T, 16, 10).arg(formatUsecTime(N - T), 15))
|
|
#define debugTimeOnly(T) qPrintable(QString("%1").arg(T, 16, 10))
|
|
#define debugTreeVector(V) V << "[" << V << " in meters ]"
|
|
|
|
#if DEBUG
|
|
#define assertLocked() assert(isLocked())
|
|
#else
|
|
#define assertLocked()
|
|
#endif
|
|
|
|
#if DEBUG
|
|
#define assertWriteLocked() assert(isWriteLocked())
|
|
#else
|
|
#define assertWriteLocked()
|
|
#endif
|
|
|
|
#if DEBUG
|
|
#define assertUnlocked() assert(isUnlocked())
|
|
#else
|
|
#define assertUnlocked()
|
|
#endif
|
|
|
|
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
|
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
|
/// one directly, instead you must only construct one of it's derived classes with additional features.
|
|
class EntityItem : public std::enable_shared_from_this<EntityItem> {
|
|
// These two classes manage lists of EntityItem pointers and must be able to cleanup pointers when an EntityItem is deleted.
|
|
// To make the cleanup robust each EntityItem has backpointers to its manager classes (which are only ever set/cleared by
|
|
// the managers themselves, hence they are fiends) whose NULL status can be used to determine which managers still need to
|
|
// do cleanup.
|
|
friend class EntityTreeElement;
|
|
friend class EntitySimulation;
|
|
public:
|
|
enum EntityDirtyFlags {
|
|
DIRTY_POSITION = 0x0001,
|
|
DIRTY_ROTATION = 0x0002,
|
|
DIRTY_LINEAR_VELOCITY = 0x0004,
|
|
DIRTY_ANGULAR_VELOCITY = 0x0008,
|
|
DIRTY_MASS = 0x0010,
|
|
DIRTY_COLLISION_GROUP = 0x0020,
|
|
DIRTY_MOTION_TYPE = 0x0040,
|
|
DIRTY_SHAPE = 0x0080,
|
|
DIRTY_LIFETIME = 0x0100,
|
|
DIRTY_UPDATEABLE = 0x0200,
|
|
DIRTY_MATERIAL = 0x00400,
|
|
DIRTY_PHYSICS_ACTIVATION = 0x0800, // should activate object in physics engine
|
|
DIRTY_SIMULATOR_OWNERSHIP = 0x1000, // should claim simulator ownership
|
|
DIRTY_SIMULATOR_ID = 0x2000, // the simulatorID has changed
|
|
DIRTY_TRANSFORM = DIRTY_POSITION | DIRTY_ROTATION,
|
|
DIRTY_VELOCITIES = DIRTY_LINEAR_VELOCITY | DIRTY_ANGULAR_VELOCITY
|
|
};
|
|
|
|
DONT_ALLOW_INSTANTIATION // This class can not be instantiated directly
|
|
|
|
EntityItem(const EntityItemID& entityItemID);
|
|
virtual ~EntityItem();
|
|
|
|
// ID and EntityItemID related methods
|
|
const QUuid& getID() const { return _id; }
|
|
void setID(const QUuid& id) { _id = id; }
|
|
EntityItemID getEntityItemID() const { return EntityItemID(_id); }
|
|
|
|
// methods for getting/setting all properties of an entity
|
|
virtual EntityItemProperties getProperties() const;
|
|
|
|
/// returns true if something changed
|
|
virtual bool setProperties(const EntityItemProperties& properties);
|
|
|
|
/// Override this in your derived class if you'd like to be informed when something about the state of the entity
|
|
/// has changed. This will be called with properties change or when new data is loaded from a stream
|
|
virtual void somethingChangedNotification() { }
|
|
|
|
void recordCreationTime(); // set _created to 'now'
|
|
quint64 getLastSimulated() const { return _lastSimulated; } /// Last simulated time of this entity universal usecs
|
|
void setLastSimulated(quint64 now) { _lastSimulated = now; }
|
|
|
|
/// Last edited time of this entity universal usecs
|
|
quint64 getLastEdited() const { return _lastEdited; }
|
|
void setLastEdited(quint64 lastEdited)
|
|
{ _lastEdited = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
|
|
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
|
|
{ return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; }
|
|
|
|
/// Last time we sent out an edit packet for this entity
|
|
quint64 getLastBroadcast() const { return _lastBroadcast; }
|
|
void setLastBroadcast(quint64 lastBroadcast) { _lastBroadcast = lastBroadcast; }
|
|
|
|
void markAsChangedOnServer() { _changedOnServer = usecTimestampNow(); }
|
|
quint64 getLastChangedOnServer() const { return _changedOnServer; }
|
|
|
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
|
|
|
virtual OctreeElement::AppendState appendEntityData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
|
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData) const;
|
|
|
|
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
|
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData,
|
|
EntityPropertyFlags& requestedProperties,
|
|
EntityPropertyFlags& propertyFlags,
|
|
EntityPropertyFlags& propertiesDidntFit,
|
|
int& propertyCount,
|
|
OctreeElement::AppendState& appendState) const { /* do nothing*/ };
|
|
|
|
static EntityItemID readEntityItemIDFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
|
ReadBitstreamToTreeParams& args);
|
|
|
|
virtual int readEntityDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
|
|
|
|
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
|
ReadBitstreamToTreeParams& args,
|
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData)
|
|
{ return 0; }
|
|
|
|
virtual bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene,
|
|
render::PendingChanges& pendingChanges) { return false; } // by default entity items don't add to scene
|
|
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene,
|
|
render::PendingChanges& pendingChanges) { } // by default entity items don't add to scene
|
|
virtual void render(RenderArgs* args) { } // by default entity items don't know how to render
|
|
|
|
static int expectedBytes();
|
|
|
|
static void adjustEditPacketForClockSkew(QByteArray& buffer, int clockSkew);
|
|
|
|
// perform update
|
|
virtual void update(const quint64& now) { _lastUpdated = now; }
|
|
quint64 getLastUpdated() const { return _lastUpdated; }
|
|
|
|
// perform linear extrapolation for SimpleEntitySimulation
|
|
void simulate(const quint64& now);
|
|
void simulateKinematicMotion(float timeElapsed, bool setFlags=true);
|
|
|
|
virtual bool needsToCallUpdate() const { return false; }
|
|
|
|
virtual void debugDump() const;
|
|
|
|
virtual bool supportsDetailedRayIntersection() const { return false; }
|
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
|
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
|
void** intersectedObject, bool precisionPicking) const { return true; }
|
|
|
|
// attributes applicable to all entity types
|
|
EntityTypes::EntityType getType() const { return _type; }
|
|
|
|
inline glm::vec3 getCenterPosition() const { return getTransformToCenter().getTranslation(); }
|
|
void setCenterPosition(const glm::vec3& position);
|
|
|
|
const Transform getTransformToCenter() const;
|
|
void setTranformToCenter(const Transform& transform);
|
|
|
|
inline const Transform& getTransform() const { return _transform; }
|
|
inline void setTransform(const Transform& transform) { _transform = transform; }
|
|
|
|
/// Position in meters (0.0 - TREE_SCALE)
|
|
inline const glm::vec3& getPosition() const { return _transform.getTranslation(); }
|
|
inline void setPosition(const glm::vec3& value) { _transform.setTranslation(value); }
|
|
|
|
inline const glm::quat& getRotation() const { return _transform.getRotation(); }
|
|
inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); }
|
|
|
|
// Hyperlink related getters and setters
|
|
QString getHref() const { return _href; }
|
|
void setHref(QString value) { _href = value; }
|
|
|
|
QString getDescription() const { return _description; }
|
|
void setDescription(QString value) { _description = value; }
|
|
|
|
/// Dimensions in meters (0.0 - TREE_SCALE)
|
|
inline const glm::vec3& getDimensions() const { return _transform.getScale(); }
|
|
virtual void setDimensions(const glm::vec3& value);
|
|
|
|
float getGlowLevel() const { return _glowLevel; }
|
|
void setGlowLevel(float glowLevel) { _glowLevel = glowLevel; }
|
|
|
|
float getLocalRenderAlpha() const { return _localRenderAlpha; }
|
|
void setLocalRenderAlpha(float localRenderAlpha) { _localRenderAlpha = localRenderAlpha; }
|
|
|
|
void setDensity(float density);
|
|
float computeMass() const;
|
|
void setMass(float mass);
|
|
|
|
float getDensity() const { return _density; }
|
|
|
|
const glm::vec3& getVelocity() const { return _velocity; } /// get velocity in meters
|
|
void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in meters
|
|
bool hasVelocity() const { return _velocity != ENTITY_ITEM_ZERO_VEC3; }
|
|
|
|
const glm::vec3& getGravity() const { return _gravity; } /// get gravity in meters
|
|
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in meters
|
|
bool hasGravity() const { return _gravity != ENTITY_ITEM_ZERO_VEC3; }
|
|
|
|
const glm::vec3& getAcceleration() const { return _acceleration; } /// get acceleration in meters/second/second
|
|
void setAcceleration(const glm::vec3& value) { _acceleration = value; } /// acceleration in meters/second/second
|
|
bool hasAcceleration() const { return _acceleration != ENTITY_ITEM_ZERO_VEC3; }
|
|
|
|
float getDamping() const { return _damping; }
|
|
void setDamping(float value) { _damping = value; }
|
|
|
|
float getRestitution() const { return _restitution; }
|
|
void setRestitution(float value);
|
|
|
|
float getFriction() const { return _friction; }
|
|
void setFriction(float value);
|
|
|
|
// lifetime related properties.
|
|
float getLifetime() const { return _lifetime; } /// get the lifetime in seconds for the entity
|
|
void setLifetime(float value) { _lifetime = value; } /// set the lifetime in seconds for the entity
|
|
|
|
quint64 getCreated() const { return _created; } /// get the created-time in useconds for the entity
|
|
void setCreated(quint64 value) { _created = value; } /// set the created-time in useconds for the entity
|
|
|
|
/// is this entity immortal, in that it has no lifetime set, and will exist until manually deleted
|
|
bool isImmortal() const { return _lifetime == ENTITY_ITEM_IMMORTAL_LIFETIME; }
|
|
|
|
/// is this entity mortal, in that it has a lifetime set, and will automatically be deleted when that lifetime expires
|
|
bool isMortal() const { return _lifetime != ENTITY_ITEM_IMMORTAL_LIFETIME; }
|
|
|
|
/// age of this entity in seconds
|
|
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
|
bool lifetimeHasExpired() const;
|
|
quint64 getExpiry() const;
|
|
|
|
// position, size, and bounds related helpers
|
|
AACube getMaximumAACube() const;
|
|
AACube getMinimumAACube() const;
|
|
AABox getAABox() const; /// axis aligned bounding box in world-frame (meters)
|
|
|
|
const QString& getScript() const { return _script; }
|
|
void setScript(const QString& value) { _script = value; }
|
|
|
|
quint64 getScriptTimestamp() const { return _scriptTimestamp; }
|
|
void setScriptTimestamp(const quint64 value) { _scriptTimestamp = value; }
|
|
|
|
const QString& getCollisionSoundURL() const { return _collisionSoundURL; }
|
|
void setCollisionSoundURL(const QString& value) { _collisionSoundURL = value; }
|
|
|
|
const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } /// registration point as ratio of entity
|
|
|
|
/// registration point as ratio of entity
|
|
void setRegistrationPoint(const glm::vec3& value)
|
|
{ _registrationPoint = glm::clamp(value, 0.0f, 1.0f); }
|
|
|
|
const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
|
void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; }
|
|
bool hasAngularVelocity() const { return _angularVelocity != ENTITY_ITEM_ZERO_VEC3; }
|
|
|
|
float getAngularDamping() const { return _angularDamping; }
|
|
void setAngularDamping(float value) { _angularDamping = value; }
|
|
|
|
QString getName() const { return _name; }
|
|
void setName(const QString& value) { _name = value; }
|
|
|
|
bool getVisible() const { return _visible; }
|
|
void setVisible(bool value) { _visible = value; }
|
|
bool isVisible() const { return _visible; }
|
|
bool isInvisible() const { return !_visible; }
|
|
|
|
bool getIgnoreForCollisions() const { return _ignoreForCollisions; }
|
|
void setIgnoreForCollisions(bool value) { _ignoreForCollisions = value; }
|
|
|
|
bool getCollisionsWillMove() const { return _collisionsWillMove; }
|
|
void setCollisionsWillMove(bool value) { _collisionsWillMove = value; }
|
|
|
|
virtual bool shouldBePhysical() const { return !_ignoreForCollisions; }
|
|
|
|
bool getLocked() const { return _locked; }
|
|
void setLocked(bool value) { _locked = value; }
|
|
|
|
const QString& getUserData() const { return _userData; }
|
|
void setUserData(const QString& value) { _userData = value; }
|
|
|
|
const SimulationOwner& getSimulationOwner() const { return _simulationOwner; }
|
|
void setSimulationOwner(const QUuid& id, quint8 priority);
|
|
void setSimulationOwner(const SimulationOwner& owner);
|
|
void promoteSimulationPriority(quint8 priority);
|
|
|
|
quint8 getSimulationPriority() const { return _simulationOwner.getPriority(); }
|
|
QUuid getSimulatorID() const { return _simulationOwner.getID(); }
|
|
void updateSimulatorID(const QUuid& value);
|
|
void clearSimulationOwnership();
|
|
|
|
const QString& getMarketplaceID() const { return _marketplaceID; }
|
|
void setMarketplaceID(const QString& value) { _marketplaceID = value; }
|
|
|
|
// TODO: get rid of users of getRadius()...
|
|
float getRadius() const;
|
|
|
|
virtual bool contains(const glm::vec3& point) const;
|
|
|
|
virtual bool isReadyToComputeShape() { return true; }
|
|
virtual void computeShapeInfo(ShapeInfo& info);
|
|
virtual float getVolumeEstimate() const { return getDimensions().x * getDimensions().y * getDimensions().z; }
|
|
|
|
/// return preferred shape type (actual physical shape may differ)
|
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
|
|
|
// updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags
|
|
void updatePosition(const glm::vec3& value);
|
|
void updateDimensions(const glm::vec3& value);
|
|
void updateRotation(const glm::quat& rotation);
|
|
void updateDensity(float value);
|
|
void updateMass(float value);
|
|
void updateVelocity(const glm::vec3& value);
|
|
void updateDamping(float value);
|
|
void updateRestitution(float value);
|
|
void updateFriction(float value);
|
|
void updateGravity(const glm::vec3& value);
|
|
void updateAngularVelocity(const glm::vec3& value);
|
|
void updateAngularDamping(float value);
|
|
void updateIgnoreForCollisions(bool value);
|
|
void updateCollisionsWillMove(bool value);
|
|
void updateLifetime(float value);
|
|
void updateCreated(uint64_t value);
|
|
virtual void updateShapeType(ShapeType type) { /* do nothing */ }
|
|
|
|
uint32_t getDirtyFlags() const { return _dirtyFlags; }
|
|
void clearDirtyFlags(uint32_t mask = 0xffffffff) { _dirtyFlags &= ~mask; }
|
|
|
|
bool isMoving() const;
|
|
|
|
void* getPhysicsInfo() const { return _physicsInfo; }
|
|
|
|
void setPhysicsInfo(void* data) { _physicsInfo = data; }
|
|
EntityTreeElement* getElement() const { return _element; }
|
|
|
|
static void setSendPhysicsUpdates(bool value) { _sendPhysicsUpdates = value; }
|
|
static bool getSendPhysicsUpdates() { return _sendPhysicsUpdates; }
|
|
|
|
glm::mat4 getEntityToWorldMatrix() const;
|
|
glm::mat4 getWorldToEntityMatrix() const;
|
|
glm::vec3 worldToEntity(const glm::vec3& point) const;
|
|
glm::vec3 entityToWorld(const glm::vec3& point) const;
|
|
|
|
quint64 getLastEditedFromRemote() { return _lastEditedFromRemote; }
|
|
|
|
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
|
|
|
|
void flagForOwnership() { _dirtyFlags |= DIRTY_SIMULATOR_OWNERSHIP; }
|
|
|
|
bool addAction(EntitySimulation* simulation, EntityActionPointer action);
|
|
bool updateAction(EntitySimulation* simulation, const QUuid& actionID, const QVariantMap& arguments);
|
|
bool removeAction(EntitySimulation* simulation, const QUuid& actionID);
|
|
bool clearActions(EntitySimulation* simulation);
|
|
void setActionData(QByteArray actionData);
|
|
const QByteArray getActionData() const;
|
|
bool hasActions() { return !_objectActions.empty(); }
|
|
QList<QUuid> getActionIDs() { return _objectActions.keys(); }
|
|
QVariantMap getActionArguments(const QUuid& actionID) const;
|
|
void deserializeActions();
|
|
void setActionDataDirty(bool value) const { _actionDataDirty = value; }
|
|
|
|
protected:
|
|
|
|
const QByteArray getActionDataInternal() const;
|
|
void setActionDataInternal(QByteArray actionData);
|
|
|
|
static bool _sendPhysicsUpdates;
|
|
EntityTypes::EntityType _type;
|
|
QUuid _id;
|
|
quint64 _lastSimulated; // last time this entity called simulate(), this includes velocity, angular velocity,
|
|
// and physics changes
|
|
quint64 _lastUpdated; // last time this entity called update(), this includes animations and non-physics changes
|
|
quint64 _lastEdited; // last official local or remote edit time
|
|
quint64 _lastBroadcast; // the last time we sent an edit packet about this entity
|
|
|
|
quint64 _lastEditedFromRemote; // last time we received and edit from the server
|
|
quint64 _lastEditedFromRemoteInRemoteTime; // last time we received an edit from the server (in server-time-frame)
|
|
quint64 _created;
|
|
quint64 _changedOnServer;
|
|
|
|
Transform _transform;
|
|
float _glowLevel;
|
|
float _localRenderAlpha;
|
|
float _density = ENTITY_ITEM_DEFAULT_DENSITY; // kg/m^3
|
|
// NOTE: _volumeMultiplier is used to allow some mass properties code exist in the EntityItem base class
|
|
// rather than in all of the derived classes. If we ever collapse these classes to one we could do it a
|
|
// different way.
|
|
float _volumeMultiplier = 1.0f;
|
|
glm::vec3 _velocity;
|
|
glm::vec3 _gravity;
|
|
glm::vec3 _acceleration;
|
|
float _damping;
|
|
float _restitution;
|
|
float _friction;
|
|
float _lifetime;
|
|
QString _script;
|
|
quint64 _scriptTimestamp;
|
|
QString _collisionSoundURL;
|
|
glm::vec3 _registrationPoint;
|
|
glm::vec3 _angularVelocity;
|
|
float _angularDamping;
|
|
bool _visible;
|
|
bool _ignoreForCollisions;
|
|
bool _collisionsWillMove;
|
|
bool _locked;
|
|
QString _userData;
|
|
SimulationOwner _simulationOwner;
|
|
QString _marketplaceID;
|
|
QString _name;
|
|
QString _href; //Hyperlink href
|
|
QString _description; //Hyperlink description
|
|
|
|
// NOTE: Damping is applied like this: v *= pow(1 - damping, dt)
|
|
//
|
|
// Hence the damping coefficient must range from 0 (no damping) to 1 (immediate stop).
|
|
// Each damping value relates to a corresponding exponential decay timescale as follows:
|
|
//
|
|
// timescale = -1 / ln(1 - damping)
|
|
//
|
|
// damping = 1 - exp(-1 / timescale)
|
|
//
|
|
|
|
// NOTE: Radius support is obsolete, but these private helper functions are available for this class to
|
|
// parse old data streams
|
|
|
|
/// set radius in domain scale units (0.0 - 1.0) this will also reset dimensions to be equal for each axis
|
|
void setRadius(float value);
|
|
|
|
// DirtyFlags are set whenever a property changes that the EntitySimulation needs to know about.
|
|
uint32_t _dirtyFlags; // things that have changed from EXTERNAL changes (via script or packet) but NOT from simulation
|
|
|
|
// these backpointers are only ever set/cleared by friends:
|
|
EntityTreeElement* _element = nullptr; // set by EntityTreeElement
|
|
void* _physicsInfo = nullptr; // set by EntitySimulation
|
|
bool _simulated; // set by EntitySimulation
|
|
|
|
bool addActionInternal(EntitySimulation* simulation, EntityActionPointer action);
|
|
bool removeActionInternal(const QUuid& actionID, EntitySimulation* simulation = nullptr);
|
|
void deserializeActionsInternal();
|
|
QByteArray serializeActions(bool& success) const;
|
|
QHash<QUuid, EntityActionPointer> _objectActions;
|
|
|
|
static int _maxActionsDataSize;
|
|
mutable QByteArray _allActionsDataCache;
|
|
// when an entity-server starts up, EntityItem::setActionData is called before the entity-tree is
|
|
// ready. This means we can't find our EntityItemPointer or add the action to the simulation. These
|
|
// are used to keep track of and work around this situation.
|
|
void checkWaitingToRemove(EntitySimulation* simulation = nullptr);
|
|
mutable QSet<QUuid> _actionsToRemove;
|
|
mutable bool _actionDataDirty = false;
|
|
|
|
mutable QReadWriteLock _lock;
|
|
void lockForRead() const;
|
|
bool tryLockForRead() const;
|
|
void lockForWrite() const;
|
|
bool tryLockForWrite() const;
|
|
void unlock() const;
|
|
bool isLocked() const;
|
|
bool isWriteLocked() const;
|
|
bool isUnlocked() const;
|
|
};
|
|
|
|
#endif // hifi_EntityItem_h
|