From 6b0d7c30f0857cef3437c09a08399681a7f32cc5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 16:58:49 -0800 Subject: [PATCH 1/9] added debugging option for forced clock skew --- interface/src/main.cpp | 11 +++++++++++ libraries/shared/src/SharedUtil.cpp | 3 ++- libraries/shared/src/SharedUtil.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 07788fefe0..c348ab6dc3 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -19,11 +19,22 @@ #include #include +#include int main(int argc, const char * argv[]) { timeval startup_time; gettimeofday(&startup_time, NULL); + // Debug option to demonstrate that the client's local time does not + // need to be in sync with any other network node. This forces clock + // skew for the individual client + const char* TIME_ADJUST = "--usecTimestampNowAdjust"; + const char* timeAdjustOption = getCmdOption(argc, argv, TIME_ADJUST); + if (timeAdjustOption) { + ::usecTimestampNowAdjust = atoi(timeAdjustOption); + qDebug("timeAdjustOption=%s usecTimestampNowAdjust=%d\n", timeAdjustOption, ::usecTimestampNowAdjust); + } + int exitCode; { Application app(argc, const_cast(argv), startup_time); diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 9a6bb8b4c3..3d79e7fcc2 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -30,10 +30,11 @@ uint64_t usecTimestamp(const timeval *time) { return (time->tv_sec * 1000000 + time->tv_usec); } +int usecTimestampNowAdjust = 0; uint64_t usecTimestampNow() { timeval now; gettimeofday(&now, NULL); - return (now.tv_sec * 1000000 + now.tv_usec); + return (now.tv_sec * 1000000 + now.tv_usec) + usecTimestampNowAdjust; } float randFloat () { diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index cd6444624f..7752e2e72c 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -56,6 +56,7 @@ static const uint64_t USECS_PER_SECOND = 1000 * 1000; uint64_t usecTimestamp(const timeval *time); uint64_t usecTimestampNow(); +extern int usecTimestampNowAdjust; float randFloat(); int randIntInRange (int min, int max); From 1badc8dc5df5e5c0e7a1afdc82662817eb59195c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 16:59:36 -0800 Subject: [PATCH 2/9] first pass at removing timestamps from particles removed _lastUpdated/getLastUpdated() --- libraries/octree-server/src/OctreeServer.cpp | 10 ++++++ libraries/particles/src/Particle.cpp | 31 ++++--------------- libraries/particles/src/Particle.h | 6 ++-- .../particles/src/ParticleEditHandle.cpp | 4 +-- .../src/ParticleScriptingInterface.cpp | 2 +- .../particles/src/ParticleTreeElement.cpp | 10 ++++-- libraries/shared/src/PacketHeaders.cpp | 2 +- 7 files changed, 30 insertions(+), 35 deletions(-) diff --git a/libraries/octree-server/src/OctreeServer.cpp b/libraries/octree-server/src/OctreeServer.cpp index ffb5f9c976..7ab0705d40 100644 --- a/libraries/octree-server/src/OctreeServer.cpp +++ b/libraries/octree-server/src/OctreeServer.cpp @@ -656,6 +656,16 @@ void OctreeServer::run() { _persistThread->initialize(true); } } + + // Debug option to demonstrate that the server's local time does not + // need to be in sync with any other network node. This forces clock + // skew for the individual server node + const char* TIME_ADJUST = "--usecTimestampNowAdjust"; + const char* timeAdjustOption = getCmdOption(_argc, _argv, TIME_ADJUST); + if (timeAdjustOption) { + ::usecTimestampNowAdjust = atoi(timeAdjustOption); + qDebug("timeAdjustOption=%s usecTimestampNowAdjust=%d\n", timeAdjustOption, ::usecTimestampNowAdjust); + } // Check to see if the user passed in a command line option for setting packet send rate const char* PACKETS_PER_SECOND = "--packetsPerSecond"; diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index fb5d603d7d..beb8203b66 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -42,8 +42,9 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 } else { _id = id; } - _lastUpdated = usecTimestampNow(); - _lastEdited = _lastUpdated; + uint64_t now = usecTimestampNow(); + _lastEdited = now; + _lastSimulated = now; _position = position; _radius = radius; @@ -65,9 +66,6 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { if (success) { success = packetData->appendValue(getCreated()); } - if (success) { - success = packetData->appendValue(getLastUpdated()); - } if (success) { success = packetData->appendValue(getLastEdited()); } @@ -124,11 +122,6 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef dataAt += sizeof(_created); bytesRead += sizeof(_created); - // lastupdated - memcpy(&_lastUpdated, dataAt, sizeof(_lastUpdated)); - dataAt += sizeof(_lastUpdated); - bytesRead += sizeof(_lastUpdated); - // _lastEdited memcpy(&_lastEdited, dataAt, sizeof(_lastEdited)); dataAt += sizeof(_lastEdited); @@ -186,7 +179,7 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef Particle Particle::fromEditPacket(unsigned char* data, int length, int& processedBytes) { - Particle newParticle; // id and lastUpdated will get set here... + Particle newParticle; // id and _lastSimulated will get set here... unsigned char* dataAt = data; processedBytes = 0; @@ -224,11 +217,6 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe dataAt += sizeof(newParticle._created); processedBytes += sizeof(newParticle._created); - // lastUpdated - memcpy(&newParticle._lastUpdated, dataAt, sizeof(newParticle._lastUpdated)); - dataAt += sizeof(newParticle._lastUpdated); - processedBytes += sizeof(newParticle._lastUpdated); - // lastEdited memcpy(&newParticle._lastEdited, dataAt, sizeof(newParticle._lastEdited)); dataAt += sizeof(newParticle._lastEdited); @@ -292,7 +280,6 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe void Particle::debugDump() const { printf("Particle id :%u\n", _id); printf(" created:%llu\n", _created); - printf(" last updated:%llu\n", _lastUpdated); printf(" last edited:%llu\n", _lastEdited); printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z); printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z); @@ -347,11 +334,6 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, copyAt += sizeof(created); sizeOut += sizeof(created); - // lastUpdated - memcpy(copyAt, &details[i].lastUpdated, sizeof(details[i].lastUpdated)); - copyAt += sizeof(details[i].lastUpdated); - sizeOut += sizeof(details[i].lastUpdated); - // lastEdited memcpy(copyAt, &details[i].lastEdited, sizeof(details[i].lastEdited)); copyAt += sizeof(details[i].lastEdited); @@ -405,7 +387,6 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, if (wantDebugging) { printf("encodeParticleEditMessageDetails()....\n"); printf("Particle id :%u\n", details[i].id); - printf(" last updated:%llu\n", details[i].lastUpdated); printf(" nextID:%u\n", _nextID); } } @@ -419,7 +400,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, void Particle::update() { uint64_t now = usecTimestampNow(); - uint64_t elapsed = now - _lastUpdated; + uint64_t elapsed = now - _lastSimulated; uint64_t USECS_PER_SECOND = 1000 * 1000; float timeElapsed = (float)((float)elapsed/(float)USECS_PER_SECOND); @@ -454,7 +435,7 @@ void Particle::update() { //printf("applying damping to Particle timeElapsed=%f\n",timeElapsed); } - _lastUpdated = now; + _lastSimulated = now; } void Particle::runScript() { diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 33e8960670..68e2b10174 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -25,7 +25,6 @@ const uint32_t UNKNOWN_TOKEN = 0xFFFFFFFF; class ParticleDetail { public: uint32_t id; - uint64_t lastUpdated; uint64_t lastEdited; glm::vec3 position; float radius; @@ -70,7 +69,6 @@ public: float getDamping() const { return _damping; } uint64_t getCreated() const { return _created; } uint64_t getLifetime() const { return usecTimestampNow() - _created; } - uint64_t getLastUpdated() const { return _lastUpdated; } uint64_t getLastEdited() const { return _lastEdited; } uint32_t getID() const { return _id; } bool getShouldDie() const { return _shouldDie; } @@ -116,7 +114,6 @@ protected: rgbColor _color; float _radius; glm::vec3 _velocity; - uint64_t _lastUpdated; uint64_t _created; uint64_t _lastEdited; uint32_t _id; @@ -129,6 +126,9 @@ protected: uint32_t _creatorTokenID; bool _newlyCreated; + + uint64_t _lastSimulated; + }; class ParticleScriptObject : public QObject { diff --git a/libraries/particles/src/ParticleEditHandle.cpp b/libraries/particles/src/ParticleEditHandle.cpp index 28356ce63e..88d3143a0f 100644 --- a/libraries/particles/src/ParticleEditHandle.cpp +++ b/libraries/particles/src/ParticleEditHandle.cpp @@ -45,7 +45,7 @@ void ParticleEditHandle::createParticle(glm::vec3 position, float radius, xColor // setup a ParticleDetail struct with the data uint64_t now = usecTimestampNow(); - ParticleDetail addParticleDetail = { NEW_PARTICLE, now, now, + ParticleDetail addParticleDetail = { NEW_PARTICLE, now, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, _creatorTokenID }; @@ -71,7 +71,7 @@ bool ParticleEditHandle::updateParticle(glm::vec3 position, float radius, xColor // setup a ParticleDetail struct with the data uint64_t now = usecTimestampNow(); - ParticleDetail newParticleDetail = { _id, now, now, + ParticleDetail newParticleDetail = { _id, now, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, _creatorTokenID }; diff --git a/libraries/particles/src/ParticleScriptingInterface.cpp b/libraries/particles/src/ParticleScriptingInterface.cpp index ec8209208c..8edfae3b88 100644 --- a/libraries/particles/src/ParticleScriptingInterface.cpp +++ b/libraries/particles/src/ParticleScriptingInterface.cpp @@ -23,7 +23,7 @@ unsigned int ParticleScriptingInterface::queueParticleAdd(glm::vec3 position, fl // setup a ParticleDetail struct with the data uint64_t now = usecTimestampNow(); - ParticleDetail addParticleDetail = { NEW_PARTICLE, now, now, + ParticleDetail addParticleDetail = { NEW_PARTICLE, now, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, creatorTokenID }; diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index a631eae926..9ab0a2b4e9 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -119,18 +119,20 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) { uint16_t numberOfParticles = _particles.size(); for (uint16_t i = 0; i < numberOfParticles; i++) { if (_particles[i].getID() == particle.getID()) { - int difference = _particles[i].getLastUpdated() - particle.getLastUpdated(); + //int difference = _particles[i].getLastUpdated() - particle.getLastUpdated(); + //bool localOlder = _particles[i].getLastUpdated() < particle.getLastUpdated(); bool changedOnServer = _particles[i].getLastEdited() < particle.getLastEdited(); - bool localOlder = _particles[i].getLastUpdated() < particle.getLastUpdated(); - if (changedOnServer || localOlder) { + if (changedOnServer /*|| localOlder*/) { if (wantDebug) { + /** printf("local particle [id:%d] %s and %s than server particle by %d, particle.isNewlyCreated()=%s\n", particle.getID(), (changedOnServer ? "CHANGED" : "same"), (localOlder ? "OLDER" : "NEWER"), difference, debug::valueOf(particle.isNewlyCreated()) ); + **/ } uint64_t actuallyCreated = particle.getCreated(); @@ -141,11 +143,13 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) { _particles[i].setCreated(actuallyCreated); } else { if (wantDebug) { + /** printf(">>> NO CHANGE <<< -- local particle [id:%d] %s and %s than server particle by %d, " "particle.isNewlyCreated()=%s\n", particle.getID(), (changedOnServer ? "CHANGED" : "same"), (localOlder ? "OLDER" : "NEWER"), difference, debug::valueOf(particle.isNewlyCreated()) ); + **/ } } return true; diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index e7c16367aa..24865fff5c 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -54,7 +54,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) { return 2; case PACKET_TYPE_PARTICLE_DATA: - return 3; + return 4; default: return 0; From 8b1c39a47168d726b4d72f5a8fd0e232f9d8539d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 17:03:53 -0800 Subject: [PATCH 3/9] more lastUpdated-ectomy --- .../particles/src/ParticleTreeElement.cpp | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index 9ab0a2b4e9..6905bb7021 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -119,20 +119,12 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) { uint16_t numberOfParticles = _particles.size(); for (uint16_t i = 0; i < numberOfParticles; i++) { if (_particles[i].getID() == particle.getID()) { - //int difference = _particles[i].getLastUpdated() - particle.getLastUpdated(); - //bool localOlder = _particles[i].getLastUpdated() < particle.getLastUpdated(); - bool changedOnServer = _particles[i].getLastEdited() < particle.getLastEdited(); - - if (changedOnServer /*|| localOlder*/) { - + if (changedOnServer) { if (wantDebug) { - /** - printf("local particle [id:%d] %s and %s than server particle by %d, particle.isNewlyCreated()=%s\n", + printf("local particle [id:%d] %s, particle.isNewlyCreated()=%s\n", particle.getID(), (changedOnServer ? "CHANGED" : "same"), - (localOlder ? "OLDER" : "NEWER"), - difference, debug::valueOf(particle.isNewlyCreated()) ); - **/ + debug::valueOf(particle.isNewlyCreated()) ); } uint64_t actuallyCreated = particle.getCreated(); @@ -143,13 +135,9 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) { _particles[i].setCreated(actuallyCreated); } else { if (wantDebug) { - /** - printf(">>> NO CHANGE <<< -- local particle [id:%d] %s and %s than server particle by %d, " - "particle.isNewlyCreated()=%s\n", + printf(">>> NO CHANGE <<< -- local particle [id:%d] %s particle.isNewlyCreated()=%s\n", particle.getID(), (changedOnServer ? "CHANGED" : "same"), - (localOlder ? "OLDER" : "NEWER"), - difference, debug::valueOf(particle.isNewlyCreated()) ); - **/ + debug::valueOf(particle.isNewlyCreated()) ); } } return true; From c68a226094763c45b6d0c32b9cb5950210e8a475 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 17:43:48 -0800 Subject: [PATCH 4/9] removing of created timestamp from wire format, still supports lifetime --- libraries/particles/src/Particle.cpp | 55 ++++++++++--------- libraries/particles/src/Particle.h | 12 ++-- .../particles/src/ParticleTreeElement.cpp | 6 +- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index beb8203b66..d68a55ce3b 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -36,7 +36,6 @@ Particle::~Particle() { void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, bool inHand, QString updateScript, uint32_t id) { if (id == NEW_PARTICLE) { - _created = usecTimestampNow(); _id = _nextID; _nextID++; } else { @@ -45,7 +44,8 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 uint64_t now = usecTimestampNow(); _lastEdited = now; _lastSimulated = now; - + _created = now; // will get updated as appropriate in setLifetime() + _position = position; _radius = radius; memcpy(_color, color, sizeof(_color)); @@ -64,7 +64,7 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { //printf("Particle::appendParticleData()... getID()=%d\n", getID()); if (success) { - success = packetData->appendValue(getCreated()); + success = packetData->appendValue(getLifetime()); } if (success) { success = packetData->appendValue(getLastEdited()); @@ -101,9 +101,17 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { } int Particle::expectedBytes() { - int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(float) + - sizeof(glm::vec3) + sizeof(rgbColor) + sizeof(glm::vec3) + - sizeof(glm::vec3) + sizeof(float) + sizeof(bool); + int expectedBytes = sizeof(uint32_t) // id + + sizeof(float) // lifetime + + sizeof(uint64_t) // lastedited + + sizeof(float) // radius + + sizeof(glm::vec3) // position + + sizeof(rgbColor) // color + + sizeof(glm::vec3) // velocity + + sizeof(glm::vec3) // gravity + + sizeof(float) // damping + + sizeof(bool); // inhand + // potentially more... return expectedBytes; } @@ -117,10 +125,12 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef dataAt += sizeof(_id); bytesRead += sizeof(_id); - // created - memcpy(&_created, dataAt, sizeof(_created)); - dataAt += sizeof(_created); - bytesRead += sizeof(_created); + // lifetime + float lifetime; + memcpy(&lifetime, dataAt, sizeof(lifetime)); + dataAt += sizeof(lifetime); + bytesRead += sizeof(lifetime); + setLifetime(lifetime); // _lastEdited memcpy(&_lastEdited, dataAt, sizeof(_lastEdited)); @@ -207,16 +217,14 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe processedBytes += sizeof(creatorTokenID); newParticle.setCreatorTokenID(creatorTokenID); newParticle._newlyCreated = true; + + newParticle.setLifetime(0); // this guy is new! + } else { newParticle._id = editID; newParticle._newlyCreated = false; } - // created - memcpy(&newParticle._created, dataAt, sizeof(newParticle._created)); - dataAt += sizeof(newParticle._created); - processedBytes += sizeof(newParticle._created); - // lastEdited memcpy(&newParticle._lastEdited, dataAt, sizeof(newParticle._lastEdited)); dataAt += sizeof(newParticle._lastEdited); @@ -279,7 +287,7 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe void Particle::debugDump() const { printf("Particle id :%u\n", _id); - printf(" created:%llu\n", _created); + printf(" lifetime:%f\n", getLifetime()); printf(" last edited:%llu\n", _lastEdited); printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z); printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z); @@ -312,7 +320,6 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, sizeOut += lengthOfOctcode; // Now add our edit content details... - uint64_t created = usecTimestampNow(); // id memcpy(copyAt, &details[i].id, sizeof(details[i].id)); @@ -325,15 +332,8 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, memcpy(copyAt, &details[i].creatorTokenID, sizeof(details[i].creatorTokenID)); copyAt += sizeof(details[i].creatorTokenID); sizeOut += sizeof(details[i].creatorTokenID); - } else { - created = 0; } - // created - memcpy(copyAt, &created, sizeof(created)); - copyAt += sizeof(created); - sizeOut += sizeof(created); - // lastEdited memcpy(copyAt, &details[i].lastEdited, sizeof(details[i].lastEdited)); copyAt += sizeof(details[i].lastEdited); @@ -413,7 +413,7 @@ void Particle::update() { bool isInHand = getInHand(); bool shouldDie = !isInHand && !isStillMoving && isReallyOld; setShouldDie(shouldDie); - + runScript(); // allow the javascript to alter our state // If the ball is in hand, it doesn't move or have gravity effect it @@ -465,3 +465,8 @@ void Particle::runScript() { } } } + +void Particle::setLifetime(float lifetime) { + uint64_t lifetimeInUsecs = lifetime * USECS_PER_SECOND; + _created = usecTimestampNow() - lifetimeInUsecs; +} diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 68e2b10174..aa884762ad 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -67,8 +67,10 @@ public: const glm::vec3& getGravity() const { return _gravity; } bool getInHand() const { return _inHand; } float getDamping() const { return _damping; } - uint64_t getCreated() const { return _created; } - uint64_t getLifetime() const { return usecTimestampNow() - _created; } + + /// lifetime of the particle in seconds + float getLifetime() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; } + uint64_t getLastEdited() const { return _lastEdited; } uint32_t getID() const { return _id; } bool getShouldDie() const { return _shouldDie; } @@ -91,7 +93,7 @@ public: void setShouldDie(bool shouldDie) { _shouldDie = shouldDie; } void setUpdateScript(QString updateScript) { _updateScript = updateScript; } void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; } - void setCreated(uint64_t created) { _created = created; } + void setLifetime(float lifetime); bool appendParticleData(OctreePacketData* packetData) const; int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); @@ -144,8 +146,8 @@ public slots: float getDamping() const { return _particle->getDamping(); } float getRadius() const { return _particle->getRadius(); } bool getShouldDie() { return _particle->getShouldDie(); } - float getCreated() const { return ((float)_particle->getCreated() / (float)USECS_PER_SECOND); } - float getLifetime() const { return ((float)_particle->getLifetime() / (float)USECS_PER_SECOND); } + //float getCreated() const { return ((float)_particle->getCreated() / (float)USECS_PER_SECOND); } + float getLifetime() const { return _particle->getLifetime(); } void setPosition(glm::vec3 value) { _particle->setPosition(value); } diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index 6905bb7021..3d9f208408 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -127,12 +127,12 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) { debug::valueOf(particle.isNewlyCreated()) ); } - uint64_t actuallyCreated = particle.getCreated(); + float actualLifetime = particle.getLifetime(); if (!particle.isNewlyCreated()) { - actuallyCreated = _particles[i].getCreated(); + actualLifetime = _particles[i].getLifetime(); } _particles[i] = particle; - _particles[i].setCreated(actuallyCreated); + _particles[i].setLifetime(actualLifetime); } else { if (wantDebug) { printf(">>> NO CHANGE <<< -- local particle [id:%d] %s particle.isNewlyCreated()=%s\n", From 920ef65ccbbeffca4f570c766cff152554f02fa1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 19:01:42 -0800 Subject: [PATCH 5/9] removed _lastedEdited changed to editedAgo --- libraries/particles/src/Particle.cpp | 51 +++++++++++-------- libraries/particles/src/Particle.h | 20 +++++--- .../particles/src/ParticleEditHandle.cpp | 6 +-- .../src/ParticleScriptingInterface.cpp | 3 +- .../particles/src/ParticleTreeElement.cpp | 10 +--- 5 files changed, 49 insertions(+), 41 deletions(-) diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index d68a55ce3b..3f231ac483 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -42,7 +42,7 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 _id = id; } uint64_t now = usecTimestampNow(); - _lastEdited = now; + _edited = now; _lastSimulated = now; _created = now; // will get updated as appropriate in setLifetime() @@ -67,7 +67,7 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { success = packetData->appendValue(getLifetime()); } if (success) { - success = packetData->appendValue(getLastEdited()); + success = packetData->appendValue(getEditedAgo()); } if (success) { success = packetData->appendValue(getRadius()); @@ -103,7 +103,7 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { int Particle::expectedBytes() { int expectedBytes = sizeof(uint32_t) // id + sizeof(float) // lifetime - + sizeof(uint64_t) // lastedited + + sizeof(float) // edited ago + sizeof(float) // radius + sizeof(glm::vec3) // position + sizeof(rgbColor) // color @@ -132,10 +132,12 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef bytesRead += sizeof(lifetime); setLifetime(lifetime); - // _lastEdited - memcpy(&_lastEdited, dataAt, sizeof(_lastEdited)); - dataAt += sizeof(_lastEdited); - bytesRead += sizeof(_lastEdited); + // edited ago + float editedAgo; + memcpy(&editedAgo, dataAt, sizeof(editedAgo)); + dataAt += sizeof(editedAgo); + bytesRead += sizeof(editedAgo); + setEditedAgo(editedAgo); // radius memcpy(&_radius, dataAt, sizeof(_radius)); @@ -225,11 +227,9 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe newParticle._newlyCreated = false; } - // lastEdited - memcpy(&newParticle._lastEdited, dataAt, sizeof(newParticle._lastEdited)); - dataAt += sizeof(newParticle._lastEdited); - processedBytes += sizeof(newParticle._lastEdited); - + // clearly we just edited it + newParticle.setEditedAgo(0); + // radius memcpy(&newParticle._radius, dataAt, sizeof(newParticle._radius)); dataAt += sizeof(newParticle._radius); @@ -288,7 +288,7 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe void Particle::debugDump() const { printf("Particle id :%u\n", _id); printf(" lifetime:%f\n", getLifetime()); - printf(" last edited:%llu\n", _lastEdited); + printf(" edited ago:%f\n", getEditedAgo()); printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z); printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z); printf(" gravity:%f,%f,%f\n", _gravity.x, _gravity.y, _gravity.z); @@ -334,11 +334,6 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, sizeOut += sizeof(details[i].creatorTokenID); } - // lastEdited - memcpy(copyAt, &details[i].lastEdited, sizeof(details[i].lastEdited)); - copyAt += sizeof(details[i].lastEdited); - sizeOut += sizeof(details[i].lastEdited); - // radius memcpy(copyAt, &details[i].radius, sizeof(details[i].radius)); copyAt += sizeof(details[i].radius); @@ -399,20 +394,25 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, void Particle::update() { + uint64_t now = usecTimestampNow(); uint64_t elapsed = now - _lastSimulated; - uint64_t USECS_PER_SECOND = 1000 * 1000; float timeElapsed = (float)((float)elapsed/(float)USECS_PER_SECOND); + // calculate our default shouldDie state... then allow script to change it if it wants... float velocityScalar = glm::length(getVelocity()); const float STILL_MOVING = 0.05 / TREE_SCALE; bool isStillMoving = (velocityScalar > STILL_MOVING); - const uint64_t REALLY_OLD = 30 * 1000 * 1000; + const float REALLY_OLD = 300.0f; // 300 seconds bool isReallyOld = (getLifetime() > REALLY_OLD); bool isInHand = getInHand(); bool shouldDie = !isInHand && !isStillMoving && isReallyOld; setShouldDie(shouldDie); + +printf("Particle::update()... timeElapsed: %f lifeTime:%f editedAgo:%f isInHand:%s isStillMoveing:%s isReallyOld:%s shouldDie:%s\n", + timeElapsed, getLifetime(), getEditedAgo(), debug::valueOf(isInHand), debug::valueOf(isStillMoving), + debug::valueOf(isReallyOld), debug::valueOf(shouldDie)); runScript(); // allow the javascript to alter our state @@ -470,3 +470,14 @@ void Particle::setLifetime(float lifetime) { uint64_t lifetimeInUsecs = lifetime * USECS_PER_SECOND; _created = usecTimestampNow() - lifetimeInUsecs; } + +void Particle::setEditedAgo(float editedAgo) { + uint64_t editedAgoInUsecs = editedAgo * USECS_PER_SECOND; + _edited = usecTimestampNow() - editedAgoInUsecs; +} + +void Particle::copyChangedProperties(const Particle& other) { + float lifetime = getLifetime(); + *this = other; + setLifetime(lifetime); +} diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index aa884762ad..e818a2e91d 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -25,7 +25,6 @@ const uint32_t UNKNOWN_TOKEN = 0xFFFFFFFF; class ParticleDetail { public: uint32_t id; - uint64_t lastEdited; glm::vec3 position; float radius; rgbColor color; @@ -70,8 +69,8 @@ public: /// lifetime of the particle in seconds float getLifetime() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; } - - uint64_t getLastEdited() const { return _lastEdited; } + /// seconds since last edited + float getEditedAgo() const { return (float)(usecTimestampNow() - _edited) / (float)USECS_PER_SECOND; } uint32_t getID() const { return _id; } bool getShouldDie() const { return _shouldDie; } QString getUpdateScript() const { return _updateScript; } @@ -93,7 +92,6 @@ public: void setShouldDie(bool shouldDie) { _shouldDie = shouldDie; } void setUpdateScript(QString updateScript) { _updateScript = updateScript; } void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; } - void setLifetime(float lifetime); bool appendParticleData(OctreePacketData* packetData) const; int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); @@ -105,19 +103,24 @@ public: void update(); void debugDump() const; + + // similar to an assignment, but it handles no breaking lifetime and editedAgo + void copyChangedProperties(const Particle& other); + protected: void runScript(); static QScriptValue vec3toScriptValue(QScriptEngine *engine, const glm::vec3 &vec3); static void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3); static QScriptValue xColorToScriptValue(QScriptEngine *engine, const xColor& color); static void xColorFromScriptValue(const QScriptValue &object, xColor& color); + + void setLifetime(float lifetime); + void setEditedAgo(float editedAgo); glm::vec3 _position; rgbColor _color; float _radius; glm::vec3 _velocity; - uint64_t _created; - uint64_t _lastEdited; uint32_t _id; static uint32_t _nextID; bool _shouldDie; @@ -128,8 +131,11 @@ protected: uint32_t _creatorTokenID; bool _newlyCreated; - + + // these are never included in wire time uint64_t _lastSimulated; + uint64_t _created; + uint64_t _edited; }; diff --git a/libraries/particles/src/ParticleEditHandle.cpp b/libraries/particles/src/ParticleEditHandle.cpp index 88d3143a0f..d8466816c4 100644 --- a/libraries/particles/src/ParticleEditHandle.cpp +++ b/libraries/particles/src/ParticleEditHandle.cpp @@ -44,8 +44,7 @@ void ParticleEditHandle::createParticle(glm::vec3 position, float radius, xColor glm::vec3 gravity, float damping, bool inHand, QString updateScript) { // setup a ParticleDetail struct with the data - uint64_t now = usecTimestampNow(); - ParticleDetail addParticleDetail = { NEW_PARTICLE, now, + ParticleDetail addParticleDetail = { NEW_PARTICLE, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, _creatorTokenID }; @@ -70,8 +69,7 @@ bool ParticleEditHandle::updateParticle(glm::vec3 position, float radius, xColor } // setup a ParticleDetail struct with the data - uint64_t now = usecTimestampNow(); - ParticleDetail newParticleDetail = { _id, now, + ParticleDetail newParticleDetail = { _id, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, _creatorTokenID }; diff --git a/libraries/particles/src/ParticleScriptingInterface.cpp b/libraries/particles/src/ParticleScriptingInterface.cpp index 8edfae3b88..758b50035d 100644 --- a/libraries/particles/src/ParticleScriptingInterface.cpp +++ b/libraries/particles/src/ParticleScriptingInterface.cpp @@ -22,8 +22,7 @@ unsigned int ParticleScriptingInterface::queueParticleAdd(glm::vec3 position, fl _nextCreatorTokenID++; // setup a ParticleDetail struct with the data - uint64_t now = usecTimestampNow(); - ParticleDetail addParticleDetail = { NEW_PARTICLE, now, + ParticleDetail addParticleDetail = { NEW_PARTICLE, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, creatorTokenID }; diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index 3d9f208408..b142c1f568 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -119,20 +119,14 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) { uint16_t numberOfParticles = _particles.size(); for (uint16_t i = 0; i < numberOfParticles; i++) { if (_particles[i].getID() == particle.getID()) { - bool changedOnServer = _particles[i].getLastEdited() < particle.getLastEdited(); + bool changedOnServer = _particles[i].getEditedAgo() > particle.getEditedAgo(); if (changedOnServer) { if (wantDebug) { printf("local particle [id:%d] %s, particle.isNewlyCreated()=%s\n", particle.getID(), (changedOnServer ? "CHANGED" : "same"), debug::valueOf(particle.isNewlyCreated()) ); } - - float actualLifetime = particle.getLifetime(); - if (!particle.isNewlyCreated()) { - actualLifetime = _particles[i].getLifetime(); - } - _particles[i] = particle; - _particles[i].setLifetime(actualLifetime); + _particles[i].copyChangedProperties(particle); } else { if (wantDebug) { printf(">>> NO CHANGE <<< -- local particle [id:%d] %s particle.isNewlyCreated()=%s\n", From c6933239d9c2c1419c845f70194f2ff33ff8c554 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 19:21:30 -0800 Subject: [PATCH 6/9] fixed comment --- libraries/particles/src/Particle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index e818a2e91d..051f9bf59d 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -104,7 +104,7 @@ public: void debugDump() const; - // similar to an assignment, but it handles no breaking lifetime and editedAgo + // similar to assignment/copy, but it handles keeping lifetime accurate void copyChangedProperties(const Particle& other); protected: From 6e2c0032b5c6ed1189ebcbd11a32b748eac2eadc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 19:22:15 -0800 Subject: [PATCH 7/9] removed dead code --- libraries/particles/src/Particle.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 051f9bf59d..995a8675ce 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -152,10 +152,8 @@ public slots: float getDamping() const { return _particle->getDamping(); } float getRadius() const { return _particle->getRadius(); } bool getShouldDie() { return _particle->getShouldDie(); } - //float getCreated() const { return ((float)_particle->getCreated() / (float)USECS_PER_SECOND); } float getLifetime() const { return _particle->getLifetime(); } - void setPosition(glm::vec3 value) { _particle->setPosition(value); } void setVelocity(glm::vec3 value) { _particle->setVelocity(value); } void setGravity(glm::vec3 value) { _particle->setGravity(value); } From 5b36953e8187359fdeea140ac8767df6df97f43e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 19:33:52 -0800 Subject: [PATCH 8/9] cleanup clockSkew debug options and remove some chatty logs --- interface/src/main.cpp | 11 ++++++----- libraries/octree-server/src/OctreeServer.cpp | 11 ++++++----- libraries/particles/src/Particle.cpp | 12 ++++++++---- libraries/shared/src/SharedUtil.cpp | 6 +++++- libraries/shared/src/SharedUtil.h | 2 +- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index c348ab6dc3..7a5703a881 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -28,11 +28,12 @@ int main(int argc, const char * argv[]) { // Debug option to demonstrate that the client's local time does not // need to be in sync with any other network node. This forces clock // skew for the individual client - const char* TIME_ADJUST = "--usecTimestampNowAdjust"; - const char* timeAdjustOption = getCmdOption(argc, argv, TIME_ADJUST); - if (timeAdjustOption) { - ::usecTimestampNowAdjust = atoi(timeAdjustOption); - qDebug("timeAdjustOption=%s usecTimestampNowAdjust=%d\n", timeAdjustOption, ::usecTimestampNowAdjust); + const char* CLOCK_SKEW = "--clockSkew"; + const char* clockSkewOption = getCmdOption(argc, argv, CLOCK_SKEW); + if (clockSkewOption) { + int clockSkew = atoi(clockSkewOption); + usecTimestampNowForceClockSkew(clockSkew); + qDebug("clockSkewOption=%s clockSkew=%d\n", clockSkewOption, clockSkew); } int exitCode; diff --git a/libraries/octree-server/src/OctreeServer.cpp b/libraries/octree-server/src/OctreeServer.cpp index 7ab0705d40..a8010cefaf 100644 --- a/libraries/octree-server/src/OctreeServer.cpp +++ b/libraries/octree-server/src/OctreeServer.cpp @@ -660,11 +660,12 @@ void OctreeServer::run() { // Debug option to demonstrate that the server's local time does not // need to be in sync with any other network node. This forces clock // skew for the individual server node - const char* TIME_ADJUST = "--usecTimestampNowAdjust"; - const char* timeAdjustOption = getCmdOption(_argc, _argv, TIME_ADJUST); - if (timeAdjustOption) { - ::usecTimestampNowAdjust = atoi(timeAdjustOption); - qDebug("timeAdjustOption=%s usecTimestampNowAdjust=%d\n", timeAdjustOption, ::usecTimestampNowAdjust); + const char* CLOCK_SKEW = "--clockSkew"; + const char* clockSkewOption = getCmdOption(_argc, _argv, CLOCK_SKEW); + if (clockSkewOption) { + int clockSkew = atoi(clockSkewOption); + usecTimestampNowForceClockSkew(clockSkew); + qDebug("clockSkewOption=%s clockSkew=%d\n", clockSkewOption, clockSkew); } // Check to see if the user passed in a command line option for setting packet send rate diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index 3f231ac483..c2f86c7b75 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -409,11 +409,15 @@ void Particle::update() { bool isInHand = getInHand(); bool shouldDie = !isInHand && !isStillMoving && isReallyOld; setShouldDie(shouldDie); - -printf("Particle::update()... timeElapsed: %f lifeTime:%f editedAgo:%f isInHand:%s isStillMoveing:%s isReallyOld:%s shouldDie:%s\n", - timeElapsed, getLifetime(), getEditedAgo(), debug::valueOf(isInHand), debug::valueOf(isStillMoving), - debug::valueOf(isReallyOld), debug::valueOf(shouldDie)); + bool wantDebug = false; + if (wantDebug) { + printf("Particle::update()... timeElapsed: %f lifeTime:%f editedAgo:%f " + "isInHand:%s isStillMoveing:%s isReallyOld:%s shouldDie:%s\n", + timeElapsed, getLifetime(), getEditedAgo(), debug::valueOf(isInHand), debug::valueOf(isStillMoving), + debug::valueOf(isReallyOld), debug::valueOf(shouldDie)); + } + runScript(); // allow the javascript to alter our state // If the ball is in hand, it doesn't move or have gravity effect it diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 3d79e7fcc2..4d178a6ee9 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -31,10 +31,14 @@ uint64_t usecTimestamp(const timeval *time) { } int usecTimestampNowAdjust = 0; +void usecTimestampNowForceClockSkew(int clockSkew) { + ::usecTimestampNowAdjust = clockSkew; +} + uint64_t usecTimestampNow() { timeval now; gettimeofday(&now, NULL); - return (now.tv_sec * 1000000 + now.tv_usec) + usecTimestampNowAdjust; + return (now.tv_sec * 1000000 + now.tv_usec) + ::usecTimestampNowAdjust; } float randFloat () { diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 7752e2e72c..893922ec28 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -56,7 +56,7 @@ static const uint64_t USECS_PER_SECOND = 1000 * 1000; uint64_t usecTimestamp(const timeval *time); uint64_t usecTimestampNow(); -extern int usecTimestampNowAdjust; +void usecTimestampNowForceClockSkew(int clockSkew); float randFloat(); int randIntInRange (int min, int max); From 95df772707b77b371f66f81a9b4592ff90ca0944 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 18 Dec 2013 19:36:34 -0800 Subject: [PATCH 9/9] make really old 30 seconds not 300 --- libraries/particles/src/Particle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index c2f86c7b75..9248bf540f 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -404,7 +404,7 @@ void Particle::update() { float velocityScalar = glm::length(getVelocity()); const float STILL_MOVING = 0.05 / TREE_SCALE; bool isStillMoving = (velocityScalar > STILL_MOVING); - const float REALLY_OLD = 300.0f; // 300 seconds + const float REALLY_OLD = 30.0f; // 30 seconds bool isReallyOld = (getLifetime() > REALLY_OLD); bool isInHand = getInHand(); bool shouldDie = !isInHand && !isStillMoving && isReallyOld;