diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 2c7b24b5c6..b718729fcb 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -79,7 +79,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f ->getTree()->findClosestParticle(targetPosition, targetRadius); if (closestParticle) { - printf("potentially caught... particle ID:%d\n", closestParticle->getID()); + //printf("potentially caught... particle ID:%d\n", closestParticle->getID()); // you can create a ParticleEditHandle by doing this... ParticleEditHandle* caughtParticle = Application::getInstance()->newParticleEditHandle(closestParticle->getID()); @@ -91,7 +91,6 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // If there's a ball in hand, and the user presses the skinny button, then change the color of the ball int currentControllerButtons = palm.getControllerButtons(); - printf("currentControllerButtons=%d\n",currentControllerButtons); if (currentControllerButtons != _lastControllerButtons && (currentControllerButtons & BUTTON_0)) { _whichBallColor[handID]++; diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index 9f945999b6..25695c5f81 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -35,6 +35,7 @@ Particle::~Particle() { void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, float damping, glm::vec3 gravity, QString updateScript, uint32_t id) { if (id == NEW_PARTICLE) { + _created = usecTimestampNow(); _id = _nextID; _nextID++; } else { @@ -58,6 +59,9 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { //printf("Particle::appendParticleData()... getID()=%d\n", getID()); + if (success) { + success = packetData->appendValue(getCreated()); + } if (success) { success = packetData->appendValue(getLastUpdated()); } @@ -90,7 +94,7 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { } int Particle::expectedBytes() { - int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(float) + + int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(float) + sizeof(glm::vec3) + sizeof(rgbColor) + sizeof(glm::vec3) + sizeof(glm::vec3) + sizeof(float); return expectedBytes; @@ -106,6 +110,11 @@ 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); + // lastupdated memcpy(&_lastUpdated, dataAt, sizeof(_lastUpdated)); dataAt += sizeof(_lastUpdated); @@ -191,6 +200,11 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe newParticle._newlyCreated = false; } + // created + memcpy(&newParticle._created, dataAt, sizeof(newParticle._created)); + dataAt += sizeof(newParticle._created); + processedBytes += sizeof(newParticle._created); + // lastUpdated memcpy(&newParticle._lastUpdated, dataAt, sizeof(newParticle._lastUpdated)); dataAt += sizeof(newParticle._lastUpdated); @@ -248,6 +262,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(" last updated:%llu\n", _lastUpdated); printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z); printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z); @@ -280,7 +295,8 @@ 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)); copyAt += sizeof(details[i].id); @@ -292,8 +308,15 @@ 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); + // lastUpdated memcpy(copyAt, &details[i].lastUpdated, sizeof(details[i].lastUpdated)); copyAt += sizeof(details[i].lastUpdated); @@ -363,7 +386,11 @@ void Particle::update() { // 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; - setShouldDie(velocityScalar < STILL_MOVING); + bool isStillMoving = (velocityScalar > STILL_MOVING); + const uint64_t REALLY_OLD = 30 * 1000 * 1000; + bool isReallyOld = (getLifetime() > REALLY_OLD); + bool shouldDie = !isStillMoving && isReallyOld; + setShouldDie(shouldDie); runScript(); // allow the javascript to alter our state diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 0fed2c80f0..8e754fee39 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -62,6 +62,8 @@ public: const glm::vec3& getVelocity() const { return _velocity; } const glm::vec3& getGravity() const { return _gravity; } float getDamping() const { return _damping; } + uint64_t getCreated() const { return _created; } + uint64_t getLifetime() const { return usecTimestampNow() - _created; } uint64_t getLastUpdated() const { return _lastUpdated; } uint32_t getID() const { return _id; } bool getShouldDie() const { return _shouldDie; } @@ -83,6 +85,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; } bool appendParticleData(OctreePacketData* packetData) const; int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); @@ -106,6 +109,7 @@ protected: float _radius; glm::vec3 _velocity; uint64_t _lastUpdated; + uint64_t _created; uint32_t _id; static uint32_t _nextID; bool _shouldDie; @@ -129,8 +133,11 @@ public slots: glm::vec3 getGravity() const { return _particle->getGravity(); } float getDamping() const { return _particle->getDamping(); } float getRadius() const { return _particle->getRadius(); } - bool setShouldDie() { return _particle->getShouldDie(); } - + 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); } + + void setPosition(glm::vec3 value) { _particle->setPosition(value); } void setVelocity(glm::vec3 value) { _particle->setVelocity(value); } void setGravity(glm::vec3 value) { _particle->setGravity(value); } diff --git a/libraries/particles/src/ParticleTree.cpp b/libraries/particles/src/ParticleTree.cpp index c1fd6d8bbb..2a0b261bef 100644 --- a/libraries/particles/src/ParticleTree.cpp +++ b/libraries/particles/src/ParticleTree.cpp @@ -110,7 +110,9 @@ bool ParticleTree::findNearPointOperation(OctreeElement* element, void* extraDat const Particle* ParticleTree::findClosestParticle(glm::vec3 position, float targetRadius) { // First, look for the existing particle in the tree.. FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX }; + lockForRead(); recurseTreeWithOperation(findNearPointOperation, &args); + unlock(); return args.closestParticle; } diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index df234269d1..6e45f7b62b 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -118,7 +118,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()) { + uint64_t actuallyCreated = particle.getCreated(); + if (!particle.isNewlyCreated()) { + actuallyCreated = _particles[i].getCreated(); + } _particles[i] = particle; + _particles[i].setCreated(actuallyCreated); return true; } } diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 8124822b46..cd6444624f 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -52,6 +52,7 @@ static const float METER = 1.0f; static const float DECIMETER = 0.1f; static const float CENTIMETER = 0.01f; static const float MILLIIMETER = 0.001f; +static const uint64_t USECS_PER_SECOND = 1000 * 1000; uint64_t usecTimestamp(const timeval *time); uint64_t usecTimestampNow();