mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 19:50:38 +02:00
partial progress toward sim ownership negotiations
works well for just a few objects but fails for piles committing some debug stuff that will have to be torn out later
This commit is contained in:
parent
c87e7c99ce
commit
cf74dbe1dc
12 changed files with 319 additions and 91 deletions
|
@ -148,10 +148,6 @@ QUuid AvatarMotionState::getSimulatorID() const {
|
||||||
return _avatar->getSessionUUID();
|
return _avatar->getSessionUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
|
||||||
void AvatarMotionState::bump() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
int16_t AvatarMotionState::computeCollisionGroup() {
|
int16_t AvatarMotionState::computeCollisionGroup() {
|
||||||
return COLLISION_GROUP_OTHER_AVATAR;
|
return COLLISION_GROUP_OTHER_AVATAR;
|
||||||
|
|
|
@ -55,7 +55,6 @@ public:
|
||||||
virtual const QUuid& getObjectID() const;
|
virtual const QUuid& getObjectID() const;
|
||||||
|
|
||||||
virtual QUuid getSimulatorID() const;
|
virtual QUuid getSimulatorID() const;
|
||||||
virtual void bump();
|
|
||||||
|
|
||||||
void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal);
|
void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
#include "EntitySimulation.h"
|
#include "EntitySimulation.h"
|
||||||
|
|
||||||
|
const char* plankyBlock2 = "PlankyBlock46"; // adebug
|
||||||
|
|
||||||
const quint64 DEFAULT_SIMULATOR_CHANGE_LOCKOUT_PERIOD = (quint64)(0.2f * USECS_PER_SECOND);
|
const quint64 DEFAULT_SIMULATOR_CHANGE_LOCKOUT_PERIOD = (quint64)(0.2f * USECS_PER_SECOND);
|
||||||
const quint64 MAX_SIMULATOR_CHANGE_LOCKOUT_PERIOD = 2 * USECS_PER_SECOND;
|
const quint64 MAX_SIMULATOR_CHANGE_LOCKOUT_PERIOD = 2 * USECS_PER_SECOND;
|
||||||
|
|
||||||
|
@ -581,11 +583,13 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
// rules that we expect the server to be using, so it is possible that we'll sometimes ignore
|
// rules that we expect the server to be using, so it is possible that we'll sometimes ignore
|
||||||
// the incoming _simulatorID data (e.g. we might know something that the server does not... yet).
|
// the incoming _simulatorID data (e.g. we might know something that the server does not... yet).
|
||||||
|
|
||||||
|
int requiredProperties = 1; // adebug
|
||||||
uint8_t priority = 0;
|
uint8_t priority = 0;
|
||||||
if (propertyFlags.getHasProperty(PROP_SIMULATOR_PRIORITY)) {
|
if (propertyFlags.getHasProperty(PROP_SIMULATOR_PRIORITY)) {
|
||||||
int bytes = OctreePacketData::unpackDataFromBytes(dataAt, priority);
|
int bytes = OctreePacketData::unpackDataFromBytes(dataAt, priority);
|
||||||
dataAt += bytes;
|
dataAt += bytes;
|
||||||
bytesRead += bytes;
|
bytesRead += bytes;
|
||||||
|
requiredProperties *= 3; // adebug
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid id;
|
QUuid id;
|
||||||
|
@ -593,32 +597,66 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
int bytes = OctreePacketData::unpackDataFromBytes(dataAt, id);
|
int bytes = OctreePacketData::unpackDataFromBytes(dataAt, id);
|
||||||
dataAt += bytes;
|
dataAt += bytes;
|
||||||
bytesRead += bytes;
|
bytesRead += bytes;
|
||||||
|
requiredProperties *= 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_simulatorID != id) {
|
// adebug
|
||||||
// ownership has changed
|
if (requiredProperties == 3) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
std::cout << "adebug split properties for '" << _name.toStdString() << "' with priority only" << std::endl; // adebug
|
||||||
if (_simulatorID == nodeList->getSessionUUID()) {
|
}
|
||||||
// we think we're the simulation owner but entity-server says otherwise
|
else if (requiredProperties == 7) {
|
||||||
// we relenquish ownership only if we don't have MAX_SIMULATOR_PRIORITY
|
std::cout << "adebug split properties for '" << _name.toStdString() << "' with id only" << std::endl; // adebug
|
||||||
if (_simulatorPriority != MAX_SIMULATOR_PRIORITY) {
|
}
|
||||||
// we're losing simulation ownership
|
|
||||||
|
// TODO: refactor simulation ownership info to be a single property
|
||||||
|
if (requiredProperties == 3*7) {
|
||||||
|
if (_simulatorID != id) {
|
||||||
|
// ownership has changed
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
if (_simulatorID == nodeList->getSessionUUID()) {
|
||||||
|
// we think we're the simulation owner but entity-server says otherwise
|
||||||
|
// we relenquish ownership only if we don't have MAX_SIMULATOR_PRIORITY
|
||||||
|
if (_simulatorPriority != MAX_SIMULATOR_PRIORITY) {
|
||||||
|
// we're losing simulation ownership
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug lose ownership of '" << _name.toStdString() << "' to " << id.toString().toStdString() << " with priority " << int(priority) << std::endl; // adebug
|
||||||
|
}
|
||||||
|
_simulatorID = id;
|
||||||
|
_simulatorPriority = priority;
|
||||||
|
if (! (_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID)) {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug setting DIRTY_SIMULATOR_ID while losing ownership" << std::endl; // adebug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
if (id == nodeList->getSessionUUID()) {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug gain ownership of '" << _name.toStdString() << "' id " << id.toString().toStdString() << " with priority " << int(priority) << std::endl; // adebug
|
||||||
|
}
|
||||||
|
}
|
||||||
_simulatorID = id;
|
_simulatorID = id;
|
||||||
_simulatorPriority = priority;
|
_simulatorPriority = priority;
|
||||||
|
if (! (_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID)) {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug setting DIRTY_SIMULATOR_ID with ownership of " << _simulatorID.toString().toStdString() << std::endl; // adebug
|
||||||
|
}
|
||||||
|
}
|
||||||
_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID;
|
_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (priority != _simulatorPriority) {
|
||||||
_simulatorID = id;
|
// priority is changing but simulatorID is not.
|
||||||
_simulatorPriority = priority;
|
// only accept this change if we are NOT the simulator owner, since otherwise
|
||||||
_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID;
|
// we would have initiated this priority
|
||||||
}
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
} else if (priority != _simulatorPriority) {
|
if (_simulatorID != nodeList->getSessionUUID()) {
|
||||||
// priority is changing but simulatorID is not.
|
if (_name == plankyBlock2) {
|
||||||
// only accept this change if we are NOT the simulator owner, since otherwise
|
std::cout << "adebug priority of '" << _name.toStdString() << "' changing from " << int(_simulatorPriority) << " to " << int(priority) << std::endl; // adebug
|
||||||
// we would have initiated this priority
|
}
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
_simulatorPriority = priority;
|
||||||
if (_simulatorID != nodeList->getSessionUUID()) {
|
}
|
||||||
_simulatorPriority = priority;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_ACCELERATION) {
|
} else if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_ACCELERATION) {
|
||||||
|
@ -904,6 +942,11 @@ void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityItem::clearDirtyFlags(uint32_t mask) {
|
||||||
|
// adebug TODO: move this back to header after done debugging
|
||||||
|
_dirtyFlags &= ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
bool EntityItem::isMoving() const {
|
bool EntityItem::isMoving() const {
|
||||||
return hasVelocity() || hasAngularVelocity();
|
return hasVelocity() || hasAngularVelocity();
|
||||||
}
|
}
|
||||||
|
@ -1039,6 +1082,9 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(description, setDescription);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(description, setDescription);
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug update for '" << _name.toStdString() << "'" << std::endl; // adebug
|
||||||
|
}
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
int elapsed = now - getLastEdited();
|
int elapsed = now - getLastEdited();
|
||||||
|
@ -1398,6 +1444,9 @@ void EntityItem::updateCreated(uint64_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::setSimulatorPriority(uint8_t priority) {
|
void EntityItem::setSimulatorPriority(uint8_t priority) {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug setSimulatorPriority() for '" << _name.toStdString() << "' from " << int(_simulatorPriority) << " to " << int(priority) << std::endl; // adebug
|
||||||
|
}
|
||||||
_simulatorPriority = priority;
|
_simulatorPriority = priority;
|
||||||
if (_simulatorPriority == MAX_SIMULATOR_PRIORITY) {
|
if (_simulatorPriority == MAX_SIMULATOR_PRIORITY) {
|
||||||
// we always extend the the ownership expiry for MAX_SIMULATOR_PRIORITY
|
// we always extend the the ownership expiry for MAX_SIMULATOR_PRIORITY
|
||||||
|
@ -1409,6 +1458,9 @@ void EntityItem::setSimulatorPriority(uint8_t priority) {
|
||||||
|
|
||||||
void EntityItem::setSimulatorID(const QUuid& value) {
|
void EntityItem::setSimulatorID(const QUuid& value) {
|
||||||
if (_simulatorID != value) {
|
if (_simulatorID != value) {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug setSimulatorID for '" << _name.toStdString() << "' from " << _simulatorID.toString().toStdString() << " to " << value.toString().toStdString() << std::endl; // adebug
|
||||||
|
}
|
||||||
_simulatorID = value;
|
_simulatorID = value;
|
||||||
if (!_simulatorID.isNull()) {
|
if (!_simulatorID.isNull()) {
|
||||||
// Note: this logic only works well if _simulatorPriority is properly set before this point
|
// Note: this logic only works well if _simulatorPriority is properly set before this point
|
||||||
|
@ -1421,6 +1473,9 @@ void EntityItem::setSimulatorID(const QUuid& value) {
|
||||||
|
|
||||||
void EntityItem::updateSimulatorID(const QUuid& value) {
|
void EntityItem::updateSimulatorID(const QUuid& value) {
|
||||||
if (_simulatorID != value) {
|
if (_simulatorID != value) {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug updateSimulatorID for '" << _name.toStdString() << "' from " << _simulatorID.toString().toStdString() << " to " << value.toString().toStdString() << std::endl; // adebug
|
||||||
|
}
|
||||||
_simulatorID = value;
|
_simulatorID = value;
|
||||||
if (!_simulatorID.isNull()) {
|
if (!_simulatorID.isNull()) {
|
||||||
// Note: this logic only works well if _simulatorPriority is properly set before this point
|
// Note: this logic only works well if _simulatorPriority is properly set before this point
|
||||||
|
@ -1433,6 +1488,9 @@ void EntityItem::updateSimulatorID(const QUuid& value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::clearSimulationOwnership() {
|
void EntityItem::clearSimulationOwnership() {
|
||||||
|
if (_name == plankyBlock2) {
|
||||||
|
std::cout << "adebug clearSimulationOwnership for '" << _name.toStdString() << "'" << std::endl; // adebug
|
||||||
|
}
|
||||||
_simulatorPriority = 0;
|
_simulatorPriority = 0;
|
||||||
_simulatorID = QUuid();
|
_simulatorID = QUuid();
|
||||||
_simulationOwnershipExpiry = 0;
|
_simulationOwnershipExpiry = 0;
|
||||||
|
|
|
@ -72,6 +72,28 @@ const uint8_t ATTACHMENT_SIMULATOR_PRIORITY = MAX_SIMULATOR_PRIORITY;
|
||||||
#define debugTimeOnly(T) qPrintable(QString("%1").arg(T, 16, 10))
|
#define debugTimeOnly(T) qPrintable(QString("%1").arg(T, 16, 10))
|
||||||
#define debugTreeVector(V) V << "[" << V << " in meters ]"
|
#define debugTreeVector(V) V << "[" << V << " in meters ]"
|
||||||
|
|
||||||
|
class SimulationOwner {
|
||||||
|
public:
|
||||||
|
SimulationOwner() : _id(), _priority(0) {}
|
||||||
|
SimulationOwner(const QUuid& id, uint8_t priority) : _id(id), _priority(priority) {}
|
||||||
|
|
||||||
|
const QUuid& getID() const { return _id; }
|
||||||
|
uint8_t getPriority() const { return _priority; }
|
||||||
|
|
||||||
|
void clear() { _id = QUuid(); _priority = 0; }
|
||||||
|
void set(const QUuid& id, uint8_t priority) { _id = id; _priority = priority; }
|
||||||
|
|
||||||
|
bool isNull() const { return _id.isNull(); }
|
||||||
|
bool matchesID(const QUuid& id) const { return _id == id; }
|
||||||
|
//void toQByteArray();
|
||||||
|
|
||||||
|
bool operator>=(uint8_t priority) const { return _priority >= priority; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUuid _id;
|
||||||
|
uint8_t _priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
/// 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
|
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
||||||
|
@ -367,7 +389,8 @@ public:
|
||||||
virtual void updateShapeType(ShapeType type) { /* do nothing */ }
|
virtual void updateShapeType(ShapeType type) { /* do nothing */ }
|
||||||
|
|
||||||
uint32_t getDirtyFlags() const { return _dirtyFlags; }
|
uint32_t getDirtyFlags() const { return _dirtyFlags; }
|
||||||
void clearDirtyFlags(uint32_t mask = 0xffffffff) { _dirtyFlags &= ~mask; }
|
//void clearDirtyFlags(uint32_t mask = 0xffffffff) { _dirtyFlags &= ~mask; }
|
||||||
|
void clearDirtyFlags(uint32_t mask = 0xffffffff);
|
||||||
|
|
||||||
bool isMoving() const;
|
bool isMoving() const;
|
||||||
|
|
||||||
|
|
|
@ -325,6 +325,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCKED, locked);
|
CHECK_PROPERTY_CHANGE(PROP_LOCKED, locked);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_TEXTURES, textures);
|
CHECK_PROPERTY_CHANGE(PROP_TEXTURES, textures);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_USER_DATA, userData);
|
CHECK_PROPERTY_CHANGE(PROP_USER_DATA, userData);
|
||||||
|
// TODO: combine these as one property
|
||||||
CHECK_PROPERTY_CHANGE(PROP_SIMULATOR_PRIORITY, simulatorPriority);
|
CHECK_PROPERTY_CHANGE(PROP_SIMULATOR_PRIORITY, simulatorPriority);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_SIMULATOR_ID, simulatorID);
|
CHECK_PROPERTY_CHANGE(PROP_SIMULATOR_ID, simulatorID);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_TEXT, text);
|
CHECK_PROPERTY_CHANGE(PROP_TEXT, text);
|
||||||
|
@ -709,6 +710,42 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
// PROP_PAGED_PROPERTY,
|
// PROP_PAGED_PROPERTY,
|
||||||
// PROP_CUSTOM_PROPERTIES_INCLUDED,
|
// PROP_CUSTOM_PROPERTIES_INCLUDED,
|
||||||
|
|
||||||
|
/* TODO: remove this old experiment code
|
||||||
|
// simulation ownership data needs to get back ASAP, and affects whether the "terse update"
|
||||||
|
// data will be accepted at the receiving end, so we put it at the front.
|
||||||
|
// if (requestedProperties.getHasProperty(PROP_SIMULATOR_PRIORITY) &&
|
||||||
|
// requestedProperties.getHasProperty(PROP_SIMULATOR_ID)) {
|
||||||
|
// QByteArray ownershipData = properties.getSimulatorID().toRfc4122();
|
||||||
|
// ownershipData.append(properties.getSimulatorPriority();
|
||||||
|
// LevelDetails propertyLevel = packetData->startLevel();
|
||||||
|
// if (packetData->appendRawData(ownershipData)) {
|
||||||
|
// propertyFlags |= PROP_SIMULATOR_PRIORITY;
|
||||||
|
// propertiesDidntFit -= PROP_SIMULATOR_PRIORITY;
|
||||||
|
// propertyCount++;
|
||||||
|
//
|
||||||
|
// propertyFlags |= PROP_SIMULATOR_ID;
|
||||||
|
// propertiesDidntFit -= PROP_SIMULATOR_ID;
|
||||||
|
// propertyCount++;
|
||||||
|
//
|
||||||
|
// packetData->endLevel(propertyLevel);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// BOOKMARK -- replace the two ownership properties with one... at the EntityProperties level
|
||||||
|
// but make it two properties at the EntityItem
|
||||||
|
if (requestedProperties.getHasProperty(PROP_SIMULATOR_OWNERSHIP)) {
|
||||||
|
QByteArray ownershipData = properties.getSimulatorID().toRfc4122();
|
||||||
|
ownershipData.append(properties.getSimulatorPriority();
|
||||||
|
LevelDetails propertyLevel = packetData->startLevel();
|
||||||
|
if (packetData->appendRawData(ownershipData)) {
|
||||||
|
propertyFlags |= PROP_SIMULATOR_OWNERSHIP;
|
||||||
|
propertyCount++;
|
||||||
|
packetData->endLevel(propertyLevel);
|
||||||
|
} else {
|
||||||
|
propertiesDidntFit -= PROP_SIMULATOR_OWNERSHIP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_POSITION, properties.getPosition());
|
APPEND_ENTITY_PROPERTY(PROP_POSITION, properties.getPosition());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, properties.getDimensions()); // NOTE: PROP_RADIUS obsolete
|
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, properties.getDimensions()); // NOTE: PROP_RADIUS obsolete
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ROTATION, properties.getRotation());
|
APPEND_ENTITY_PROPERTY(PROP_ROTATION, properties.getRotation());
|
||||||
|
@ -733,6 +770,64 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData());
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_PRIORITY, properties.getSimulatorPriority());
|
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_PRIORITY, properties.getSimulatorPriority());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, properties.getSimulatorID());
|
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, properties.getSimulatorID());
|
||||||
|
/* TODO remove this experiment too
|
||||||
|
if (requestedProperties.getHasProperty(PROP_SIMULATOR_PRIORITY) &&
|
||||||
|
requestedProperties.getHasProperty(PROP_SIMULATOR_ID)) {
|
||||||
|
|
||||||
|
QByteArray bytes = properties.getSimulatorID().toRfc4122();
|
||||||
|
if (packetData->canAppendBytes(1 + bytes.size())) {
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_PRIORITY, properties.getSimulatorPriority());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, properties.getSimulatorID());
|
||||||
|
} else {
|
||||||
|
LevelDetails propertyLevel = packetData->startLevel();
|
||||||
|
successPropertyFits = false;
|
||||||
|
packetData->discardLevel(propertyLevel);
|
||||||
|
appendState = OctreeElement::PARTIAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!requestedProperties.getHasProperty(PROP_SIMULATOR_PRIORITY)) {
|
||||||
|
propertiesDidntFit -= PROP_SIMULATOR_PRIORITY;
|
||||||
|
}
|
||||||
|
if (!requestedProperties.getHasProperty(PROP_SIMULATOR_ID)) {
|
||||||
|
propertiesDidntFit -= PROP_SIMULATOR_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/* and this one
|
||||||
|
//#define APPEND_ENTITY_PROPERTY(P,V)
|
||||||
|
if (requestedProperties.getHasProperty(PROP_SIMULATOR_PRIORITY) &&
|
||||||
|
requestedProperties.getHasProperty(PROP_SIMULATOR_ID)) {
|
||||||
|
|
||||||
|
LevelDetails propertyLevel = packetData->startLevel();
|
||||||
|
|
||||||
|
QByteArray bytes = properties.getSimulatorID().toRfc4122();
|
||||||
|
if (packetData->canAppendBytes(10 + bytes.size())) {
|
||||||
|
packetData->appendValue(properties.getSimulatorPriority());
|
||||||
|
propertyFlags |= PROP_SIMULATOR_PRIORITY;
|
||||||
|
propertiesDidntFit -= PROP_SIMULATOR_PRIORITY;
|
||||||
|
propertyCount++;
|
||||||
|
packetData->endLevel(propertyLevel);
|
||||||
|
|
||||||
|
propertyLevel = packetData->startLevel();
|
||||||
|
packetData->appendValue(properties.getSimulatorID());
|
||||||
|
propertyFlags |= PROP_SIMULATOR_ID;
|
||||||
|
propertiesDidntFit -= PROP_SIMULATOR_ID;
|
||||||
|
propertyCount++;
|
||||||
|
packetData->endLevel(propertyLevel);
|
||||||
|
} else {
|
||||||
|
successPropertyFits = false;
|
||||||
|
packetData->discardLevel(propertyLevel);
|
||||||
|
appendState = OctreeElement::PARTIAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!requestedProperties.getHasProperty(PROP_SIMULATOR_PRIORITY)) {
|
||||||
|
propertiesDidntFit -= PROP_SIMULATOR_PRIORITY;
|
||||||
|
}
|
||||||
|
if (!requestedProperties.getHasProperty(PROP_SIMULATOR_ID)) {
|
||||||
|
propertiesDidntFit -= PROP_SIMULATOR_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
APPEND_ENTITY_PROPERTY(PROP_HREF, properties.getHref());
|
APPEND_ENTITY_PROPERTY(PROP_HREF, properties.getHref());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, properties.getDescription());
|
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, properties.getDescription());
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
|
||||||
uint32_t newFlags = entity->getDirtyFlags() & ~preFlags;
|
uint32_t newFlags = entity->getDirtyFlags() & ~preFlags;
|
||||||
if (newFlags) {
|
if (newFlags) {
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
|
std::cout << "adebug newFlags & DIRTY_SIMULATION_FLAGS = 0x" << std::hex << (newFlags & DIRTY_SIMULATION_FLAGS) << std::dec << std::endl; // adebug
|
||||||
if (newFlags & DIRTY_SIMULATION_FLAGS) {
|
if (newFlags & DIRTY_SIMULATION_FLAGS) {
|
||||||
_simulation->lock();
|
_simulation->lock();
|
||||||
_simulation->changeEntity(entity);
|
_simulation->changeEntity(entity);
|
||||||
|
|
|
@ -188,6 +188,8 @@ public:
|
||||||
bool appendRawData(const unsigned char* data, int length);
|
bool appendRawData(const unsigned char* data, int length);
|
||||||
bool appendRawData(QByteArray data);
|
bool appendRawData(QByteArray data);
|
||||||
|
|
||||||
|
bool canAppendBytes(int numBytes) const { return _bytesAvailable > numBytes; }
|
||||||
|
|
||||||
/// returns a byte offset from beginning of the uncompressed stream based on offset from end.
|
/// returns a byte offset from beginning of the uncompressed stream based on offset from end.
|
||||||
/// Positive offsetFromEnd returns that many bytes before the end of uncompressed stream
|
/// Positive offsetFromEnd returns that many bytes before the end of uncompressed stream
|
||||||
int getUncompressedByteOffset(int offsetFromEnd = 0) const { return _bytesInUse - offsetFromEnd; }
|
int getUncompressedByteOffset(int offsetFromEnd = 0) const { return _bytesInUse - offsetFromEnd; }
|
||||||
|
|
|
@ -22,12 +22,14 @@
|
||||||
#ifdef WANT_DEBUG_ENTITY_TREE_LOCKS
|
#ifdef WANT_DEBUG_ENTITY_TREE_LOCKS
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
#endif
|
#endif
|
||||||
|
const char* plankyBlock = "PlankyBlock46"; // adebug
|
||||||
|
|
||||||
static const float ACCELERATION_EQUIVALENT_EPSILON_RATIO = 0.1f;
|
static const float ACCELERATION_EQUIVALENT_EPSILON_RATIO = 0.1f;
|
||||||
static const quint8 STEPS_TO_DECIDE_BALLISTIC = 4;
|
static const quint8 STEPS_TO_DECIDE_BALLISTIC = 4;
|
||||||
|
|
||||||
const uint32_t LOOPS_FOR_SIMULATION_ORPHAN = 50;
|
const uint32_t LOOPS_FOR_SIMULATION_ORPHAN = 50;
|
||||||
const uint32_t LOOPS_BETWEEN_OWNERSHIP_BIDS = 30;
|
//const uint32_t LOOPS_BETWEEN_OWNERSHIP_BIDS = 30;
|
||||||
|
const quint64 USECS_BETWEEN_OWNERSHIP_BIDS = USECS_PER_SECOND / 5;
|
||||||
|
|
||||||
#ifdef WANT_DEBUG_ENTITY_TREE_LOCKS
|
#ifdef WANT_DEBUG_ENTITY_TREE_LOCKS
|
||||||
bool EntityMotionState::entityTreeIsLocked() const {
|
bool EntityMotionState::entityTreeIsLocked() const {
|
||||||
|
@ -69,8 +71,7 @@ EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItemPointer
|
||||||
_serverGravity(0.0f),
|
_serverGravity(0.0f),
|
||||||
_serverAcceleration(0.0f),
|
_serverAcceleration(0.0f),
|
||||||
_accelerationNearlyGravityCount(0),
|
_accelerationNearlyGravityCount(0),
|
||||||
_candidateForOwnership(false),
|
_nextOwnershipBid(0),
|
||||||
_loopsSinceOwnershipBid(0),
|
|
||||||
_loopsWithoutOwner(0)
|
_loopsWithoutOwner(0)
|
||||||
{
|
{
|
||||||
_type = MOTIONSTATE_TYPE_ENTITY;
|
_type = MOTIONSTATE_TYPE_ENTITY;
|
||||||
|
@ -94,37 +95,55 @@ void EntityMotionState::updateServerPhysicsVariables() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void EntityMotionState::handleEasyChanges(uint32_t flags) {
|
void EntityMotionState::handleEasyChanges(uint32_t flags, PhysicsEngine* engine) {
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
|
quint64 dt = (usecTimestampNow() - _activationTime) / 1000; // adebug
|
||||||
|
std::cout << "adebug handleEasyChanges flags = 0x" << std::hex << flags << std::dec << " dt = " << dt << std::endl; // adebug
|
||||||
|
}
|
||||||
updateServerPhysicsVariables();
|
updateServerPhysicsVariables();
|
||||||
ObjectMotionState::handleEasyChanges(flags);
|
ObjectMotionState::handleEasyChanges(flags, engine);
|
||||||
|
|
||||||
if (flags & EntityItem::DIRTY_SIMULATOR_ID) {
|
if (flags & EntityItem::DIRTY_SIMULATOR_ID) {
|
||||||
_loopsSinceOwnershipBid = 0;
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
|
std::cout << "adebug handleEasyChanges() '" << _entity->getName().toStdString() << "' found DIRTY_SIMULATOR_ID flag" << std::endl; // adebug
|
||||||
|
}
|
||||||
_loopsWithoutOwner = 0;
|
_loopsWithoutOwner = 0;
|
||||||
_candidateForOwnership = false;
|
if (_entity->getSimulatorID().isNull()) {
|
||||||
if (_entity->getSimulatorID().isNull()
|
// simulation ownership is being removed
|
||||||
&& !_entity->isMoving()
|
|
||||||
&& _body->isActive()) {
|
|
||||||
// remove the ACTIVATION flag because this object is coming to rest
|
// remove the ACTIVATION flag because this object is coming to rest
|
||||||
// according to a remote simulation and we don't want to wake it up again
|
// according to a remote simulation and we don't want to wake it up again
|
||||||
flags &= ~EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
flags &= ~EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
||||||
|
// hint to Bullet that the object is deactivating
|
||||||
_body->setActivationState(WANTS_DEACTIVATION);
|
_body->setActivationState(WANTS_DEACTIVATION);
|
||||||
} else {
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
std::cout << "adebug handleEasyChanges() '" << _entity->getName().toStdString() << "' clearing ownership so _candidatePriority goes to 0" << std::endl; // adebug
|
||||||
const QUuid& sessionID = nodeList->getSessionUUID();
|
}
|
||||||
if (_entity->getSimulatorID() != sessionID) {
|
_candidatePriority = 0;
|
||||||
_loopsSinceOwnershipBid = 0;
|
if (_expectedOwnership != -1) {
|
||||||
|
std::cout << "adebug unexpected loss of ownership '" << _entity->getName().toStdString() << "' expected -1 but got " << _expectedOwnership << std::endl; // adebug
|
||||||
|
}
|
||||||
|
_expectedOwnership = 0;
|
||||||
|
} else {
|
||||||
|
_nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS;
|
||||||
|
if (engine->getSessionID() == _entity->getSimulatorID() || _entity->getSimulatorPriority() > _candidatePriority) {
|
||||||
|
// we own the simulation or our priority looses to remote
|
||||||
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
|
std::cout << "adebug handleEasyChanges() '" << _entity->getName().toStdString() << "' we own it so _candidatePriority goes to 0" << std::endl; // adebug
|
||||||
|
}
|
||||||
|
if (_expectedOwnership != 1) {
|
||||||
|
std::cout << "adebug unexpected gain of ownership '" << _entity->getName().toStdString() << "' expected 1 but got " << _expectedOwnership << " _candidatePriority = " << int(_candidatePriority) << std::endl; // adebug
|
||||||
|
}
|
||||||
|
_expectedOwnership = 0;
|
||||||
|
_candidatePriority = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & EntityItem::DIRTY_SIMULATOR_OWNERSHIP) {
|
if (flags & EntityItem::DIRTY_SIMULATOR_OWNERSHIP) {
|
||||||
|
// also known as "bid for ownership with SCRIPT priority"
|
||||||
// we're manipulating this object directly via script, so we artificially
|
// we're manipulating this object directly via script, so we artificially
|
||||||
// manipulate the logic to trigger an immediate bid for ownership
|
// manipulate the logic to trigger an immediate bid for ownership
|
||||||
_candidateForOwnership = true;
|
setSimulatorPriorityHint(SCRIPT_EDIT_SIMULATOR_PRIORITY);
|
||||||
_loopsSinceOwnershipBid = LOOPS_BETWEEN_OWNERSHIP_BIDS;
|
|
||||||
_loopsWithoutOwner = LOOPS_FOR_SIMULATION_ORPHAN;
|
|
||||||
_simulatorPriorityHint = SCRIPT_EDIT_SIMULATOR_PRIORITY;
|
|
||||||
}
|
}
|
||||||
if ((flags & EntityItem::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) {
|
if ((flags & EntityItem::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) {
|
||||||
_body->activate();
|
_body->activate();
|
||||||
|
@ -202,13 +221,14 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||||
if (_entity->getSimulatorID().isNull()) {
|
if (_entity->getSimulatorID().isNull()) {
|
||||||
_loopsWithoutOwner++;
|
_loopsWithoutOwner++;
|
||||||
|
|
||||||
if (_loopsWithoutOwner > LOOPS_FOR_SIMULATION_ORPHAN) {
|
if (_loopsWithoutOwner > LOOPS_FOR_SIMULATION_ORPHAN && usecTimestampNow() > _nextOwnershipBid) {
|
||||||
//qDebug() << "Warning -- claiming something I saw moving." << getName();
|
//qDebug() << "Warning -- claiming something I saw moving." << getName();
|
||||||
_candidateForOwnership = true;
|
quint64 dt = (usecTimestampNow() - _activationTime) / 1000; // adebug
|
||||||
_loopsSinceOwnershipBid = LOOPS_BETWEEN_OWNERSHIP_BIDS + 1;
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
|
std::cout << "adebug setWorldTransform() bid for orphan '" << _entity->getName().toStdString() << "' dt = " << dt << std::endl; // adebug
|
||||||
|
}
|
||||||
|
setSimulatorPriorityHint(VOLUNTEER_SIMULATOR_PRIORITY);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
_loopsWithoutOwner = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
|
@ -239,7 +259,7 @@ bool EntityMotionState::isCandidateForOwnership(const QUuid& sessionID) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
return _candidateForOwnership || sessionID == _entity->getSimulatorID();
|
return _candidatePriority > 0 || sessionID == _entity->getSimulatorID();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
|
@ -356,18 +376,19 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep, const QUuid& s
|
||||||
|
|
||||||
if (_entity->getSimulatorID() != sessionID) {
|
if (_entity->getSimulatorID() != sessionID) {
|
||||||
// we don't own the simulation, but maybe we should...
|
// we don't own the simulation, but maybe we should...
|
||||||
if (_candidateForOwnership) {
|
if (_candidatePriority > 0) {
|
||||||
_candidateForOwnership = false;
|
if (_candidatePriority < _entity->getSimulatorPriority()) {
|
||||||
++_loopsSinceOwnershipBid;
|
// our priority looses to remote, so we don't bother to bid
|
||||||
if (_loopsSinceOwnershipBid > LOOPS_BETWEEN_OWNERSHIP_BIDS) {
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
// it's time to bid for ownership
|
std::cout << "adebug shouldSendUpdate() '" << _entity->getName().toStdString() << "' clear priority " << int(_candidatePriority) << " in favor of remote priority " << int(_entity->getSimulatorPriority()) << std::endl; // adebug
|
||||||
_loopsSinceOwnershipBid = 0;
|
}
|
||||||
return true;
|
_candidatePriority = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return usecTimestampNow() > _nextOwnershipBid;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_candidateForOwnership = false;
|
|
||||||
|
|
||||||
return remoteSimulationOutOfSync(simulationStep);
|
return remoteSimulationOutOfSync(simulationStep);
|
||||||
}
|
}
|
||||||
|
@ -456,15 +477,28 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q
|
||||||
if (!active) {
|
if (!active) {
|
||||||
// we own the simulation but the entity has stopped, so we tell the server that we're clearing simulatorID
|
// we own the simulation but the entity has stopped, so we tell the server that we're clearing simulatorID
|
||||||
// but we remember that we do still own it... and rely on the server to tell us that we don't
|
// but we remember that we do still own it... and rely on the server to tell us that we don't
|
||||||
|
std::cout << "adebug releasing ownership of '" << _entity->getName().toStdString() << "' for inactivity" << std::endl; // adebug
|
||||||
properties.clearSimulatorOwnership();
|
properties.clearSimulatorOwnership();
|
||||||
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
|
std::cout << "adebug sendUpdate() send clear ownership for '" << _entity->getName().toStdString() << "'" << std::endl; // adebug
|
||||||
|
}
|
||||||
|
_expectedOwnership = -1;
|
||||||
} else {
|
} else {
|
||||||
// re-assert the simulation info
|
// re-assert the simulation info
|
||||||
properties.setSimulatorOwnership(sessionID, _entity->getSimulatorPriority());
|
properties.setSimulatorOwnership(sessionID, _entity->getSimulatorPriority());
|
||||||
|
_expectedOwnership = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we don't own the simulation for this entity yet, but we're sending a bid for it
|
// we don't own the simulation for this entity yet, but we're sending a bid for it
|
||||||
properties.setSimulatorOwnership(sessionID, glm::max(_simulatorPriorityHint, VOLUNTEER_SIMULATOR_PRIORITY));
|
quint64 dt = (usecTimestampNow() - _activationTime) / 1000; // adebug
|
||||||
_simulatorPriorityHint = 0;
|
uint8_t bidPriority = glm::max<uint8_t>(_candidatePriority, VOLUNTEER_SIMULATOR_PRIORITY); // adebug
|
||||||
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
|
std::cout << "adebug sendUpdate() bid for ownership of '" << _entity->getName().toStdString() << "' dt = " << dt << " with priority " << int(bidPriority) << std::endl; // adebug
|
||||||
|
}
|
||||||
|
properties.setSimulatorOwnership(sessionID, glm::max<uint8_t>(_candidatePriority, VOLUNTEER_SIMULATOR_PRIORITY));
|
||||||
|
_nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS;
|
||||||
|
_expectedOwnership = 1;
|
||||||
|
//_candidatePriority = 0; // TODO: it would be nice to not have to clear this until we get a message back that ownership has changed
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EntityItem::getSendPhysicsUpdates()) {
|
if (EntityItem::getSendPhysicsUpdates()) {
|
||||||
|
@ -502,6 +536,13 @@ uint32_t EntityMotionState::getAndClearIncomingDirtyFlags() {
|
||||||
return dirtyFlags;
|
return dirtyFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
uint8_t EntityMotionState::getSimulatorPriority() const {
|
||||||
|
if (_entity) {
|
||||||
|
return _entity->getSimulatorPriority();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
QUuid EntityMotionState::getSimulatorID() const {
|
QUuid EntityMotionState::getSimulatorID() const {
|
||||||
|
@ -512,10 +553,13 @@ QUuid EntityMotionState::getSimulatorID() const {
|
||||||
return QUuid();
|
return QUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void EntityMotionState::bump() {
|
void EntityMotionState::bump(uint8_t priority) {
|
||||||
_candidateForOwnership = true;
|
if (_entity) {
|
||||||
|
//uint8_t inheritedPriority = priority < 2 ? 1 : priority - 1;
|
||||||
|
uint8_t inheritedPriority = VOLUNTEER_SIMULATOR_PRIORITY;
|
||||||
|
setSimulatorPriorityHint(inheritedPriority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityMotionState::resetMeasuredBodyAcceleration() {
|
void EntityMotionState::resetMeasuredBodyAcceleration() {
|
||||||
|
@ -543,9 +587,11 @@ void EntityMotionState::measureBodyAcceleration() {
|
||||||
glm::vec3 velocity = bulletToGLM(_body->getLinearVelocity());
|
glm::vec3 velocity = bulletToGLM(_body->getLinearVelocity());
|
||||||
_measuredAcceleration = (velocity / powf(1.0f - _body->getLinearDamping(), dt) - _lastVelocity) * invDt;
|
_measuredAcceleration = (velocity / powf(1.0f - _body->getLinearDamping(), dt) - _lastVelocity) * invDt;
|
||||||
_lastVelocity = velocity;
|
_lastVelocity = velocity;
|
||||||
if (numSubsteps > PHYSICS_ENGINE_MAX_NUM_SUBSTEPS && !_candidateForOwnership) {
|
if (numSubsteps > PHYSICS_ENGINE_MAX_NUM_SUBSTEPS) {
|
||||||
// object has just been re-activated so clear ownership logic
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
_loopsSinceOwnershipBid = 0;
|
std::cout << "adebug measureBodyAcceleration() activate '" << _entity->getName().toStdString() << "'" << std::endl; // adebug
|
||||||
|
}
|
||||||
|
_activationTime = usecTimestampNow(); // adebug
|
||||||
_loopsWithoutOwner = 0;
|
_loopsWithoutOwner = 0;
|
||||||
_lastStep = ObjectMotionState::getWorldSimulationStep();
|
_lastStep = ObjectMotionState::getWorldSimulationStep();
|
||||||
_sentInactive = false;
|
_sentInactive = false;
|
||||||
|
@ -589,6 +635,11 @@ int16_t EntityMotionState::computeCollisionGroup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityMotionState::setSimulatorPriorityHint(uint8_t priority) {
|
void EntityMotionState::setSimulatorPriorityHint(uint8_t priority) {
|
||||||
_candidateForOwnership = true;
|
uint8_t oldPriority = _candidatePriority;
|
||||||
_simulatorPriorityHint = priority;
|
_candidatePriority = glm::max<uint8_t>(_candidatePriority, priority);
|
||||||
|
if (_candidatePriority != oldPriority) {
|
||||||
|
if (_entity && _entity->getName() == plankyBlock) {
|
||||||
|
std::cout << "adebug setSimulatorPriorityHint() '" << _entity->getName().toStdString() << "' _candidatePrioity changed from " << int(oldPriority) << " to " << int(_candidatePriority) << std::endl; // adebug
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
virtual ~EntityMotionState();
|
virtual ~EntityMotionState();
|
||||||
|
|
||||||
void updateServerPhysicsVariables();
|
void updateServerPhysicsVariables();
|
||||||
virtual void handleEasyChanges(uint32_t flags);
|
virtual void handleEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
||||||
virtual void handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
virtual void handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
||||||
|
|
||||||
/// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem
|
/// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem
|
||||||
|
@ -68,8 +68,9 @@ public:
|
||||||
|
|
||||||
virtual const QUuid& getObjectID() const { return _entity->getID(); }
|
virtual const QUuid& getObjectID() const { return _entity->getID(); }
|
||||||
|
|
||||||
|
virtual uint8_t getSimulatorPriority() const;
|
||||||
virtual QUuid getSimulatorID() const;
|
virtual QUuid getSimulatorID() const;
|
||||||
virtual void bump();
|
virtual void bump(uint8_t priority);
|
||||||
|
|
||||||
EntityItemPointer getEntity() const { return _entity; }
|
EntityItemPointer getEntity() const { return _entity; }
|
||||||
|
|
||||||
|
@ -113,10 +114,11 @@ protected:
|
||||||
float _measuredDeltaTime;
|
float _measuredDeltaTime;
|
||||||
|
|
||||||
quint8 _accelerationNearlyGravityCount;
|
quint8 _accelerationNearlyGravityCount;
|
||||||
bool _candidateForOwnership;
|
quint64 _nextOwnershipBid = 0;
|
||||||
uint32_t _loopsSinceOwnershipBid;
|
|
||||||
uint32_t _loopsWithoutOwner;
|
uint32_t _loopsWithoutOwner;
|
||||||
uint8_t _simulatorPriorityHint;
|
uint8_t _candidatePriority = 0;
|
||||||
|
quint64 _activationTime = 0; // adebug
|
||||||
|
int _expectedOwnership = 0; // adebug
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityMotionState_h
|
#endif // hifi_EntityMotionState_h
|
||||||
|
|
|
@ -114,7 +114,7 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectMotionState::handleEasyChanges(uint32_t flags) {
|
void ObjectMotionState::handleEasyChanges(uint32_t flags, PhysicsEngine* engine) {
|
||||||
if (flags & EntityItem::DIRTY_POSITION) {
|
if (flags & EntityItem::DIRTY_POSITION) {
|
||||||
btTransform worldTrans;
|
btTransform worldTrans;
|
||||||
if (flags & EntityItem::DIRTY_ROTATION) {
|
if (flags & EntityItem::DIRTY_ROTATION) {
|
||||||
|
@ -159,7 +159,7 @@ void ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine*
|
||||||
if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) {
|
if ((flags & HARD_DIRTY_PHYSICS_FLAGS) == 0) {
|
||||||
// no HARD flags remain, so do any EASY changes
|
// no HARD flags remain, so do any EASY changes
|
||||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
handleEasyChanges(flags);
|
handleEasyChanges(flags, engine);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ void ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
handleEasyChanges(flags);
|
handleEasyChanges(flags, engine);
|
||||||
}
|
}
|
||||||
// it is possible that there are no HARD flags at this point (if DIRTY_SHAPE was removed)
|
// it is possible that there are no HARD flags at this point (if DIRTY_SHAPE was removed)
|
||||||
// so we check again befoe we reinsert:
|
// so we check again befoe we reinsert:
|
||||||
|
|
|
@ -40,7 +40,8 @@ enum MotionStateType {
|
||||||
const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_MOTION_TYPE | EntityItem::DIRTY_SHAPE);
|
const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_MOTION_TYPE | EntityItem::DIRTY_SHAPE);
|
||||||
const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES |
|
const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES |
|
||||||
EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP |
|
EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP |
|
||||||
EntityItem::DIRTY_MATERIAL | EntityItem::DIRTY_SIMULATOR_OWNERSHIP);
|
EntityItem::DIRTY_MATERIAL | EntityItem::DIRTY_SIMULATOR_ID |
|
||||||
|
EntityItem::DIRTY_SIMULATOR_OWNERSHIP);
|
||||||
|
|
||||||
// These are the set of incoming flags that the PhysicsEngine needs to hear about:
|
// These are the set of incoming flags that the PhysicsEngine needs to hear about:
|
||||||
const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS |
|
const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS |
|
||||||
|
@ -70,7 +71,7 @@ public:
|
||||||
ObjectMotionState(btCollisionShape* shape);
|
ObjectMotionState(btCollisionShape* shape);
|
||||||
~ObjectMotionState();
|
~ObjectMotionState();
|
||||||
|
|
||||||
virtual void handleEasyChanges(uint32_t flags);
|
virtual void handleEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
||||||
virtual void handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
virtual void handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
||||||
|
|
||||||
void updateBodyMaterialProperties();
|
void updateBodyMaterialProperties();
|
||||||
|
@ -118,8 +119,9 @@ public:
|
||||||
|
|
||||||
virtual const QUuid& getObjectID() const = 0;
|
virtual const QUuid& getObjectID() const = 0;
|
||||||
|
|
||||||
|
virtual uint8_t getSimulatorPriority() const { return 0; }
|
||||||
virtual QUuid getSimulatorID() const = 0;
|
virtual QUuid getSimulatorID() const = 0;
|
||||||
virtual void bump() = 0;
|
virtual void bump(uint8_t priority) {}
|
||||||
|
|
||||||
virtual QString getName() { return ""; }
|
virtual QString getName() { return ""; }
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ void PhysicsEngine::changeObjects(VectorOfMotionStates& objects) {
|
||||||
if (flags & HARD_DIRTY_PHYSICS_FLAGS) {
|
if (flags & HARD_DIRTY_PHYSICS_FLAGS) {
|
||||||
object->handleHardAndEasyChanges(flags, this);
|
object->handleHardAndEasyChanges(flags, this);
|
||||||
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
} else if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||||
object->handleEasyChanges(flags);
|
object->handleEasyChanges(flags, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,9 +260,6 @@ void PhysicsEngine::stepSimulation() {
|
||||||
|
|
||||||
void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) {
|
void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const btCollisionObject* objectB) {
|
||||||
BT_PROFILE("ownershipInfection");
|
BT_PROFILE("ownershipInfection");
|
||||||
if (_sessionID.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const btCollisionObject* characterObject = _characterController ? _characterController->getCollisionObject() : nullptr;
|
const btCollisionObject* characterObject = _characterController ? _characterController->getCollisionObject() : nullptr;
|
||||||
|
|
||||||
|
@ -272,14 +269,14 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const
|
||||||
if (b && ((a && a->getSimulatorID() == _sessionID && !objectA->isStaticObject()) || (objectA == characterObject))) {
|
if (b && ((a && a->getSimulatorID() == _sessionID && !objectA->isStaticObject()) || (objectA == characterObject))) {
|
||||||
// NOTE: we might own the simulation of a kinematic object (A)
|
// NOTE: we might own the simulation of a kinematic object (A)
|
||||||
// but we don't claim ownership of kinematic objects (B) based on collisions here.
|
// but we don't claim ownership of kinematic objects (B) based on collisions here.
|
||||||
if (!objectB->isStaticOrKinematicObject()) {
|
if (!objectB->isStaticOrKinematicObject() && b->getSimulatorID() != _sessionID) {
|
||||||
b->bump();
|
b->bump(a->getSimulatorPriority());
|
||||||
}
|
}
|
||||||
} else if (a && ((b && b->getSimulatorID() == _sessionID && !objectB->isStaticObject()) || (objectB == characterObject))) {
|
} else if (a && ((b && b->getSimulatorID() == _sessionID && !objectB->isStaticObject()) || (objectB == characterObject))) {
|
||||||
// SIMILARLY: we might own the simulation of a kinematic object (B)
|
// SIMILARLY: we might own the simulation of a kinematic object (B)
|
||||||
// but we don't claim ownership of kinematic objects (A) based on collisions here.
|
// but we don't claim ownership of kinematic objects (A) based on collisions here.
|
||||||
if (!objectA->isStaticOrKinematicObject()) {
|
if (!objectA->isStaticOrKinematicObject() && a->getSimulatorID() != _sessionID) {
|
||||||
a->bump();
|
a->bump(b->getSimulatorPriority());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,7 +308,9 @@ void PhysicsEngine::updateContactMap() {
|
||||||
_contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0));
|
_contactMap[ContactKey(a, b)].update(_numContactFrames, contactManifold->getContactPoint(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
doOwnershipInfection(objectA, objectB);
|
if (!_sessionID.isNull()) {
|
||||||
|
doOwnershipInfection(objectA, objectB);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,7 +401,7 @@ void PhysicsEngine::bump(ObjectMotionState* motionState) {
|
||||||
if (!objectA->isStaticOrKinematicObject()) {
|
if (!objectA->isStaticOrKinematicObject()) {
|
||||||
ObjectMotionState* motionStateA = static_cast<ObjectMotionState*>(objectA->getUserPointer());
|
ObjectMotionState* motionStateA = static_cast<ObjectMotionState*>(objectA->getUserPointer());
|
||||||
if (motionStateA) {
|
if (motionStateA) {
|
||||||
motionStateA->bump();
|
motionStateA->bump(VOLUNTEER_SIMULATOR_PRIORITY);
|
||||||
objectA->setActivationState(ACTIVE_TAG);
|
objectA->setActivationState(ACTIVE_TAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,7 +409,7 @@ void PhysicsEngine::bump(ObjectMotionState* motionState) {
|
||||||
if (!objectB->isStaticOrKinematicObject()) {
|
if (!objectB->isStaticOrKinematicObject()) {
|
||||||
ObjectMotionState* motionStateB = static_cast<ObjectMotionState*>(objectB->getUserPointer());
|
ObjectMotionState* motionStateB = static_cast<ObjectMotionState*>(objectB->getUserPointer());
|
||||||
if (motionStateB) {
|
if (motionStateB) {
|
||||||
motionStateB->bump();
|
motionStateB->bump(VOLUNTEER_SIMULATOR_PRIORITY);
|
||||||
objectB->setActivationState(ACTIVE_TAG);
|
objectB->setActivationState(ACTIVE_TAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue