first cut at PACKET_TYPE_PARTICLE_ADD implementation

This commit is contained in:
ZappoMan 2013-12-05 15:38:36 -08:00
parent a9d16862c8
commit 072ced0185
10 changed files with 171 additions and 5 deletions

View file

@ -532,6 +532,12 @@ OctreeElement* Octree::getOctreeElementAt(float x, float y, float z, float s) co
return node;
}
OctreeElement* Octree::getOrCreateChildElementAt(float x, float y, float z, float s) {
return getRoot()->getOrCreateChildElementAt(x, y, z, s);
}
// combines the ray cast arguments into a single object
class RayArgs {
public:

View file

@ -198,6 +198,7 @@ public:
void deleteOctreeElementAt(float x, float y, float z, float s);
OctreeElement* getOctreeElementAt(float x, float y, float z, float s) const;
OctreeElement* getOrCreateChildElementAt(float x, float y, float z, float s);
void recurseTreeWithOperation(RecurseOctreeOperation operation, void* extraData=NULL);

View file

@ -1273,4 +1273,74 @@ void OctreeElement::notifyUpdateHooks() {
for (int i = 0; i < _updateHooks.size(); i++) {
_updateHooks[i]->elementUpdated(this);
}
}
}
OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float z, float s) {
OctreeElement* child = NULL;
// If the requested size is less than or equal to our scale, but greater than half our scale, then
// we are the Element they are looking for.
float ourScale = getScale();
float halfOurScale = ourScale / 2.0f;
assert(s <= ourScale); // This should never happen
if (s > halfOurScale) {
return this;
}
// otherwise, we need to find which of our children we should recurse
glm::vec3 ourCenter = _box.calcCenter();
int childIndex = CHILD_UNKNOWN;
// left half
if (x > ourCenter.x) {
if (y > ourCenter.y) {
// top left
if (z > ourCenter.z) {
// top left far
childIndex = CHILD_TOP_LEFT_FAR;
} else {
// top left near
childIndex = CHILD_TOP_LEFT_NEAR;
}
} else {
// bottom left
if (z > ourCenter.z) {
// bottom left far
childIndex = CHILD_BOTTOM_LEFT_FAR;
} else {
// bottom left near
childIndex = CHILD_BOTTOM_LEFT_NEAR;
}
}
} else {
// right half
if (y > ourCenter.y) {
// top right
if (z > ourCenter.z) {
// top right far
childIndex = CHILD_TOP_RIGHT_FAR;
} else {
// top right near
childIndex = CHILD_TOP_RIGHT_NEAR;
}
} else {
// bottom right
if (z > ourCenter.z) {
// bottom right far
childIndex = CHILD_BOTTOM_RIGHT_FAR;
} else {
// bottom right near
childIndex = CHILD_BOTTOM_RIGHT_NEAR;
}
}
}
// Now, check if we have a child at that location
child = getChildAtIndex(childIndex);
if (!child) {
child = addChildAtIndex(childIndex);
}
// Now that we have the child to recurse down, let it answer the original question...
return child->getOrCreateChildElementAt(x, y, z, s);
}

View file

@ -180,7 +180,22 @@ public:
#endif // def HAS_AUDIT_CHILDREN
#endif // def BLENDED_UNION_CHILDREN
enum ChildIndex {
CHILD_BOTTOM_RIGHT_NEAR = 0,
CHILD_BOTTOM_RIGHT_FAR = 1,
CHILD_TOP_RIGHT_NEAR = 2,
CHILD_TOP_RIGHT_FAR = 3,
CHILD_BOTTOM_LEFT_NEAR = 4,
CHILD_BOTTOM_LEFT_FAR = 5,
CHILD_TOP_LEFT_NEAR = 6,
CHILD_TOP_LEFT_FAR = 7,
CHILD_UNKNOWN = -1
};
OctreeElement* getOrCreateChildElementAt(float x, float y, float z, float s);
protected:
void deleteAllChildren();
void setChildAtIndex(int childIndex, OctreeElement* child);

View file

@ -99,3 +99,33 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef
}
return bytesRead;
}
Particle Particle::fromEditPacket(unsigned char* data, int length, int& processedBytes) {
Particle newParticle; // id and lastUpdated will get set here...
unsigned char* dataAt = data;
processedBytes = 0;
// radius
memcpy(&newParticle._radius, dataAt, sizeof(newParticle._radius));
dataAt += sizeof(newParticle._radius);
processedBytes += sizeof(newParticle._radius);
// position
memcpy(&newParticle._position, dataAt, sizeof(newParticle._position));
dataAt += sizeof(newParticle._position);
processedBytes += sizeof(newParticle._position);
// color
memcpy(newParticle._color, dataAt, sizeof(newParticle._color));
dataAt += sizeof(newParticle._color);
processedBytes += sizeof(newParticle._color);
// velocity
memcpy(&newParticle._velocity, dataAt, sizeof(newParticle._velocity));
dataAt += sizeof(newParticle._velocity);
processedBytes += sizeof(newParticle._velocity);
return newParticle;
}

View file

@ -20,6 +20,10 @@ class Particle {
public:
Particle();
Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity);
/// creates an NEW particle from an PACKET_TYPE_PARTICLE_ADD edit data buffer
static Particle fromEditPacket(unsigned char* data, int length, int& processedBytes);
virtual ~Particle();
virtual void init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity);

View file

@ -18,11 +18,40 @@ ParticleTreeElement* ParticleTree::createNewElement(unsigned char * octalCode) c
}
bool ParticleTree::handlesEditPacketType(PACKET_TYPE packetType) const {
return false; // not yet.
// we handle these types of "edit" packets
switch (packetType) {
case PACKET_TYPE_PARTICLE_ADD:
case PACKET_TYPE_PARTICLE_ERASE:
return true;
}
return false;
}
void ParticleTree::storeParticle(const Particle& particle) {
glm::vec3 position = particle.getPosition();
float size = particle.getRadius();
ParticleTreeElement* element = (ParticleTreeElement*)getOrCreateChildElementAt(position.x, position.y, position.z, size);
element->storeParticle(particle);
}
int ParticleTree::processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
unsigned char* editData, int maxLength) {
return 0; // not yet... soon...
int processedBytes = 0;
// we handle these types of "edit" packets
switch (packetType) {
case PACKET_TYPE_PARTICLE_ADD: {
Particle newParticle = Particle::fromEditPacket(editData, maxLength, processedBytes);
storeParticle(newParticle);
// It seems like we need some way to send the ID back to the creator??
} break;
case PACKET_TYPE_PARTICLE_ERASE: {
processedBytes = 0;
} break;
}
return processedBytes;
}

View file

@ -31,6 +31,10 @@ public:
unsigned char* editData, int maxLength);
private:
void storeParticle(const Particle& particle);
};
#endif /* defined(__hifi__ParticleTree__) */

View file

@ -61,7 +61,6 @@ bool ParticleTreeElement::appendElementData(OctreePacketData* packetData) const
int ParticleTreeElement::readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
ReadBitstreamToTreeParams& args) {
const unsigned char* dataAt = data;
int bytesRead = 0;
uint16_t numberOfParticles = 0;
@ -103,3 +102,8 @@ bool ParticleTreeElement::collapseChildren() {
return false;
}
void ParticleTreeElement::storeParticle(const Particle& particle) {
_particles.push_back(particle);
}

View file

@ -70,6 +70,9 @@ public:
virtual bool isRendered() const { return getShouldRender(); }
protected:
void storeParticle(const Particle& particle);
std::vector<Particle> _particles;
};