mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 07:58:59 +02:00
first cut at using erase entity message to delete entities
This commit is contained in:
parent
4bdb8765f5
commit
49e616dd49
15 changed files with 207 additions and 233 deletions
|
@ -78,7 +78,7 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool debugProcessPacket = _myServer->wantsVerboseDebug();
|
bool debugProcessPacket = true;// _myServer->wantsVerboseDebug();
|
||||||
|
|
||||||
if (debugProcessPacket) {
|
if (debugProcessPacket) {
|
||||||
qDebug("OctreeInboundPacketProcessor::processPacket() packetData=%p packetLength=%d", &packet, packet.size());
|
qDebug("OctreeInboundPacketProcessor::processPacket() packetData=%p packetLength=%d", &packet, packet.size());
|
||||||
|
@ -103,7 +103,7 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
|
||||||
quint64 processTime = 0;
|
quint64 processTime = 0;
|
||||||
quint64 lockWaitTime = 0;
|
quint64 lockWaitTime = 0;
|
||||||
|
|
||||||
if (_myServer->wantsDebugReceiving()) {
|
if (debugProcessPacket || _myServer->wantsDebugReceiving()) {
|
||||||
qDebug() << "PROCESSING THREAD: got '" << packetType << "' packet - " << _receivedPacketCount
|
qDebug() << "PROCESSING THREAD: got '" << packetType << "' packet - " << _receivedPacketCount
|
||||||
<< " command from client receivedBytes=" << packet.size()
|
<< " command from client receivedBytes=" << packet.size()
|
||||||
<< " sequence=" << sequence << " transitTime=" << transitTime << " usecs";
|
<< " sequence=" << sequence << " transitTime=" << transitTime << " usecs";
|
||||||
|
@ -126,6 +126,12 @@ void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendin
|
||||||
reinterpret_cast<const unsigned char*>(packet.data()),
|
reinterpret_cast<const unsigned char*>(packet.data()),
|
||||||
packet.size(),
|
packet.size(),
|
||||||
editData, maxSize, sendingNode);
|
editData, maxSize, sendingNode);
|
||||||
|
|
||||||
|
if (debugProcessPacket) {
|
||||||
|
qDebug() << "OctreeInboundPacketProcessor::processPacket() after processEditPacketData()..."
|
||||||
|
<< "editDataBytesRead=" << editDataBytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
_myServer->getOctree()->unlock();
|
_myServer->getOctree()->unlock();
|
||||||
quint64 endProcess = usecTimestampNow();
|
quint64 endProcess = usecTimestampNow();
|
||||||
|
|
||||||
|
|
|
@ -17,32 +17,10 @@
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
|
|
||||||
|
|
||||||
void EntityEditPacketSender::sendEditEntityMessage(PacketType type, EntityItemID modelID, const EntityItemProperties& properties) {
|
|
||||||
// allows app to disable sending if for example voxels have been disabled
|
|
||||||
if (!_shouldSend) {
|
|
||||||
return; // bail early
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char bufferOut[MAX_PACKET_SIZE];
|
|
||||||
int sizeOut = 0;
|
|
||||||
|
|
||||||
// This encodes the voxel edit message into a buffer...
|
|
||||||
if (EntityItemProperties::encodeEntityEditPacket(type, modelID, properties, &bufferOut[0], _maxPacketSize, sizeOut)){
|
|
||||||
// If we don't have voxel jurisdictions, then we will simply queue up these packets and wait till we have
|
|
||||||
// jurisdictions for processing
|
|
||||||
if (!serversExist()) {
|
|
||||||
queuePendingPacketToNodes(type, bufferOut, sizeOut);
|
|
||||||
} else {
|
|
||||||
queuePacketToNodes(bufferOut, sizeOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityEditPacketSender::adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew) {
|
void EntityEditPacketSender::adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew) {
|
||||||
EntityItem::adjustEditPacketForClockSkew(codeColorBuffer, length, clockSkew);
|
EntityItem::adjustEditPacketForClockSkew(codeColorBuffer, length, clockSkew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EntityEditPacketSender::queueEditEntityMessage(PacketType type, EntityItemID modelID,
|
void EntityEditPacketSender::queueEditEntityMessage(PacketType type, EntityItemID modelID,
|
||||||
const EntityItemProperties& properties) {
|
const EntityItemProperties& properties) {
|
||||||
if (!_shouldSend) {
|
if (!_shouldSend) {
|
||||||
|
@ -58,3 +36,23 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, EntityItemI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityEditPacketSender::queueEraseEntityMessage(const EntityItemID& entityItemID) {
|
||||||
|
if (!_shouldSend) {
|
||||||
|
return; // bail early
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "EntityEditPacketSender::queueEraseEntityMessage() entityItemID=" << entityItemID;
|
||||||
|
|
||||||
|
// use MAX_PACKET_SIZE since it's static and guaranteed to be larger than _maxPacketSize
|
||||||
|
static unsigned char bufferOut[MAX_PACKET_SIZE];
|
||||||
|
size_t sizeOut = 0;
|
||||||
|
|
||||||
|
qDebug() << " _maxPacketSize=" << _maxPacketSize;
|
||||||
|
|
||||||
|
if (EntityItemProperties::encodeEraseEntityMessage(entityItemID, &bufferOut[0], _maxPacketSize, sizeOut)) {
|
||||||
|
|
||||||
|
qDebug() << " encodeEraseEntityMessage()... sizeOut=" << sizeOut;
|
||||||
|
|
||||||
|
queueOctreeEditMessage(PacketTypeEntityErase, bufferOut, sizeOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,16 +20,14 @@
|
||||||
class EntityEditPacketSender : public OctreeEditPacketSender {
|
class EntityEditPacketSender : public OctreeEditPacketSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/// Send model add message immediately
|
|
||||||
/// NOTE: EntityItemProperties assumes that all distances are in meter units
|
|
||||||
void sendEditEntityMessage(PacketType type, EntityItemID modelID, const EntityItemProperties& properties);
|
|
||||||
|
|
||||||
/// Queues an array of several voxel edit messages. Will potentially send a pending multi-command packet. Determines
|
/// Queues an array of several voxel edit messages. Will potentially send a pending multi-command packet. Determines
|
||||||
/// which voxel-server node or nodes the packet should be sent to. Can be called even before voxel servers are known, in
|
/// which voxel-server node or nodes the packet should be sent to. Can be called even before voxel servers are known, in
|
||||||
/// which case up to MaxPendingMessages will be buffered and processed when voxel servers are known.
|
/// which case up to MaxPendingMessages will be buffered and processed when voxel servers are known.
|
||||||
/// NOTE: EntityItemProperties assumes that all distances are in meter units
|
/// NOTE: EntityItemProperties assumes that all distances are in meter units
|
||||||
void queueEditEntityMessage(PacketType type, EntityItemID modelID, const EntityItemProperties& properties);
|
void queueEditEntityMessage(PacketType type, EntityItemID modelID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
void queueEraseEntityMessage(const EntityItemID& entityItemID);
|
||||||
|
|
||||||
// My server type is the model server
|
// My server type is the model server
|
||||||
virtual char getMyNodeType() const { return NodeType::EntityServer; }
|
virtual char getMyNodeType() const { return NodeType::EntityServer; }
|
||||||
virtual void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
|
virtual void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
|
||||||
|
|
|
@ -54,7 +54,6 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
|
||||||
_position = glm::vec3(0,0,0);
|
_position = glm::vec3(0,0,0);
|
||||||
_radius = 0;
|
_radius = 0;
|
||||||
_rotation = ENTITY_DEFAULT_ROTATION;
|
_rotation = ENTITY_DEFAULT_ROTATION;
|
||||||
_shouldBeDeleted = false;
|
|
||||||
|
|
||||||
_glowLevel = DEFAULT_GLOW_LEVEL;
|
_glowLevel = DEFAULT_GLOW_LEVEL;
|
||||||
_mass = DEFAULT_MASS;
|
_mass = DEFAULT_MASS;
|
||||||
|
@ -220,26 +219,6 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
||||||
propertiesDidntFit -= PROP_ROTATION;
|
propertiesDidntFit -= PROP_ROTATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROP_SHOULD_BE_DELETED
|
|
||||||
if (requestedProperties.getHasProperty(PROP_SHOULD_BE_DELETED)) {
|
|
||||||
//qDebug() << "PROP_SHOULD_BE_DELETED requested...";
|
|
||||||
LevelDetails propertyLevel = packetData->startLevel();
|
|
||||||
successPropertyFits = packetData->appendValue(getShouldBeDeleted());
|
|
||||||
if (successPropertyFits) {
|
|
||||||
propertyFlags |= PROP_SHOULD_BE_DELETED;
|
|
||||||
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
|
|
||||||
propertyCount++;
|
|
||||||
packetData->endLevel(propertyLevel);
|
|
||||||
} else {
|
|
||||||
//qDebug() << "PROP_SHOULD_BE_DELETED didn't fit...";
|
|
||||||
packetData->discardLevel(propertyLevel);
|
|
||||||
appendState = OctreeElement::PARTIAL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//qDebug() << "PROP_SHOULD_BE_DELETED NOT requested...";
|
|
||||||
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PROP_MASS,
|
// PROP_MASS,
|
||||||
if (requestedProperties.getHasProperty(PROP_MASS)) {
|
if (requestedProperties.getHasProperty(PROP_MASS)) {
|
||||||
LevelDetails propertyLevel = packetData->startLevel();
|
LevelDetails propertyLevel = packetData->startLevel();
|
||||||
|
@ -545,17 +524,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROP_SHOULD_BE_DELETED
|
|
||||||
if (propertyFlags.getHasProperty(PROP_SHOULD_BE_DELETED)) {
|
|
||||||
bool shouldBeDeleted;
|
|
||||||
memcpy(&shouldBeDeleted, dataAt, sizeof(shouldBeDeleted));
|
|
||||||
dataAt += sizeof(shouldBeDeleted);
|
|
||||||
bytesRead += sizeof(shouldBeDeleted);
|
|
||||||
if (overwriteLocalData) {
|
|
||||||
_shouldBeDeleted = shouldBeDeleted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PROP_MASS,
|
// PROP_MASS,
|
||||||
if (propertyFlags.getHasProperty(PROP_MASS)) {
|
if (propertyFlags.getHasProperty(PROP_MASS)) {
|
||||||
float value;
|
float value;
|
||||||
|
@ -641,7 +609,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
void EntityItem::debugDump() const {
|
void EntityItem::debugDump() const {
|
||||||
qDebug() << "EntityItem id:" << getEntityItemID();
|
qDebug() << "EntityItem id:" << getEntityItemID();
|
||||||
qDebug(" edited ago:%f", getEditedAgo());
|
qDebug(" edited ago:%f", getEditedAgo());
|
||||||
qDebug(" should die:%s", debug::valueOf(getShouldBeDeleted()));
|
|
||||||
qDebug(" position:%f,%f,%f", _position.x, _position.y, _position.z);
|
qDebug(" position:%f,%f,%f", _position.x, _position.y, _position.z);
|
||||||
qDebug(" radius:%f", getRadius());
|
qDebug(" radius:%f", getRadius());
|
||||||
}
|
}
|
||||||
|
@ -802,7 +769,6 @@ EntityItemProperties EntityItem::getProperties() const {
|
||||||
properties._position = getPosition() * (float) TREE_SCALE;
|
properties._position = getPosition() * (float) TREE_SCALE;
|
||||||
properties._radius = getRadius() * (float) TREE_SCALE;
|
properties._radius = getRadius() * (float) TREE_SCALE;
|
||||||
properties._rotation = getRotation();
|
properties._rotation = getRotation();
|
||||||
properties._shouldBeDeleted = getShouldBeDeleted();
|
|
||||||
|
|
||||||
properties._mass = getMass();
|
properties._mass = getMass();
|
||||||
properties._velocity = getVelocity() * (float) TREE_SCALE;
|
properties._velocity = getVelocity() * (float) TREE_SCALE;
|
||||||
|
@ -814,7 +780,6 @@ EntityItemProperties EntityItem::getProperties() const {
|
||||||
properties._positionChanged = false;
|
properties._positionChanged = false;
|
||||||
properties._radiusChanged = false;
|
properties._radiusChanged = false;
|
||||||
properties._rotationChanged = false;
|
properties._rotationChanged = false;
|
||||||
properties._shouldBeDeletedChanged = false;
|
|
||||||
properties._massChanged = false;
|
properties._massChanged = false;
|
||||||
properties._velocityChanged = false;
|
properties._velocityChanged = false;
|
||||||
properties._gravityChanged = false;
|
properties._gravityChanged = false;
|
||||||
|
@ -848,11 +813,6 @@ void EntityItem::setProperties(const EntityItemProperties& properties, bool forc
|
||||||
somethingChanged = true;
|
somethingChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties._shouldBeDeletedChanged || forceCopy) {
|
|
||||||
setShouldBeDeleted(properties._shouldBeDeleted);
|
|
||||||
somethingChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (properties._massChanged || forceCopy) {
|
if (properties._massChanged || forceCopy) {
|
||||||
setMass(properties._mass);
|
setMass(properties._mass);
|
||||||
somethingChanged = true;
|
somethingChanged = true;
|
||||||
|
|
|
@ -111,9 +111,6 @@ public:
|
||||||
const glm::quat& getRotation() const { return _rotation; }
|
const glm::quat& getRotation() const { return _rotation; }
|
||||||
void setRotation(const glm::quat& rotation) { _rotation = rotation; }
|
void setRotation(const glm::quat& rotation) { _rotation = rotation; }
|
||||||
|
|
||||||
bool getShouldBeDeleted() const { return _shouldBeDeleted; }
|
|
||||||
void setShouldBeDeleted(bool shouldBeDeleted) { _shouldBeDeleted = shouldBeDeleted; }
|
|
||||||
|
|
||||||
static const float DEFAULT_GLOW_LEVEL;
|
static const float DEFAULT_GLOW_LEVEL;
|
||||||
float getGlowLevel() const { return _glowLevel; }
|
float getGlowLevel() const { return _glowLevel; }
|
||||||
void setGlowLevel(float glowLevel) { _glowLevel = glowLevel; }
|
void setGlowLevel(float glowLevel) { _glowLevel = glowLevel; }
|
||||||
|
@ -182,7 +179,6 @@ protected:
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
float _radius;
|
float _radius;
|
||||||
glm::quat _rotation;
|
glm::quat _rotation;
|
||||||
bool _shouldBeDeleted;
|
|
||||||
float _glowLevel;
|
float _glowLevel;
|
||||||
float _mass;
|
float _mass;
|
||||||
glm::vec3 _velocity;
|
glm::vec3 _velocity;
|
||||||
|
|
|
@ -28,7 +28,6 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
_position(0),
|
_position(0),
|
||||||
_radius(ENTITY_DEFAULT_RADIUS),
|
_radius(ENTITY_DEFAULT_RADIUS),
|
||||||
_rotation(ENTITY_DEFAULT_ROTATION),
|
_rotation(ENTITY_DEFAULT_ROTATION),
|
||||||
_shouldBeDeleted(false),
|
|
||||||
_mass(EntityItem::DEFAULT_MASS),
|
_mass(EntityItem::DEFAULT_MASS),
|
||||||
_velocity(EntityItem::DEFAULT_VELOCITY),
|
_velocity(EntityItem::DEFAULT_VELOCITY),
|
||||||
_gravity(EntityItem::DEFAULT_GRAVITY),
|
_gravity(EntityItem::DEFAULT_GRAVITY),
|
||||||
|
@ -39,7 +38,6 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
_positionChanged(false),
|
_positionChanged(false),
|
||||||
_radiusChanged(false),
|
_radiusChanged(false),
|
||||||
_rotationChanged(false),
|
_rotationChanged(false),
|
||||||
_shouldBeDeletedChanged(false),
|
|
||||||
_massChanged(false),
|
_massChanged(false),
|
||||||
_velocityChanged(false),
|
_velocityChanged(false),
|
||||||
_gravityChanged(false),
|
_gravityChanged(false),
|
||||||
|
@ -89,11 +87,6 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
changedProperties += PROP_ROTATION;
|
changedProperties += PROP_ROTATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_shouldBeDeletedChanged) {
|
|
||||||
changedProperties += PROP_SHOULD_BE_DELETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (_massChanged) {
|
if (_massChanged) {
|
||||||
changedProperties += PROP_MASS;
|
changedProperties += PROP_MASS;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +154,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
||||||
properties.setProperty("radius", _radius);
|
properties.setProperty("radius", _radius);
|
||||||
QScriptValue rotation = quatToScriptValue(engine, _rotation);
|
QScriptValue rotation = quatToScriptValue(engine, _rotation);
|
||||||
properties.setProperty("rotation", rotation);
|
properties.setProperty("rotation", rotation);
|
||||||
properties.setProperty("shouldBeDeleted", _shouldBeDeleted);
|
|
||||||
properties.setProperty("mass", _mass);
|
properties.setProperty("mass", _mass);
|
||||||
QScriptValue velocity = vec3toScriptValue(engine, _velocity);
|
QScriptValue velocity = vec3toScriptValue(engine, _velocity);
|
||||||
properties.setProperty("velocity", velocity);
|
properties.setProperty("velocity", velocity);
|
||||||
|
@ -251,16 +243,6 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue shouldBeDeleted = object.property("shouldBeDeleted");
|
|
||||||
if (shouldBeDeleted.isValid()) {
|
|
||||||
bool newShouldBeDeleted;
|
|
||||||
newShouldBeDeleted = shouldBeDeleted.toVariant().toBool();
|
|
||||||
if (_defaultSettings || newShouldBeDeleted != _shouldBeDeleted) {
|
|
||||||
_shouldBeDeleted = newShouldBeDeleted;
|
|
||||||
_shouldBeDeletedChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue mass = object.property("mass");
|
QScriptValue mass = object.property("mass");
|
||||||
if (mass.isValid()) {
|
if (mass.isValid()) {
|
||||||
float newValue;
|
float newValue;
|
||||||
|
@ -600,26 +582,6 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
propertiesDidntFit -= PROP_ROTATION;
|
propertiesDidntFit -= PROP_ROTATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROP_SHOULD_BE_DELETED
|
|
||||||
if (requestedProperties.getHasProperty(PROP_SHOULD_BE_DELETED)) {
|
|
||||||
//qDebug() << "PROP_SHOULD_BE_DELETED requested...";
|
|
||||||
LevelDetails propertyLevel = packetData.startLevel();
|
|
||||||
successPropertyFits = packetData.appendValue(properties.getShouldBeDeleted());
|
|
||||||
if (successPropertyFits) {
|
|
||||||
propertyFlags |= PROP_SHOULD_BE_DELETED;
|
|
||||||
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
|
|
||||||
propertyCount++;
|
|
||||||
packetData.endLevel(propertyLevel);
|
|
||||||
} else {
|
|
||||||
//qDebug() << "PROP_SHOULD_BE_DELETED didn't fit...";
|
|
||||||
packetData.discardLevel(propertyLevel);
|
|
||||||
appendState = OctreeElement::PARTIAL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//qDebug() << "PROP_SHOULD_BE_DELETED NOT requested...";
|
|
||||||
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PROP_MASS,
|
// PROP_MASS,
|
||||||
if (requestedProperties.getHasProperty(PROP_MASS)) {
|
if (requestedProperties.getHasProperty(PROP_MASS)) {
|
||||||
LevelDetails propertyLevel = packetData.startLevel();
|
LevelDetails propertyLevel = packetData.startLevel();
|
||||||
|
@ -913,7 +875,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
EntityItemID& entityID, EntityItemProperties& properties) {
|
EntityItemID& entityID, EntityItemProperties& properties) {
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
|
||||||
bool wantDebug = false;
|
bool wantDebug = true;
|
||||||
if (wantDebug) {
|
if (wantDebug) {
|
||||||
qDebug() << "EntityItemProperties::decodeEntityEditPacket() bytesToRead=" << bytesToRead;
|
qDebug() << "EntityItemProperties::decodeEntityEditPacket() bytesToRead=" << bytesToRead;
|
||||||
}
|
}
|
||||||
|
@ -1045,15 +1007,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
properties.setRotation(rotation);
|
properties.setRotation(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROP_SHOULD_BE_DELETED
|
|
||||||
if (propertyFlags.getHasProperty(PROP_SHOULD_BE_DELETED)) {
|
|
||||||
bool shouldBeDeleted;
|
|
||||||
memcpy(&shouldBeDeleted, dataAt, sizeof(shouldBeDeleted));
|
|
||||||
dataAt += sizeof(shouldBeDeleted);
|
|
||||||
processedBytes += sizeof(shouldBeDeleted);
|
|
||||||
properties.setShouldBeDeleted(shouldBeDeleted);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PROP_MASS,
|
// PROP_MASS,
|
||||||
if (propertyFlags.getHasProperty(PROP_MASS)) {
|
if (propertyFlags.getHasProperty(PROP_MASS)) {
|
||||||
float value;
|
float value;
|
||||||
|
@ -1186,4 +1139,35 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: This version will only encode the portion of the edit message immediately following the
|
||||||
|
// header it does not include the send times and sequence number because that is handled by the
|
||||||
|
// edit packet sender...
|
||||||
|
bool EntityItemProperties::encodeEraseEntityMessage(const EntityItemID& entityItemID,
|
||||||
|
unsigned char* outputBuffer, size_t maxLength, size_t& outputLength) {
|
||||||
|
|
||||||
|
qDebug() << "EntityItemProperties::encodeEraseEntityMessage()";
|
||||||
|
|
||||||
|
unsigned char* copyAt = outputBuffer;
|
||||||
|
|
||||||
|
uint16_t numberOfIds = 1; // only one entity ID in this message
|
||||||
|
memcpy(copyAt, &numberOfIds, sizeof(numberOfIds));
|
||||||
|
copyAt += sizeof(numberOfIds);
|
||||||
|
outputLength += sizeof(numberOfIds);
|
||||||
|
|
||||||
|
qDebug() << " numberOfIds=" << numberOfIds;
|
||||||
|
|
||||||
|
QUuid entityID = entityItemID.id;
|
||||||
|
QByteArray encodedEntityID = entityID.toRfc4122();
|
||||||
|
memcpy(copyAt, encodedEntityID.constData(), NUM_BYTES_RFC4122_UUID);
|
||||||
|
copyAt += NUM_BYTES_RFC4122_UUID;
|
||||||
|
outputLength += NUM_BYTES_RFC4122_UUID;
|
||||||
|
|
||||||
|
qDebug() << " entityID=" << entityID;
|
||||||
|
|
||||||
|
qDebug() << " outputLength=" << outputLength;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
|
@ -63,8 +63,8 @@ enum EntityPropertyList {
|
||||||
PROP_ANIMATION_FPS,
|
PROP_ANIMATION_FPS,
|
||||||
PROP_ANIMATION_FRAME_INDEX,
|
PROP_ANIMATION_FRAME_INDEX,
|
||||||
PROP_ANIMATION_PLAYING,
|
PROP_ANIMATION_PLAYING,
|
||||||
PROP_SHOULD_BE_DELETED,
|
|
||||||
PROP_LAST_ITEM = PROP_SHOULD_BE_DELETED
|
PROP_LAST_ITEM = PROP_ANIMATION_PLAYING
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
||||||
|
@ -122,14 +122,12 @@ public:
|
||||||
float getMaxDimension() const { return _radius * 2.0f; }
|
float getMaxDimension() const { return _radius * 2.0f; }
|
||||||
glm::vec3 getDimensions() const { return glm::vec3(_radius, _radius, _radius) * 2.0f; }
|
glm::vec3 getDimensions() const { return glm::vec3(_radius, _radius, _radius) * 2.0f; }
|
||||||
const glm::quat& getRotation() const { return _rotation; }
|
const glm::quat& getRotation() const { return _rotation; }
|
||||||
bool getShouldBeDeleted() const { return _shouldBeDeleted; }
|
|
||||||
|
|
||||||
void setType(EntityTypes::EntityType type) { _type = type; }
|
void setType(EntityTypes::EntityType type) { _type = type; }
|
||||||
/// set position in meter units
|
/// set position in meter units
|
||||||
void setPosition(const glm::vec3& value) { _position = value; _positionChanged = true; }
|
void setPosition(const glm::vec3& value) { _position = value; _positionChanged = true; }
|
||||||
void setRadius(float value) { _radius = value; _radiusChanged = true; }
|
void setRadius(float value) { _radius = value; _radiusChanged = true; }
|
||||||
void setRotation(const glm::quat& rotation) { _rotation = rotation; _rotationChanged = true; }
|
void setRotation(const glm::quat& rotation) { _rotation = rotation; _rotationChanged = true; }
|
||||||
void setShouldBeDeleted(bool shouldBeDeleted) { _shouldBeDeleted = shouldBeDeleted; _shouldBeDeletedChanged = true; }
|
|
||||||
|
|
||||||
float getMass() const { return _mass; }
|
float getMass() const { return _mass; }
|
||||||
void setMass(float value) { _mass = value; _massChanged = true; }
|
void setMass(float value) { _mass = value; _massChanged = true; }
|
||||||
|
@ -175,6 +173,10 @@ public:
|
||||||
static bool encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties,
|
static bool encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties,
|
||||||
unsigned char* bufferOut, int sizeIn, int& sizeOut);
|
unsigned char* bufferOut, int sizeIn, int& sizeOut);
|
||||||
|
|
||||||
|
static bool encodeEraseEntityMessage(const EntityItemID& entityItemID,
|
||||||
|
unsigned char* outputBuffer, size_t maxLength, size_t& outputLength);
|
||||||
|
|
||||||
|
|
||||||
static bool decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes,
|
static bool decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes,
|
||||||
EntityItemID& entityID, EntityItemProperties& properties);
|
EntityItemID& entityID, EntityItemProperties& properties);
|
||||||
|
|
||||||
|
@ -189,7 +191,6 @@ private:
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
float _radius;
|
float _radius;
|
||||||
glm::quat _rotation;
|
glm::quat _rotation;
|
||||||
bool _shouldBeDeleted;
|
|
||||||
float _mass;
|
float _mass;
|
||||||
glm::vec3 _velocity;
|
glm::vec3 _velocity;
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
|
@ -200,7 +201,6 @@ private:
|
||||||
bool _positionChanged;
|
bool _positionChanged;
|
||||||
bool _radiusChanged;
|
bool _radiusChanged;
|
||||||
bool _rotationChanged;
|
bool _rotationChanged;
|
||||||
bool _shouldBeDeletedChanged;
|
|
||||||
bool _massChanged;
|
bool _massChanged;
|
||||||
bool _velocityChanged;
|
bool _velocityChanged;
|
||||||
bool _gravityChanged;
|
bool _gravityChanged;
|
||||||
|
|
|
@ -123,10 +123,6 @@ EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const E
|
||||||
// message which takes a list of model id's to delete.
|
// message which takes a list of model id's to delete.
|
||||||
void EntityScriptingInterface::deleteEntity(EntityItemID entityID) {
|
void EntityScriptingInterface::deleteEntity(EntityItemID entityID) {
|
||||||
|
|
||||||
// setup properties to kill the model
|
|
||||||
EntityItemProperties properties;
|
|
||||||
properties.setShouldBeDeleted(true);
|
|
||||||
|
|
||||||
EntityItemID actualID = entityID;
|
EntityItemID actualID = entityID;
|
||||||
|
|
||||||
// if the model is unknown, attempt to look it up
|
// if the model is unknown, attempt to look it up
|
||||||
|
@ -138,8 +134,13 @@ void EntityScriptingInterface::deleteEntity(EntityItemID entityID) {
|
||||||
if (actualID.id != UNKNOWN_ENTITY_ID) {
|
if (actualID.id != UNKNOWN_ENTITY_ID) {
|
||||||
entityID.id = actualID.id;
|
entityID.id = actualID.id;
|
||||||
entityID.isKnownID = true;
|
entityID.isKnownID = true;
|
||||||
//qDebug() << "EntityScriptingInterface::deleteEntity()... isKnownID=" << entityID.isKnownID << "id=" << entityID.id << "creatorTokenID=" << entityID.creatorTokenID;
|
|
||||||
queueEntityMessage(PacketTypeEntityAddOrEdit, entityID, properties);
|
qDebug() << "EntityScriptingInterface::deleteEntity()... "
|
||||||
|
<< "isKnownID=" << entityID.isKnownID
|
||||||
|
<< "id=" << entityID.id
|
||||||
|
<< "creatorTokenID=" << entityID.creatorTokenID;
|
||||||
|
|
||||||
|
getEntityPacketSender()->queueEraseEntityMessage(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a local model tree set, then also update it.
|
// If we have a local model tree set, then also update it.
|
||||||
|
|
|
@ -302,9 +302,9 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
||||||
// does this entity tree element contain the old entity
|
// does this entity tree element contain the old entity
|
||||||
bool UpdateEntityOperator::subTreeContainsOldEntity(OctreeElement* element) {
|
bool UpdateEntityOperator::subTreeContainsOldEntity(OctreeElement* element) {
|
||||||
bool elementContainsOldBox = element->getAACube().contains(_oldEntityBox);
|
bool elementContainsOldBox = element->getAACube().contains(_oldEntityBox);
|
||||||
bool elementContainsOldCube = element->getAACube().contains(_oldEntityCube);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
bool elementContainsOldCube = element->getAACube().contains(_oldEntityCube);
|
||||||
qDebug() << "UpdateEntityOperator::subTreeContainsOldEntity()....";
|
qDebug() << "UpdateEntityOperator::subTreeContainsOldEntity()....";
|
||||||
qDebug() << " element->getAACube()=" << element->getAACube();
|
qDebug() << " element->getAACube()=" << element->getAACube();
|
||||||
qDebug() << " _oldEntityCube=" << _oldEntityCube;
|
qDebug() << " _oldEntityCube=" << _oldEntityCube;
|
||||||
|
@ -318,9 +318,9 @@ bool UpdateEntityOperator::subTreeContainsOldEntity(OctreeElement* element) {
|
||||||
|
|
||||||
bool UpdateEntityOperator::subTreeContainsNewEntity(OctreeElement* element) {
|
bool UpdateEntityOperator::subTreeContainsNewEntity(OctreeElement* element) {
|
||||||
bool elementContainsNewBox = element->getAACube().contains(_newEntityBox);
|
bool elementContainsNewBox = element->getAACube().contains(_newEntityBox);
|
||||||
bool elementContainsNewCube = element->getAACube().contains(_newEntityCube);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
bool elementContainsNewCube = element->getAACube().contains(_newEntityCube);
|
||||||
qDebug() << "UpdateEntityOperator::subTreeContainsNewEntity()....";
|
qDebug() << "UpdateEntityOperator::subTreeContainsNewEntity()....";
|
||||||
qDebug() << " element->getAACube()=" << element->getAACube();
|
qDebug() << " element->getAACube()=" << element->getAACube();
|
||||||
qDebug() << " _newEntityCube=" << _newEntityCube;
|
qDebug() << " _newEntityCube=" << _newEntityCube;
|
||||||
|
@ -511,7 +511,10 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
|
||||||
// You should not call this on existing entities that are already part of the tree! Call updateEntity()
|
// You should not call this on existing entities that are already part of the tree! Call updateEntity()
|
||||||
EntityTreeElement* containingElement = getContainingElement(entityID);
|
EntityTreeElement* containingElement = getContainingElement(entityID);
|
||||||
if (!containingElement) {
|
if (!containingElement) {
|
||||||
assert(containingElement); // don't call updateEntity() on entity items that don't exist
|
//assert(containingElement); // don't call updateEntity() on entity items that don't exist
|
||||||
|
|
||||||
|
qDebug() << "UNEXPECTED!!!! EntityTree::updateEntity() entityID doesn't exist!!! entityID=" << entityID;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,10 +636,23 @@ void DeleteEntityOperator::addEntityIDToDeleteList(const EntityItemID& searchEnt
|
||||||
details.cube = details.containingElement->getAACube();
|
details.cube = details.containingElement->getAACube();
|
||||||
_entitiesToDelete << details;
|
_entitiesToDelete << details;
|
||||||
_lookingCount++;
|
_lookingCount++;
|
||||||
|
|
||||||
|
_tree->trackDeletedEntity(searchEntityID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityTree::trackDeletedEntity(const EntityItemID& entityID) {
|
||||||
|
// this is only needed on the server to send delete messages for recently deleted entities to the viewers
|
||||||
|
if (getIsServer()) {
|
||||||
|
// set up the deleted entities ID
|
||||||
|
quint64 deletedAt = usecTimestampNow();
|
||||||
|
_recentlyDeletedEntitiesLock.lockForWrite();
|
||||||
|
_recentlyDeletedEntityItemIDs.insert(deletedAt, entityID.id);
|
||||||
|
_recentlyDeletedEntitiesLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// does this entity tree element contain the old entity
|
// does this entity tree element contain the old entity
|
||||||
bool DeleteEntityOperator::subTreeContainsSomeEntitiesToDelete(OctreeElement* element) {
|
bool DeleteEntityOperator::subTreeContainsSomeEntitiesToDelete(OctreeElement* element) {
|
||||||
|
@ -1046,8 +1062,15 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
int processedBytes = 0;
|
int processedBytes = 0;
|
||||||
// we handle these types of "edit" packets
|
// we handle these types of "edit" packets
|
||||||
switch (packetType) {
|
switch (packetType) {
|
||||||
|
case PacketTypeEntityErase: {
|
||||||
|
qDebug() << "EntityTree::processEditPacketData().... PacketTypeEntityErase ****** packetLength=" << packetLength;
|
||||||
|
QByteArray dataByteArray((const char*)packetData, packetLength);
|
||||||
|
processEraseMessageDetails(dataByteArray, senderNode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case PacketTypeEntityAddOrEdit: {
|
case PacketTypeEntityAddOrEdit: {
|
||||||
//qDebug() << "EntityTree::processEditPacketData()....";
|
qDebug() << "EntityTree::processEditPacketData()....";
|
||||||
|
|
||||||
EntityItemID entityItemID;
|
EntityItemID entityItemID;
|
||||||
EntityItemProperties properties;
|
EntityItemProperties properties;
|
||||||
|
@ -1071,21 +1094,10 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
qDebug() << "User attempted to edit an unknown entity.";
|
qDebug() << "User attempted to edit an unknown entity.";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// NOTE: We need to fix this... we can't have the creator tokens in the server side map... because if we do that
|
|
||||||
// then we will have multiple creator tokens with the same id from different editors... since assignEntityID()
|
|
||||||
// checks for the ID already existing in the map, this will assert/abort.
|
|
||||||
//
|
|
||||||
// But we do want the creator tokens in the client side version of the map...
|
|
||||||
// so maybe the fix is just to ....
|
|
||||||
|
|
||||||
|
|
||||||
// this is a new entity... assign a new entityID
|
// this is a new entity... assign a new entityID
|
||||||
qDebug() << "EntityTree::processEditPacketData() ... BEFORE assignEntityID()... entityItemID=" << entityItemID;
|
qDebug() << "EntityTree::processEditPacketData() ... BEFORE assignEntityID()... entityItemID=" << entityItemID;
|
||||||
entityItemID = assignEntityID(entityItemID);
|
entityItemID = assignEntityID(entityItemID);
|
||||||
qDebug() << "EntityTree::processEditPacketData() ... AFTER assignEntityID()... entityItemID=" << entityItemID;
|
qDebug() << "EntityTree::processEditPacketData() ... AFTER assignEntityID()... entityItemID=" << entityItemID;
|
||||||
|
|
||||||
EntityItem* newEntity = addEntity(entityItemID, properties);
|
EntityItem* newEntity = addEntity(entityItemID, properties);
|
||||||
if (newEntity) {
|
if (newEntity) {
|
||||||
|
@ -1130,13 +1142,6 @@ void EntityTree::removeNewlyCreatedHook(NewlyCreatedEntityHook* hook) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityTree::updateOperation(OctreeElement* element, void* extraData) {
|
|
||||||
EntityTreeUpdateArgs* args = static_cast<EntityTreeUpdateArgs*>(extraData);
|
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
|
||||||
entityTreeElement->update(*args);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityTree::changeEntityState(EntityItem* const entity, EntityItem::SimuationState oldState, EntityItem::SimuationState newState) {
|
void EntityTree::changeEntityState(EntityItem* const entity, EntityItem::SimuationState oldState, EntityItem::SimuationState newState) {
|
||||||
|
|
||||||
bool wantDebug = false;
|
bool wantDebug = false;
|
||||||
|
@ -1302,7 +1307,7 @@ bool EntityTree::hasEntitiesDeletedSince(quint64 sinceTime) {
|
||||||
bool hasSomethingNewer = false;
|
bool hasSomethingNewer = false;
|
||||||
|
|
||||||
_recentlyDeletedEntitiesLock.lockForRead();
|
_recentlyDeletedEntitiesLock.lockForRead();
|
||||||
QMultiMap<quint64, uint32_t>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin();
|
QMultiMap<quint64, QUuid>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin();
|
||||||
while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) {
|
while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) {
|
||||||
//qDebug() << "considering... time/key:" << iterator.key();
|
//qDebug() << "considering... time/key:" << iterator.key();
|
||||||
if (iterator.key() > sinceTime) {
|
if (iterator.key() > sinceTime) {
|
||||||
|
@ -1357,28 +1362,30 @@ qDebug() << "EntityTree::encodeEntitiesDeletedSince()";
|
||||||
// we keep a multi map of entity IDs to timestamps, we only want to include the entity IDs that have been
|
// we keep a multi map of entity IDs to timestamps, we only want to include the entity IDs that have been
|
||||||
// deleted since we last sent to this node
|
// deleted since we last sent to this node
|
||||||
_recentlyDeletedEntitiesLock.lockForRead();
|
_recentlyDeletedEntitiesLock.lockForRead();
|
||||||
QMultiMap<quint64, uint32_t>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin();
|
QMultiMap<quint64, QUuid>::const_iterator iterator = _recentlyDeletedEntityItemIDs.constBegin();
|
||||||
while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) {
|
while (iterator != _recentlyDeletedEntityItemIDs.constEnd()) {
|
||||||
QList<uint32_t> values = _recentlyDeletedEntityItemIDs.values(iterator.key());
|
QList<QUuid> values = _recentlyDeletedEntityItemIDs.values(iterator.key());
|
||||||
for (int valueItem = 0; valueItem < values.size(); ++valueItem) {
|
for (int valueItem = 0; valueItem < values.size(); ++valueItem) {
|
||||||
|
|
||||||
// if the timestamp is more recent then out last sent time, include it
|
// if the timestamp is more recent then out last sent time, include it
|
||||||
if (iterator.key() > sinceTime) {
|
if (iterator.key() > sinceTime) {
|
||||||
uint32_t entityID = values.at(valueItem);
|
QUuid entityID = values.at(valueItem);
|
||||||
memcpy(copyAt, &entityID, sizeof(entityID));
|
|
||||||
copyAt += sizeof(entityID);
|
QByteArray encodedEntityID = entityID.toRfc4122();
|
||||||
outputLength += sizeof(entityID);
|
memcpy(copyAt, encodedEntityID.constData(), NUM_BYTES_RFC4122_UUID);
|
||||||
|
copyAt += NUM_BYTES_RFC4122_UUID;
|
||||||
|
outputLength += NUM_BYTES_RFC4122_UUID;
|
||||||
numberOfIds++;
|
numberOfIds++;
|
||||||
|
|
||||||
// check to make sure we have room for one more id...
|
// check to make sure we have room for one more id...
|
||||||
if (outputLength + sizeof(uint32_t) > maxLength) {
|
if (outputLength + NUM_BYTES_RFC4122_UUID > maxLength) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to make sure we have room for one more id...
|
// check to make sure we have room for one more id...
|
||||||
if (outputLength + sizeof(uint32_t) > maxLength) {
|
if (outputLength + NUM_BYTES_RFC4122_UUID > maxLength) {
|
||||||
|
|
||||||
// let our caller know how far we got
|
// let our caller know how far we got
|
||||||
sinceTime = iterator.key();
|
sinceTime = iterator.key();
|
||||||
|
@ -1398,14 +1405,14 @@ qDebug() << "EntityTree::encodeEntitiesDeletedSince()";
|
||||||
return hasMoreToSend;
|
return hasMoreToSend;
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by the server when it knows all nodes have been sent deleted packets
|
|
||||||
|
|
||||||
|
// called by the server when it knows all nodes have been sent deleted packets
|
||||||
void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
||||||
//qDebug() << "forgetEntitiesDeletedBefore()";
|
//qDebug() << "forgetEntitiesDeletedBefore()";
|
||||||
QSet<quint64> keysToRemove;
|
QSet<quint64> keysToRemove;
|
||||||
|
|
||||||
_recentlyDeletedEntitiesLock.lockForWrite();
|
_recentlyDeletedEntitiesLock.lockForWrite();
|
||||||
QMultiMap<quint64, uint32_t>::iterator iterator = _recentlyDeletedEntityItemIDs.begin();
|
QMultiMap<quint64, QUuid>::iterator iterator = _recentlyDeletedEntityItemIDs.begin();
|
||||||
|
|
||||||
// First find all the keys in the map that are older and need to be deleted
|
// First find all the keys in the map that are older and need to be deleted
|
||||||
while (iterator != _recentlyDeletedEntityItemIDs.end()) {
|
while (iterator != _recentlyDeletedEntityItemIDs.end()) {
|
||||||
|
@ -1426,10 +1433,6 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
||||||
|
|
||||||
|
|
||||||
void EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
void EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||||
|
|
||||||
#if 0 ///////////////
|
|
||||||
|
|
||||||
|
|
||||||
qDebug() << "EntityTree::processEraseMessage()...";
|
qDebug() << "EntityTree::processEraseMessage()...";
|
||||||
|
|
||||||
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
||||||
|
@ -1449,18 +1452,25 @@ void EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Shar
|
||||||
dataAt += sizeof(numberOfIds);
|
dataAt += sizeof(numberOfIds);
|
||||||
processedBytes += sizeof(numberOfIds);
|
processedBytes += sizeof(numberOfIds);
|
||||||
|
|
||||||
|
qDebug() << "EntityTree::processEraseMessage().... numberOfIds=" << numberOfIds;
|
||||||
|
qDebug() << "EntityTree::processEraseMessage().... processedBytes=" << processedBytes;
|
||||||
|
qDebug() << "EntityTree::processEraseMessage().... packetLength=" << packetLength;
|
||||||
|
|
||||||
if (numberOfIds > 0) {
|
if (numberOfIds > 0) {
|
||||||
QSet<EntityItemID> entityItemIDsToDelete;
|
QSet<EntityItemID> entityItemIDsToDelete;
|
||||||
|
|
||||||
for (size_t i = 0; i < numberOfIds; i++) {
|
for (size_t i = 0; i < numberOfIds; i++) {
|
||||||
if (processedBytes + sizeof(uint32_t) > packetLength) {
|
|
||||||
|
|
||||||
|
if (processedBytes + NUM_BYTES_RFC4122_UUID > packetLength) {
|
||||||
|
qDebug() << "EntityTree::processEraseMessage().... bailing because not enough bytes in buffer";
|
||||||
break; // bail to prevent buffer overflow
|
break; // bail to prevent buffer overflow
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t entityID = 0; // placeholder for now
|
QByteArray encodedID = dataByteArray.mid(processedBytes, NUM_BYTES_RFC4122_UUID);
|
||||||
memcpy(&entityID, dataAt, sizeof(entityID));
|
QUuid entityID = QUuid::fromRfc4122(encodedID);
|
||||||
dataAt += sizeof(entityID);
|
dataAt += encodedID.size();
|
||||||
processedBytes += sizeof(entityID);
|
processedBytes += encodedID.size();
|
||||||
|
|
||||||
EntityItemID entityItemID(entityID);
|
EntityItemID entityItemID(entityID);
|
||||||
entityItemIDsToDelete << entityItemID;
|
entityItemIDsToDelete << entityItemID;
|
||||||
|
@ -1469,9 +1479,49 @@ void EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Shar
|
||||||
qDebug() << "EntityTree::processEraseMessage()... deleteEntities(entityItemIDsToDelete)";
|
qDebug() << "EntityTree::processEraseMessage()... deleteEntities(entityItemIDsToDelete)";
|
||||||
deleteEntities(entityItemIDsToDelete);
|
deleteEntities(entityItemIDsToDelete);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif // 0 ///////////////
|
|
||||||
|
// This version skips over the header
|
||||||
|
void EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||||
|
qDebug() << "EntityTree::processEraseMessageDetails()...";
|
||||||
|
|
||||||
|
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
||||||
|
const unsigned char* dataAt = packetData;
|
||||||
|
size_t packetLength = dataByteArray.size();
|
||||||
|
size_t processedBytes = 0;
|
||||||
|
|
||||||
|
uint16_t numberOfIds = 0; // placeholder for now
|
||||||
|
memcpy(&numberOfIds, dataAt, sizeof(numberOfIds));
|
||||||
|
dataAt += sizeof(numberOfIds);
|
||||||
|
processedBytes += sizeof(numberOfIds);
|
||||||
|
|
||||||
|
qDebug() << "EntityTree::processEraseMessageDetails().... numberOfIds=" << numberOfIds;
|
||||||
|
qDebug() << "EntityTree::processEraseMessageDetails().... processedBytes=" << processedBytes;
|
||||||
|
qDebug() << "EntityTree::processEraseMessageDetails().... packetLength=" << packetLength;
|
||||||
|
|
||||||
|
if (numberOfIds > 0) {
|
||||||
|
QSet<EntityItemID> entityItemIDsToDelete;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < numberOfIds; i++) {
|
||||||
|
|
||||||
|
|
||||||
|
if (processedBytes + NUM_BYTES_RFC4122_UUID > packetLength) {
|
||||||
|
qDebug() << "EntityTree::processEraseMessageDetails().... bailing because not enough bytes in buffer";
|
||||||
|
break; // bail to prevent buffer overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray encodedID = dataByteArray.mid(processedBytes, NUM_BYTES_RFC4122_UUID);
|
||||||
|
QUuid entityID = QUuid::fromRfc4122(encodedID);
|
||||||
|
dataAt += encodedID.size();
|
||||||
|
processedBytes += encodedID.size();
|
||||||
|
|
||||||
|
EntityItemID entityItemID(entityID);
|
||||||
|
entityItemIDsToDelete << entityItemID;
|
||||||
|
qDebug() << "EntityTree::processEraseMessageDetails()... entityItemIDsToDelete << entityItemID=" << entityItemID;
|
||||||
|
}
|
||||||
|
qDebug() << "EntityTree::processEraseMessageDetails()... deleteEntities(entityItemIDsToDelete)";
|
||||||
|
deleteEntities(entityItemIDsToDelete);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ public:
|
||||||
void forgetEntitiesDeletedBefore(quint64 sinceTime);
|
void forgetEntitiesDeletedBefore(quint64 sinceTime);
|
||||||
|
|
||||||
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||||
|
void processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||||
void handleAddEntityResponse(const QByteArray& packet);
|
void handleAddEntityResponse(const QByteArray& packet);
|
||||||
|
|
||||||
EntityItemFBXService* getFBXService() const { return _fbxService; }
|
EntityItemFBXService* getFBXService() const { return _fbxService; }
|
||||||
|
@ -119,9 +120,10 @@ public:
|
||||||
|
|
||||||
void changeEntityState(EntityItem* const entity, EntityItem::SimuationState oldState, EntityItem::SimuationState newState);
|
void changeEntityState(EntityItem* const entity, EntityItem::SimuationState oldState, EntityItem::SimuationState newState);
|
||||||
|
|
||||||
|
void trackDeletedEntity(const EntityItemID& entityID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static bool updateOperation(OctreeElement* element, void* extraData);
|
|
||||||
static bool findAndUpdateOperation(OctreeElement* element, void* extraData);
|
static bool findAndUpdateOperation(OctreeElement* element, void* extraData);
|
||||||
static bool findAndUpdateWithIDandPropertiesOperation(OctreeElement* element, void* extraData);
|
static bool findAndUpdateWithIDandPropertiesOperation(OctreeElement* element, void* extraData);
|
||||||
static bool findNearPointOperation(OctreeElement* element, void* extraData);
|
static bool findNearPointOperation(OctreeElement* element, void* extraData);
|
||||||
|
@ -137,8 +139,9 @@ private:
|
||||||
QReadWriteLock _newlyCreatedHooksLock;
|
QReadWriteLock _newlyCreatedHooksLock;
|
||||||
QVector<NewlyCreatedEntityHook*> _newlyCreatedHooks;
|
QVector<NewlyCreatedEntityHook*> _newlyCreatedHooks;
|
||||||
|
|
||||||
|
|
||||||
QReadWriteLock _recentlyDeletedEntitiesLock;
|
QReadWriteLock _recentlyDeletedEntitiesLock;
|
||||||
QMultiMap<quint64, uint32_t> _recentlyDeletedEntityItemIDs;
|
QMultiMap<quint64, QUuid> _recentlyDeletedEntityItemIDs;
|
||||||
EntityItemFBXService* _fbxService;
|
EntityItemFBXService* _fbxService;
|
||||||
|
|
||||||
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
|
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
|
||||||
|
|
|
@ -280,51 +280,6 @@ bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EntityTreeElement::update(EntityTreeUpdateArgs& args) {
|
|
||||||
args._totalElements++;
|
|
||||||
// update our contained entities
|
|
||||||
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
|
|
||||||
while(entityItr != _entityItems->end()) {
|
|
||||||
EntityItem* entity = (*entityItr);
|
|
||||||
args._totalItems++;
|
|
||||||
|
|
||||||
// TODO: this _lastChanged isn't actually changing because we're not marking this element as changed.
|
|
||||||
// how do we want to handle this??? We really only want to consider an element changed when it is
|
|
||||||
// edited... not just animated...
|
|
||||||
entity->update(_lastChanged);
|
|
||||||
|
|
||||||
|
|
||||||
// If the entity wants to die, or if it's left our bounding box, then move it
|
|
||||||
// into the arguments moving entities. These will be added back or deleted completely
|
|
||||||
if (entity->getShouldBeDeleted() || !bestFitEntityBounds(entity)) {
|
|
||||||
qDebug() << "EntityTreeElement::update()... OLD DELETE LOGIC CALLED BUT NOT IMPLEMENTED...";
|
|
||||||
|
|
||||||
/***
|
|
||||||
// TODO: What to do about this???
|
|
||||||
|
|
||||||
args._movingEntities.push_back(entity);
|
|
||||||
|
|
||||||
// erase this entity
|
|
||||||
entityItr = _entityItems->erase(entityItr);
|
|
||||||
|
|
||||||
args._movingItems++;
|
|
||||||
|
|
||||||
// this element has changed so mark it...
|
|
||||||
markWithChangedTime();
|
|
||||||
|
|
||||||
// TODO: is this a good place to change the containing element map???
|
|
||||||
qDebug() << "EntityTreeElement::update()... calling _myTree->setContainingElement(entity.getEntityItemID(), NULL); ********";
|
|
||||||
_myTree->setContainingElement(entity->getEntityItemID(), NULL);
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
++entityItr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||||
void** intersectedObject) {
|
void** intersectedObject) {
|
||||||
|
|
|
@ -114,7 +114,6 @@ public:
|
||||||
QList<EntityItem*>& getEntities() { return *_entityItems; }
|
QList<EntityItem*>& getEntities() { return *_entityItems; }
|
||||||
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
||||||
|
|
||||||
void update(EntityTreeUpdateArgs& args);
|
|
||||||
void setTree(EntityTree* tree) { _myTree = tree; }
|
void setTree(EntityTree* tree) { _myTree = tree; }
|
||||||
|
|
||||||
bool updateEntity(const EntityItem& entity);
|
bool updateEntity(const EntityItem& entity);
|
||||||
|
|
|
@ -255,10 +255,16 @@ int ModelEntityItem::oldVersionReadEntityDataFromBuffer(const unsigned char* dat
|
||||||
dataAt += sizeof(_color);
|
dataAt += sizeof(_color);
|
||||||
bytesRead += sizeof(_color);
|
bytesRead += sizeof(_color);
|
||||||
|
|
||||||
|
// TODO: how to handle this? Presumable, this would only ever be true if the model file was saved with
|
||||||
|
// a model being in a shouldBeDeleted state. Which seems unlikely. But if it happens, maybe we should delete the entity after loading?
|
||||||
// shouldBeDeleted
|
// shouldBeDeleted
|
||||||
memcpy(&_shouldBeDeleted, dataAt, sizeof(_shouldBeDeleted));
|
bool shouldBeDeleted = false;
|
||||||
dataAt += sizeof(_shouldBeDeleted);
|
memcpy(&shouldBeDeleted, dataAt, sizeof(shouldBeDeleted));
|
||||||
bytesRead += sizeof(_shouldBeDeleted);
|
dataAt += sizeof(shouldBeDeleted);
|
||||||
|
bytesRead += sizeof(shouldBeDeleted);
|
||||||
|
if (shouldBeDeleted) {
|
||||||
|
qDebug() << "UNEXPECTED - read shouldBeDeleted=TRUE from an old format file";
|
||||||
|
}
|
||||||
|
|
||||||
// modelURL
|
// modelURL
|
||||||
uint16_t modelURLLength;
|
uint16_t modelURLLength;
|
||||||
|
|
|
@ -77,7 +77,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
case PacketTypeEntityData:
|
case PacketTypeEntityData:
|
||||||
return VERSION_ENTITIES_SUPPORT_SPLIT_MTU;
|
return VERSION_ENTITIES_SUPPORT_SPLIT_MTU;
|
||||||
case PacketTypeEntityErase:
|
case PacketTypeEntityErase:
|
||||||
return 1;
|
return 2;
|
||||||
case PacketTypeAudioStreamStats:
|
case PacketTypeAudioStreamStats:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -251,8 +251,10 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
|
||||||
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
bool isMyJurisdiction = true;
|
bool isMyJurisdiction = true;
|
||||||
|
|
||||||
if (_serverJurisdictions) {
|
if (type == PacketTypeEntityErase) {
|
||||||
|
isMyJurisdiction = true; // send erase messages to all servers
|
||||||
|
} else if (_serverJurisdictions) {
|
||||||
// we need to get the jurisdiction for this
|
// we need to get the jurisdiction for this
|
||||||
// here we need to get the "pending packet" for this server
|
// here we need to get the "pending packet" for this server
|
||||||
_serverJurisdictions->lockForRead();
|
_serverJurisdictions->lockForRead();
|
||||||
|
@ -265,6 +267,9 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
|
||||||
_serverJurisdictions->unlock();
|
_serverJurisdictions->unlock();
|
||||||
}
|
}
|
||||||
if (isMyJurisdiction) {
|
if (isMyJurisdiction) {
|
||||||
|
|
||||||
|
qDebug() << "OctreeEditPacketSender::queueOctreeEditMessage()... isMyJurisidiction....";
|
||||||
|
|
||||||
EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID];
|
EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID];
|
||||||
packetBuffer._nodeUUID = nodeUUID;
|
packetBuffer._nodeUUID = nodeUUID;
|
||||||
|
|
||||||
|
@ -272,11 +277,17 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
|
||||||
if ((type != packetBuffer._currentType && packetBuffer._currentSize > 0) ||
|
if ((type != packetBuffer._currentType && packetBuffer._currentSize > 0) ||
|
||||||
(packetBuffer._currentSize + length >= _maxPacketSize)) {
|
(packetBuffer._currentSize + length >= _maxPacketSize)) {
|
||||||
releaseQueuedPacket(packetBuffer);
|
releaseQueuedPacket(packetBuffer);
|
||||||
|
|
||||||
|
qDebug() << "OctreeEditPacketSender::queueOctreeEditMessage()... SWITCHING TYPE...initializePacket()....";
|
||||||
|
|
||||||
initializePacket(packetBuffer, type);
|
initializePacket(packetBuffer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the buffer is empty and not correctly initialized for our type...
|
// If the buffer is empty and not correctly initialized for our type...
|
||||||
if (type != packetBuffer._currentType && packetBuffer._currentSize == 0) {
|
if (type != packetBuffer._currentType && packetBuffer._currentSize == 0) {
|
||||||
|
|
||||||
|
qDebug() << "OctreeEditPacketSender::queueOctreeEditMessage()... SWITCHING TYPE...initializePacket()....";
|
||||||
|
|
||||||
initializePacket(packetBuffer, type);
|
initializePacket(packetBuffer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,12 +296,19 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch
|
||||||
// We call this virtual function that allows our specific type of EditPacketSender to
|
// We call this virtual function that allows our specific type of EditPacketSender to
|
||||||
// fixup the buffer for any clock skew
|
// fixup the buffer for any clock skew
|
||||||
if (node->getClockSkewUsec() != 0) {
|
if (node->getClockSkewUsec() != 0) {
|
||||||
|
qDebug() << "OctreeEditPacketSender::queueOctreeEditMessage()... adjustEditPacketForClockSkew()....";
|
||||||
adjustEditPacketForClockSkew(editPacketBuffer, length, node->getClockSkewUsec());
|
adjustEditPacketForClockSkew(editPacketBuffer, length, node->getClockSkewUsec());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "OctreeEditPacketSender::queueOctreeEditMessage()... memcpy(&packetBuffer...)....";
|
||||||
|
qDebug() << " BEFORE packetBuffer._currentSize=" << packetBuffer._currentSize;
|
||||||
|
|
||||||
memcpy(&packetBuffer._currentBuffer[packetBuffer._currentSize], editPacketBuffer, length);
|
memcpy(&packetBuffer._currentBuffer[packetBuffer._currentSize], editPacketBuffer, length);
|
||||||
packetBuffer._currentSize += length;
|
packetBuffer._currentSize += length;
|
||||||
packetBuffer._satoshiCost += satoshiCost;
|
packetBuffer._satoshiCost += satoshiCost;
|
||||||
|
|
||||||
|
qDebug() << " AFTER packetBuffer._currentSize=" << packetBuffer._currentSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue