From 1a6f7306594db61ffbf38c7aae291cd220a21bdb Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 12 Dec 2013 12:24:07 -0800 Subject: [PATCH 1/3] add findClosestParticle() --- interface/src/Application.h | 1 + interface/src/avatar/Hand.cpp | 16 +++++- libraries/particles/src/ParticleTree.cpp | 51 +++++++++++++++++++ libraries/particles/src/ParticleTree.h | 2 + .../particles/src/ParticleTreeElement.cpp | 13 +++++ libraries/particles/src/ParticleTreeElement.h | 1 + 6 files changed, 82 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 38c8ea4f64..601bec8573 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -141,6 +141,7 @@ public: Camera* getCamera() { return &_myCamera; } ViewFrustum* getViewFrustum() { return &_viewFrustum; } VoxelSystem* getVoxels() { return &_voxels; } + ParticleTreeRenderer* getParticles() { return &_particles; } VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; } VoxelTree* getClipboard() { return &_clipboard; } Environment* getEnvironment() { return &_environment; } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index a085a42953..692ce74d7c 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -61,6 +61,16 @@ void Hand::reset() { } void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) { + + glm::vec3 targetPosition = fingerTipPosition / (float)TREE_SCALE; + float targetRadius = (TOY_BALL_RADIUS * 2.0f) / (float)TREE_SCALE; + const Particle* closestParticle = Application::getInstance()->getParticles() + ->getTree()->findClosestPartice(targetPosition, targetRadius); + + if (closestParticle) { + printf("potentially caught... particle ID:%d\n", closestParticle->getID()); + } + // Is the controller button being held down.... if (palm.getControllerButtons() & BUTTON_FWD) { // If grabbing toy ball, add forces to it. @@ -71,8 +81,10 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // isCaught is also used as "creating" a new ball... for now, this section is the // create new ball portion of the code... - bool isCaught = true; - if (isCaught) { + bool isCaught = false; + + // If we didn't catch something, then create a new ball.... + if (!isCaught) { _toyBallInHand = true; _hasToyBall = true; diff --git a/libraries/particles/src/ParticleTree.cpp b/libraries/particles/src/ParticleTree.cpp index 9d36c72f4a..d0fa672887 100644 --- a/libraries/particles/src/ParticleTree.cpp +++ b/libraries/particles/src/ParticleTree.cpp @@ -64,6 +64,57 @@ void ParticleTree::storeParticle(const Particle& particle) { _isDirty = true; } +class FindNearPointArgs { +public: + glm::vec3 position; + float targetRadius; + bool found; + const Particle* closestParticle; + float closestParticleDistance; +}; + + +bool ParticleTree::findNearPointOperation(OctreeElement* element, void* extraData) { + FindNearPointArgs* args = static_cast(extraData); + ParticleTreeElement* particleTreeElement = static_cast(element); + + + // If this particleTreeElement contains the point, then search it... + if (particleTreeElement->getAABox().contains(args->position)) { + const Particle* thisClosestParticle = particleTreeElement->getClosestParticle(args->position); + + // we may have gotten NULL back, meaning no particle was available + if (thisClosestParticle) { + glm::vec3 particlePosition = thisClosestParticle->getPosition(); + float distanceFromPointToParticle = glm::distance(particlePosition, args->position); + + // If we're within our target radius + if (distanceFromPointToParticle <= args->targetRadius) { + // we are closer than anything else we've found + if (distanceFromPointToParticle < args->closestParticleDistance) { + args->closestParticle = thisClosestParticle; + args->closestParticleDistance = distanceFromPointToParticle; + args->found = true; + } + } + } + + // we should be able to optimize this... + return true; // keep searching in case children have closer particles + } + + // if this element doesn't contain the point, then none of it's children can contain the point, so stop searching + return false; +} + +const Particle* ParticleTree::findClosestPartice(glm::vec3 position, float targetRadius) { + // First, look for the existing particle in the tree.. + FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX }; + recurseTreeWithOperation(findNearPointOperation, &args); + return args.closestParticle; +} + + int ParticleTree::processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength, unsigned char* editData, int maxLength, Node* senderNode) { diff --git a/libraries/particles/src/ParticleTree.h b/libraries/particles/src/ParticleTree.h index cde0bb60f7..a43dd45913 100644 --- a/libraries/particles/src/ParticleTree.h +++ b/libraries/particles/src/ParticleTree.h @@ -43,6 +43,7 @@ public: virtual void update(); void storeParticle(const Particle& particle); + const Particle* findClosestPartice(glm::vec3 position, float targetRadius); void addNewlyCreatedHook(NewlyCreatedParticleHook* hook); void removeNewlyCreatedHook(NewlyCreatedParticleHook* hook); @@ -51,6 +52,7 @@ private: static bool updateOperation(OctreeElement* element, void* extraData); static bool findAndUpdateOperation(OctreeElement* element, void* extraData); + static bool findNearPointOperation(OctreeElement* element, void* extraData); void notifyNewlyCreatedParticle(const Particle& newParticle, Node* senderNode); diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index 2d2d000eaa..a997dd1480 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -104,6 +104,19 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) { return false; } +const Particle* ParticleTreeElement::getClosestParticle(glm::vec3 position) const { + const Particle* closestParticle = NULL; + float closestParticleDistance = FLT_MAX; + uint16_t numberOfParticles = _particles.size(); + for (uint16_t i = 0; i < numberOfParticles; i++) { + float distanceToParticle = glm::distance(position, _particles[i].getPosition()); + if (distanceToParticle < closestParticleDistance) { + closestParticle = &_particles[i]; + } + } + return closestParticle; +} + int ParticleTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) { diff --git a/libraries/particles/src/ParticleTreeElement.h b/libraries/particles/src/ParticleTreeElement.h index a61ec854dd..292e0fe745 100644 --- a/libraries/particles/src/ParticleTreeElement.h +++ b/libraries/particles/src/ParticleTreeElement.h @@ -80,6 +80,7 @@ public: bool containsParticle(const Particle& particle) const; bool updateParticle(const Particle& particle); + const Particle* getClosestParticle(glm::vec3 position) const; protected: void storeParticle(const Particle& particle); From cd830efdd47d420b1464b4aa934ca34c14755c22 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 12 Dec 2013 12:26:12 -0800 Subject: [PATCH 2/3] fixed typo --- interface/src/avatar/Hand.cpp | 2 +- libraries/particles/src/ParticleTree.cpp | 2 +- libraries/particles/src/ParticleTree.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 692ce74d7c..00ddc4d301 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -65,7 +65,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f glm::vec3 targetPosition = fingerTipPosition / (float)TREE_SCALE; float targetRadius = (TOY_BALL_RADIUS * 2.0f) / (float)TREE_SCALE; const Particle* closestParticle = Application::getInstance()->getParticles() - ->getTree()->findClosestPartice(targetPosition, targetRadius); + ->getTree()->findClosestParticle(targetPosition, targetRadius); if (closestParticle) { printf("potentially caught... particle ID:%d\n", closestParticle->getID()); diff --git a/libraries/particles/src/ParticleTree.cpp b/libraries/particles/src/ParticleTree.cpp index d0fa672887..152f1dec69 100644 --- a/libraries/particles/src/ParticleTree.cpp +++ b/libraries/particles/src/ParticleTree.cpp @@ -107,7 +107,7 @@ bool ParticleTree::findNearPointOperation(OctreeElement* element, void* extraDat return false; } -const Particle* ParticleTree::findClosestPartice(glm::vec3 position, float targetRadius) { +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 }; recurseTreeWithOperation(findNearPointOperation, &args); diff --git a/libraries/particles/src/ParticleTree.h b/libraries/particles/src/ParticleTree.h index a43dd45913..2491934252 100644 --- a/libraries/particles/src/ParticleTree.h +++ b/libraries/particles/src/ParticleTree.h @@ -43,7 +43,7 @@ public: virtual void update(); void storeParticle(const Particle& particle); - const Particle* findClosestPartice(glm::vec3 position, float targetRadius); + const Particle* findClosestParticle(glm::vec3 position, float targetRadius); void addNewlyCreatedHook(NewlyCreatedParticleHook* hook); void removeNewlyCreatedHook(NewlyCreatedParticleHook* hook); From 50b93d1e2ba7e8e415e541d8cde22933b2ad411d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 12 Dec 2013 12:40:38 -0800 Subject: [PATCH 3/3] added easy access to creating a ParticleEditHandle for a know particle ID --- interface/src/Application.cpp | 8 +++++++- interface/src/Application.h | 1 + interface/src/avatar/Hand.cpp | 6 ++++++ libraries/particles/src/Particle.h | 2 ++ .../particles/src/ParticleEditHandle.cpp | 19 +++++++++++++------ libraries/particles/src/ParticleEditHandle.h | 4 +++- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9075e235a9..1ab9dea1f3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1523,11 +1523,17 @@ void Application::shootParticle() { delete particleEditHandle; } +// Caller is responsible for managing this EditableParticle +ParticleEditHandle* Application::newParticleEditHandle(uint32_t id) { + ParticleEditHandle* particleEditHandle = new ParticleEditHandle(&_particleEditSender, _particles.getTree()); + return particleEditHandle; +} + // Caller is responsible for managing this EditableParticle ParticleEditHandle* Application::makeParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, QString updateScript) { - ParticleEditHandle* particleEditHandle = new ParticleEditHandle(&_particleEditSender, _particles.getTree()); + ParticleEditHandle* particleEditHandle = newParticleEditHandle(); particleEditHandle->createParticle(position, radius, color, velocity, gravity, damping, updateScript); return particleEditHandle; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 601bec8573..fd44d44ea1 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -121,6 +121,7 @@ public: void wheelEvent(QWheelEvent* event); void shootParticle(); // shoots a particle in the direction you're looking + ParticleEditHandle* newParticleEditHandle(uint32_t id = NEW_PARTICLE); ParticleEditHandle* makeParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, QString updateScript); diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 00ddc4d301..32a9c26d36 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -69,6 +69,12 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f if (closestParticle) { printf("potentially caught... particle ID:%d\n", closestParticle->getID()); + + // you can create a ParticleEditHandle by doing this... + ParticleEditHandle* caughtParticle = Application::getInstance()->newParticleEditHandle(closestParticle->getID()); + + // but make sure you clean it up, when you're done + delete caughtParticle; } // Is the controller button being held down.... diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 764f10c87d..bfdcbdd338 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -20,6 +20,8 @@ #include const uint32_t NEW_PARTICLE = 0xFFFFFFFF; +const uint32_t UNKNOWN_TOKEN = 0xFFFFFFFF; + class ParticleDetail { public: uint32_t id; diff --git a/libraries/particles/src/ParticleEditHandle.cpp b/libraries/particles/src/ParticleEditHandle.cpp index 27182b24e0..c14c960d3f 100644 --- a/libraries/particles/src/ParticleEditHandle.cpp +++ b/libraries/particles/src/ParticleEditHandle.cpp @@ -16,15 +16,22 @@ std::map ParticleEditHandle::_allHandles; uint32_t ParticleEditHandle::_nextCreatorTokenID = 0; -ParticleEditHandle::ParticleEditHandle(ParticleEditPacketSender* packetSender, ParticleTree* localTree) { - _creatorTokenID = _nextCreatorTokenID; - _nextCreatorTokenID++; - _id = NEW_PARTICLE; - _isKnownID = false; +ParticleEditHandle::ParticleEditHandle(ParticleEditPacketSender* packetSender, ParticleTree* localTree, uint32_t id) { + if (id == NEW_PARTICLE) { + _creatorTokenID = _nextCreatorTokenID; + _nextCreatorTokenID++; + _id = NEW_PARTICLE; + _isKnownID = false; + _allHandles[_creatorTokenID] = this; + } else { + _creatorTokenID = UNKNOWN_TOKEN; + _id = id; + _isKnownID = true; + // don't add to _allHandles because we already know it... + } _packetSender = packetSender; _localTree = localTree; - _allHandles[_creatorTokenID] = this; } ParticleEditHandle::~ParticleEditHandle() { diff --git a/libraries/particles/src/ParticleEditHandle.h b/libraries/particles/src/ParticleEditHandle.h index 2e81f35abf..bed8b29d14 100644 --- a/libraries/particles/src/ParticleEditHandle.h +++ b/libraries/particles/src/ParticleEditHandle.h @@ -19,12 +19,14 @@ #include #include +#include "Particle.h" + class ParticleEditPacketSender; class ParticleTree; class ParticleEditHandle { public: - ParticleEditHandle(ParticleEditPacketSender* packetSender, ParticleTree* localTree); + ParticleEditHandle(ParticleEditPacketSender* packetSender, ParticleTree* localTree, uint32_t id = NEW_PARTICLE); ~ParticleEditHandle(); uint32_t getCreatorTokenID() const { return _creatorTokenID; }