diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f77fcd936c..a4271afdc7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1509,28 +1509,23 @@ void Application::shootParticle() { float damping = DEFAULT_DAMPING; QString updateScript(""); - makeParticle(position / (float)TREE_SCALE, radius, color, - velocity / (float)TREE_SCALE, gravity, damping, updateScript); - + ParticleEditHandle* particleEditHandle = makeParticle(position / (float)TREE_SCALE, radius, color, + velocity / (float)TREE_SCALE, gravity, damping, updateScript); + + // If we wanted to be able to edit this particle after shooting, then we could store this value + // and use it for editing later. But we don't care about that for "shooting" and therefore we just + // clean up our memory now. deleting a ParticleEditHandle does not effect the underlying particle, + // it just removes your ability to edit that particle later. + delete particleEditHandle; } -void Application::makeParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, +// 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) { - - // The application will keep track of creatorTokenID - uint32_t creatorTokenID = _nextCreatorTokenID; - _nextCreatorTokenID++; - // setup a ParticleDetail struct with the data - ParticleDetail addParticleDetail = { NEW_PARTICLE, usecTimestampNow(), - position, radius, {color.red, color.green, color.blue }, - velocity, gravity, damping, updateScript, creatorTokenID }; - - // queue the packet - _particleEditSender.queueParticleEditMessages(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, 1, &addParticleDetail); - - // release them - _particleEditSender.releaseQueuedMessages(); + ParticleEditHandle* particleEditHandle = new ParticleEditHandle(&_particleEditSender); + particleEditHandle->createParticle(position, radius, color, velocity, gravity, damping, updateScript); + return particleEditHandle; } @@ -4311,6 +4306,11 @@ void* Application::networkReceive(void* args) { Q_ARG(QByteArray, QByteArray((char*) app->_incomingPacket, bytesReceived))); break; + case PACKET_TYPE_PARTICLE_ADD_RESPONSE: + // look up our ParticleEditHanders.... + ParticleEditHandle::handleAddResponse(app->_incomingPacket, bytesReceived); + break; + case PACKET_TYPE_PARTICLE_DATA: case PACKET_TYPE_VOXEL_DATA: case PACKET_TYPE_VOXEL_ERASE: diff --git a/interface/src/Application.h b/interface/src/Application.h index c70e6b6b16..ce3e09c8a1 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -65,6 +65,7 @@ #include "ui/RearMirrorTools.h" #include "ui/LodToolsDialog.h" #include "ParticleTreeRenderer.h" +#include "ParticleEditHandle.h" class QAction; class QActionGroup; @@ -120,7 +121,7 @@ public: void wheelEvent(QWheelEvent* event); void shootParticle(); // shoots a particle in the direction you're looking - void makeParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, + ParticleEditHandle* makeParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, QString updateScript); void makeVoxel(glm::vec3 position, diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/VoxelPacketProcessor.cpp index 6576b0c2fc..9e0eecb2e0 100644 --- a/interface/src/VoxelPacketProcessor.cpp +++ b/interface/src/VoxelPacketProcessor.cpp @@ -58,15 +58,21 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns Node* voxelServer = NodeList::getInstance()->nodeWithAddress(senderSockAddr); if (voxelServer && *voxelServer->getActiveSocket() == senderSockAddr) { - if (packetData[0] == PACKET_TYPE_PARTICLE_DATA) { - //printf("VoxelPacketProcessor::processPacket().... got PACKET_TYPE_PARTICLE_DATA\n"); - app->_particles.processDatagram(QByteArray((char*) packetData, messageLength), senderSockAddr); - } else if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) { - app->_environment.parseData(senderSockAddr, packetData, messageLength); - } else { - app->_voxels.setDataSourceUUID(voxelServer->getUUID()); - app->_voxels.parseData(packetData, messageLength); - app->_voxels.setDataSourceUUID(QUuid()); + + switch(packetData[0]) { + case PACKET_TYPE_PARTICLE_DATA: { + app->_particles.processDatagram(QByteArray((char*) packetData, messageLength), senderSockAddr); + } break; + + case PACKET_TYPE_ENVIRONMENT_DATA: { + app->_environment.parseData(senderSockAddr, packetData, messageLength); + } break; + + default : { + app->_voxels.setDataSourceUUID(voxelServer->getUUID()); + app->_voxels.parseData(packetData, messageLength); + app->_voxels.setDataSourceUUID(QUuid()); + } break; } } } diff --git a/libraries/octree-server/src/OctreeSendThread.cpp b/libraries/octree-server/src/OctreeSendThread.cpp index eb53f5a3ad..4b770fbc43 100644 --- a/libraries/octree-server/src/OctreeSendThread.cpp +++ b/libraries/octree-server/src/OctreeSendThread.cpp @@ -506,23 +506,6 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b trueBytesSent += _myServer->sendSpecialPacket(node); truePacketsSent++; packetsSentThisInterval++; - - /** - int numBytesPacketHeader = populateTypeAndVersion(_tempOutputBuffer, PACKET_TYPE_ENVIRONMENT_DATA); - int envPacketLength = numBytesPacketHeader; - int environmentsToSend = _myServer->getSendMinimalEnvironment() ? 1 : _myServer->getEnvironmentDataCount(); - - for (int i = 0; i < environmentsToSend; i++) { - envPacketLength += _myServer->getEnvironmentData(i)->getBroadcastData(_tempOutputBuffer + envPacketLength); - } - - NodeList::getInstance()->getNodeSocket().writeDatagram((char*) _tempOutputBuffer, envPacketLength, - node->getActiveSocket()->getAddress(), - node->getActiveSocket()->getPort()); - trueBytesSent += envPacketLength; - truePacketsSent++; - packetsSentThisInterval++; - **/ } diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 823ccbe05b..aa436fb690 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -27,9 +27,6 @@ OctreeRenderer::~OctreeRenderer() { } void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { - - - bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool extraDebugging = false; // Menu::getInstance()->isOptionChecked(MenuOption::ExtraDebugging) PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails); @@ -38,6 +35,7 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Hifi int packetLength = dataByteArray.size(); unsigned char command = *packetData; + int numBytesPacketHeader = numBytesForPacketHeader(packetData); PACKET_TYPE expectedType = getExpectedPacketType(); diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 7340dd0c2f..767ae48691 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -43,7 +43,7 @@ public: virtual void renderElement(OctreeElement* element, RenderArgs* args) = 0; /// process incoming data - void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); + virtual void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); /// initialize and GPU/rendering related resources void init(); diff --git a/libraries/particle-server/src/ParticleServer.cpp b/libraries/particle-server/src/ParticleServer.cpp index 9640eec441..5d0de40113 100644 --- a/libraries/particle-server/src/ParticleServer.cpp +++ b/libraries/particle-server/src/ParticleServer.cpp @@ -39,6 +39,29 @@ void ParticleServer::beforeRun() { // nothing special to do... } -void ParticleServer::particleCreated(const Particle& newParticle, Node* senderNode) { +void ParticleServer::particleCreated(const Particle& newParticle, Node* node) { printf("ParticleServer::particleCreated(newParticle.creatorTokenID=%u, senderNode)\n",newParticle.getCreatorTokenID()); + unsigned char outputBuffer[MAX_PACKET_SIZE]; + unsigned char* copyAt = outputBuffer; + + int numBytesPacketHeader = populateTypeAndVersion(outputBuffer, PACKET_TYPE_PARTICLE_ADD_RESPONSE); + int packetLength = numBytesPacketHeader; + copyAt += numBytesPacketHeader; + + // encode the creatorTokenID + uint32_t creatorTokenID = newParticle.getCreatorTokenID(); + memcpy(copyAt, &creatorTokenID, sizeof(creatorTokenID)); + copyAt += sizeof(creatorTokenID); + packetLength += sizeof(creatorTokenID); + + // encode the particle ID + uint32_t particleID = newParticle.getID(); + memcpy(copyAt, &particleID, sizeof(particleID)); + copyAt += sizeof(particleID); + packetLength += sizeof(particleID); + + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) outputBuffer, packetLength, + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); + printf("ParticleServer::particleCreated() called writeDatagram() packetLength=%d\n", packetLength); } diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index 64407c51a8..3b6ce0aeea 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -147,7 +147,7 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef dataAt += scriptLength; bytesRead += scriptLength; - printf("Particle::readParticleDataFromBuffer()... "); debugDump(); + //printf("Particle::readParticleDataFromBuffer()... "); debugDump(); } return bytesRead; } @@ -253,7 +253,8 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, for (int i = 0; i < count && success; i++) { // get the octal code for the particle - unsigned char* octcode = pointToOctalCode(details[i].position.x, details[i].position.y, details[i].position.z, details[i].radius); + unsigned char* octcode = pointToOctalCode(details[i].position.x, details[i].position.y, + details[i].position.z, details[i].radius); int octets = numberOfThreeBitSectionsInCode(octcode); int lengthOfOctcode = bytesRequiredForCodeLength(octets); @@ -326,12 +327,14 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, memcpy(copyAt, qPrintable(details[i].updateScript), scriptLength); copyAt += scriptLength; sizeOut += scriptLength; - - printf("encodeParticleEditMessageDetails()....\n"); - printf("Particle id :%u\n", details[i].id); - printf(" last updated:%llu\n", details[i].lastUpdated); - printf(" nextID:%u\n", _nextID); + bool wantDebugging = false; + 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); + } } // cleanup delete[] octcode; diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index f5def1392a..dc3c90b14a 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -140,4 +140,5 @@ private: Particle* _particle; }; + #endif /* defined(__hifi__Particle__) */ \ No newline at end of file diff --git a/libraries/particles/src/ParticleEditHandle.cpp b/libraries/particles/src/ParticleEditHandle.cpp new file mode 100644 index 0000000000..6e2ccd2257 --- /dev/null +++ b/libraries/particles/src/ParticleEditHandle.cpp @@ -0,0 +1,90 @@ +// +// ParticleEditHandle.cpp +// hifi +// +// Created by Brad Hefta-Gaub on 12/4/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// + +#include "Particle.h" +#include "ParticleEditHandle.h" +#include "ParticleEditPacketSender.h" + +std::map ParticleEditHandle::_allHandles; +uint32_t ParticleEditHandle::_nextCreatorTokenID = 0; + + +ParticleEditHandle::ParticleEditHandle(ParticleEditPacketSender* packetSender) { + _creatorTokenID = _nextCreatorTokenID; + _nextCreatorTokenID++; + _id = NEW_PARTICLE; + _isKnownID = false; + _packetSender = packetSender; + + _allHandles[_creatorTokenID] = this; +} + +ParticleEditHandle::~ParticleEditHandle() { + // remove us from our _allHandles map + _allHandles.erase(_allHandles.find(_creatorTokenID)); +} + +void ParticleEditHandle::createParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, + glm::vec3 gravity, float damping, QString updateScript) { + + // setup a ParticleDetail struct with the data + ParticleDetail addParticleDetail = { NEW_PARTICLE, usecTimestampNow(), + position, radius, {color.red, color.green, color.blue }, + velocity, gravity, damping, updateScript, _creatorTokenID }; + + // queue the packet + _packetSender->queueParticleEditMessages(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, 1, &addParticleDetail); + + // release them + _packetSender->releaseQueuedMessages(); +} + +bool ParticleEditHandle::updateParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, + glm::vec3 gravity, float damping, QString updateScript) { + + if (!isKnownID()) { + return false; // not allowed until we know the id + } + + // setup a ParticleDetail struct with the data + ParticleDetail newParticleDetail = { _id, usecTimestampNow(), + position, radius, {color.red, color.green, color.blue }, + velocity, gravity, damping, updateScript, _creatorTokenID }; + + // queue the packet + _packetSender->queueParticleEditMessages(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, 1, &newParticleDetail); + + // release them + _packetSender->releaseQueuedMessages(); + + return true; +} + +void ParticleEditHandle::handleAddResponse(unsigned char* packetData , int packetLength) { + unsigned char* dataAt = packetData; + int numBytesPacketHeader = numBytesForPacketHeader(packetData); + dataAt += numBytesPacketHeader; + + uint32_t creatorTokenID; + memcpy(&creatorTokenID, dataAt, sizeof(creatorTokenID)); + dataAt += sizeof(creatorTokenID); + + uint32_t particleID; + memcpy(&particleID, dataAt, sizeof(particleID)); + dataAt += sizeof(particleID); + + printf("handleAddResponse() creatorTokenID=%u particleID=%u\n",creatorTokenID, particleID); + + // find this particle in the _allHandles map + if (_allHandles.find(creatorTokenID) != _allHandles.end()) { + ParticleEditHandle* theHandle = _allHandles[creatorTokenID]; + theHandle->_id = particleID; + printf("handleAddResponse() for creatorTokenID=%u theHandle->_id=%u\n",creatorTokenID, particleID); + } +} diff --git a/libraries/particles/src/ParticleEditHandle.h b/libraries/particles/src/ParticleEditHandle.h new file mode 100644 index 0000000000..22eeffff80 --- /dev/null +++ b/libraries/particles/src/ParticleEditHandle.h @@ -0,0 +1,50 @@ +// +// ParticleEditHandle.h +// hifi +// +// Created by Brad Hefta-Gaub on 12/4/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// + +#ifndef __hifi__ParticleEditHandle__ +#define __hifi__ParticleEditHandle__ + +#include +#include + +#include +#include + +#include +#include + +class ParticleEditPacketSender; + +class ParticleEditHandle { +public: + ParticleEditHandle(ParticleEditPacketSender* packetSender); + ~ParticleEditHandle(); + + uint32_t getCreatorTokenID() const { return _creatorTokenID; } + uint32_t getID() const { return _id; } + + bool isKnownID() const { return _isKnownID; } + + void createParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, + glm::vec3 gravity, float damping, QString updateScript); + + bool updateParticle(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, + glm::vec3 gravity, float damping, QString updateScript); + + static void handleAddResponse(unsigned char* packetData , int packetLength); +private: + uint32_t _creatorTokenID; + uint32_t _id; + bool _isKnownID; + static uint32_t _nextCreatorTokenID; + static std::map _allHandles; + ParticleEditPacketSender* _packetSender; +}; + +#endif /* defined(__hifi__ParticleEditHandle__) */ \ No newline at end of file diff --git a/libraries/particles/src/ParticleTree.cpp b/libraries/particles/src/ParticleTree.cpp index 186ea26aa6..9d36c72f4a 100644 --- a/libraries/particles/src/ParticleTree.cpp +++ b/libraries/particles/src/ParticleTree.cpp @@ -77,7 +77,7 @@ int ParticleTree::processEditPacketData(PACKET_TYPE packetType, unsigned char* p notifyNewlyCreatedParticle(newParticle, senderNode); } } break; - + case PACKET_TYPE_PARTICLE_ERASE: { processedBytes = 0; } break;