add model properties to particles

This commit is contained in:
ZappoMan 2014-01-28 11:18:37 -08:00
parent 1681dbb57b
commit 427abd4509
7 changed files with 329 additions and 149 deletions

View file

@ -305,6 +305,19 @@ bool OctreePacketData::appendValue(const glm::vec3& value) {
return success; return success;
} }
bool OctreePacketData::appendValue(const glm::quat& value) {
const size_t VALUES_PER_QUAT = 4;
const size_t PACKED_QUAT_SIZE = sizeof(uint16_t) * VALUES_PER_QUAT;
unsigned char data[PACKED_QUAT_SIZE];
int length = packOrientationQuatToBytes(data, value);
bool success = append(data, length);
if (success) {
_bytesOfValues += length;
_totalBytesOfValues += length;
}
return success;
}
bool OctreePacketData::appendValue(bool value) { bool OctreePacketData::appendValue(bool value) {
bool success = append((uint8_t)value); // used unsigned char version bool success = append((uint8_t)value); // used unsigned char version
if (success) { if (success) {

View file

@ -130,6 +130,9 @@ public:
/// appends a non-position vector to the end of the stream, may fail if new data stream is too long to fit in packet /// appends a non-position vector to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendValue(const glm::vec3& value); bool appendValue(const glm::vec3& value);
/// appends a packed quat to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendValue(const glm::quat& value);
/// appends a bool value to the end of the stream, may fail if new data stream is too long to fit in packet /// appends a bool value to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendValue(bool value); bool appendValue(bool value);

View file

@ -65,13 +65,6 @@ void Particle::handleAddParticleResponse(unsigned char* packetData , int packetL
} }
Particle::Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, glm::vec3 gravity,
float damping, float lifetime, bool inHand, QString updateScript, uint32_t id) {
init(position, radius, color, velocity, gravity, damping, lifetime, inHand, updateScript, id);
}
Particle::Particle() { Particle::Particle() {
rgbColor noColor = { 0, 0, 0 }; rgbColor noColor = { 0, 0, 0 };
init(glm::vec3(0,0,0), 0, noColor, glm::vec3(0,0,0), init(glm::vec3(0,0,0), 0, noColor, glm::vec3(0,0,0),
@ -182,7 +175,6 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
if (success) { if (success) {
success = packetData->appendValue(getShouldDie()); success = packetData->appendValue(getShouldDie());
} }
if (success) { if (success) {
uint16_t scriptLength = _script.size() + 1; // include NULL uint16_t scriptLength = _script.size() + 1; // include NULL
success = packetData->appendValue(scriptLength); success = packetData->appendValue(scriptLength);
@ -190,6 +182,28 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
success = packetData->appendRawData((const unsigned char*)qPrintable(_script), scriptLength); success = packetData->appendRawData((const unsigned char*)qPrintable(_script), scriptLength);
} }
} }
// modelURL
if (success) {
uint16_t modelURLLength = _modelURL.size() + 1; // include NULL
success = packetData->appendValue(modelURLLength);
if (success) {
success = packetData->appendRawData((const unsigned char*)qPrintable(_modelURL), modelURLLength);
}
}
// modelTranslation
if (success) {
success = packetData->appendValue(getModelTranslation());
}
// modelRotation
if (success) {
success = packetData->appendValue(getModelRotation());
}
// modelScale
if (success) {
success = packetData->appendValue(getModelScale());
}
return success; return success;
} }
@ -210,21 +224,6 @@ int Particle::expectedBytes() {
return expectedBytes; return expectedBytes;
} }
int Particle::expectedEditMessageBytes() {
int expectedBytes = sizeof(uint32_t) // id
+ sizeof(uint64_t) // lasted edited
+ sizeof(float) // radius
+ sizeof(glm::vec3) // position
+ sizeof(rgbColor) // color
+ sizeof(glm::vec3) // velocity
+ sizeof(glm::vec3) // gravity
+ sizeof(float) // damping
+ sizeof(float) // lifetime
+ sizeof(bool); // inhand
// potentially more...
return expectedBytes;
}
int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) { int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) {
int bytesRead = 0; int bytesRead = 0;
if (bytesLeftToRead >= expectedBytes()) { if (bytesLeftToRead >= expectedBytes()) {
@ -311,6 +310,31 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef
dataAt += scriptLength; dataAt += scriptLength;
bytesRead += scriptLength; bytesRead += scriptLength;
// modelURL
uint16_t modelURLLength;
memcpy(&modelURLLength, dataAt, sizeof(modelURLLength));
dataAt += sizeof(modelURLLength);
bytesRead += sizeof(modelURLLength);
QString modelURLString((const char*)dataAt);
_modelURL = modelURLString;
dataAt += modelURLLength;
bytesRead += modelURLLength;
// modelTranslation
memcpy(&_modelTranslation, dataAt, sizeof(_modelTranslation));
dataAt += sizeof(_modelTranslation);
bytesRead += sizeof(_modelTranslation);
// modelRotation
int bytes = unpackOrientationQuatFromBytes(dataAt, _modelRotation);
dataAt += bytes;
bytesRead += bytes;
// modelScale
memcpy(&_modelScale, dataAt, sizeof(_modelScale));
dataAt += sizeof(_modelScale);
bytesRead += sizeof(_modelScale);
//printf("Particle::readParticleDataFromBuffer()... "); debugDump(); //printf("Particle::readParticleDataFromBuffer()... "); debugDump();
} }
return bytesRead; return bytesRead;
@ -466,6 +490,39 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe
processedBytes += scriptLength; processedBytes += scriptLength;
} }
// modelURL
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_URL) == CONTAINS_MODEL_URL)) {
uint16_t modelURLLength;
memcpy(&modelURLLength, dataAt, sizeof(modelURLLength));
dataAt += sizeof(modelURLLength);
processedBytes += sizeof(modelURLLength);
QString tempString((const char*)dataAt);
newParticle._modelURL = tempString;
dataAt += modelURLLength;
processedBytes += modelURLLength;
}
// modelTranslation
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_TRANSLATION) == CONTAINS_MODEL_TRANSLATION)) {
memcpy(&newParticle._modelTranslation, dataAt, sizeof(newParticle._modelTranslation));
dataAt += sizeof(newParticle._modelTranslation);
processedBytes += sizeof(newParticle._modelTranslation);
}
// modelRotation
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_ROTATION) == CONTAINS_MODEL_ROTATION)) {
int bytes = unpackOrientationQuatFromBytes(dataAt, newParticle._modelRotation);
dataAt += bytes;
processedBytes += bytes;
}
// modelScale
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_SCALE) == CONTAINS_MODEL_SCALE)) {
memcpy(&newParticle._modelScale, dataAt, sizeof(newParticle._modelScale));
dataAt += sizeof(newParticle._modelScale);
processedBytes += sizeof(newParticle._modelScale);
}
const bool wantDebugging = false; const bool wantDebugging = false;
if (wantDebugging) { if (wantDebugging) {
qDebug("Particle::fromEditPacket()..."); qDebug("Particle::fromEditPacket()...");
@ -512,12 +569,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
int octets = numberOfThreeBitSectionsInCode(octcode); int octets = numberOfThreeBitSectionsInCode(octcode);
int lengthOfOctcode = bytesRequiredForCodeLength(octets); int lengthOfOctcode = bytesRequiredForCodeLength(octets);
int lenfthOfEditData = lengthOfOctcode + expectedEditMessageBytes();
// make sure we have room to copy this particle
if (sizeOut + lenfthOfEditData > sizeIn) {
success = false;
} else {
// add it to our message // add it to our message
memcpy(copyAt, octcode, lengthOfOctcode); memcpy(copyAt, octcode, lengthOfOctcode);
copyAt += lengthOfOctcode; copyAt += lengthOfOctcode;
@ -638,13 +690,46 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
sizeOut += scriptLength; sizeOut += scriptLength;
} }
// modelURL
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_URL) == CONTAINS_MODEL_URL)) {
uint16_t urlLength = properties.getModelURL().size() + 1;
memcpy(copyAt, &urlLength, sizeof(urlLength));
copyAt += sizeof(urlLength);
sizeOut += sizeof(urlLength);
memcpy(copyAt, qPrintable(properties.getModelURL()), urlLength);
copyAt += urlLength;
sizeOut += urlLength;
}
// modelTranslation
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_TRANSLATION) == CONTAINS_MODEL_TRANSLATION)) {
glm::vec3 modelTranslation = properties.getModelTranslation(); // should this be relative to TREE_SCALE??
memcpy(copyAt, &modelTranslation, sizeof(modelTranslation));
copyAt += sizeof(modelTranslation);
sizeOut += sizeof(modelTranslation);
}
// modelRotation
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_ROTATION) == CONTAINS_MODEL_ROTATION)) {
int bytes = packOrientationQuatToBytes(copyAt, properties.getModelRotation());
copyAt += bytes;
sizeOut += bytes;
}
// modelScale
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_SCALE) == CONTAINS_MODEL_SCALE)) {
float modelScale = properties.getModelScale();
memcpy(copyAt, &modelScale, sizeof(modelScale));
copyAt += sizeof(modelScale);
sizeOut += sizeof(modelScale);
}
bool wantDebugging = false; bool wantDebugging = false;
if (wantDebugging) { if (wantDebugging) {
printf("encodeParticleEditMessageDetails()....\n"); printf("encodeParticleEditMessageDetails()....\n");
printf("Particle id :%u\n", id.id); printf("Particle id :%u\n", id.id);
printf(" nextID:%u\n", _nextID); printf(" nextID:%u\n", _nextID);
} }
}
// cleanup // cleanup
delete[] octcode; delete[] octcode;
@ -1121,6 +1206,63 @@ void ParticleProperties::copyFromScriptValue(const QScriptValue &object) {
} }
} }
QScriptValue modelURL = object.property("modelURL");
if (modelURL.isValid()) {
QString newModelURL;
newModelURL = modelURL.toVariant().toString();
if (_defaultSettings || newModelURL != _modelURL) {
_modelURL = newModelURL;
_modelURLChanged = true;
}
}
QScriptValue modelTranslation = object.property("modelTranslation");
if (modelTranslation.isValid()) {
QScriptValue x = modelTranslation.property("x");
QScriptValue y = modelTranslation.property("y");
QScriptValue z = modelTranslation.property("z");
if (x.isValid() && y.isValid() && z.isValid()) {
glm::vec3 newModelTranslation;
newModelTranslation.x = x.toVariant().toFloat();
newModelTranslation.y = y.toVariant().toFloat();
newModelTranslation.z = z.toVariant().toFloat();
if (_defaultSettings || newModelTranslation != _modelTranslation) {
_modelTranslation = newModelTranslation;
_modelTranslationChanged = true;
}
}
}
QScriptValue modelRotation = object.property("modelRotation");
if (modelRotation.isValid()) {
QScriptValue x = modelRotation.property("x");
QScriptValue y = modelRotation.property("y");
QScriptValue z = modelRotation.property("z");
QScriptValue w = modelRotation.property("w");
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
glm::quat newModelRotation;
newModelRotation.x = x.toVariant().toFloat();
newModelRotation.y = y.toVariant().toFloat();
newModelRotation.z = z.toVariant().toFloat();
newModelRotation.w = w.toVariant().toFloat();
if (_defaultSettings || newModelRotation != _modelRotation) {
_modelRotation = newModelRotation;
_modelRotationChanged = true;
}
}
}
QScriptValue modelScale = object.property("modelScale");
if (modelScale.isValid()) {
float newModelScale;
newModelScale = modelScale.toVariant().toFloat();
if (_defaultSettings || newModelScale != _modelScale) {
_modelScale = newModelScale;
_modelScaleChanged = true;
}
}
_lastEdited = usecTimestampNow(); _lastEdited = usecTimestampNow();
} }
@ -1176,6 +1318,26 @@ void ParticleProperties::copyToParticle(Particle& particle) const {
somethingChanged = true; somethingChanged = true;
} }
if (_modelURLChanged) {
particle.setModelURL(_modelURL);
somethingChanged = true;
}
if (_modelTranslationChanged) {
particle.setModelTranslation(_modelTranslation);
somethingChanged = true;
}
if (_modelRotationChanged) {
particle.setModelRotation(_modelRotation);
somethingChanged = true;
}
if (_modelScaleChanged) {
particle.setModelScale(_modelScale);
somethingChanged = true;
}
if (somethingChanged) { if (somethingChanged) {
bool wantDebug = false; bool wantDebug = false;
if (wantDebug) { if (wantDebug) {
@ -1199,6 +1361,10 @@ void ParticleProperties::copyFromParticle(const Particle& particle) {
_script = particle.getScript(); _script = particle.getScript();
_inHand = particle.getInHand(); _inHand = particle.getInHand();
_shouldDie = particle.getShouldDie(); _shouldDie = particle.getShouldDie();
_modelURL = particle.getModelURL();
_modelTranslation = particle.getModelTranslation();
_modelRotation = particle.getModelRotation();
_modelScale = particle.getModelScale();
_id = particle.getID(); _id = particle.getID();
_idSet = true; _idSet = true;
@ -1213,6 +1379,10 @@ void ParticleProperties::copyFromParticle(const Particle& particle) {
_scriptChanged = false; _scriptChanged = false;
_inHandChanged = false; _inHandChanged = false;
_shouldDieChanged = false; _shouldDieChanged = false;
_modelURLChanged = false;
_modelTranslationChanged = false;
_modelRotationChanged = false;
_modelScaleChanged = false;
_defaultSettings = false; _defaultSettings = false;
} }

View file

@ -192,11 +192,6 @@ public:
Particle(const ParticleID& particleID, const ParticleProperties& properties); Particle(const ParticleID& particleID, const ParticleProperties& properties);
/// all position, velocity, gravity, radius units are in domain units (0.0 to 1.0)
Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity,
glm::vec3 gravity = DEFAULT_GRAVITY, float damping = DEFAULT_DAMPING, float lifetime = DEFAULT_LIFETIME,
bool inHand = NOT_IN_HAND, QString updateScript = DEFAULT_SCRIPT, uint32_t id = NEW_PARTICLE);
/// creates an NEW particle from an PACKET_TYPE_PARTICLE_ADD_OR_EDIT edit data buffer /// creates an NEW particle from an PACKET_TYPE_PARTICLE_ADD_OR_EDIT edit data buffer
static Particle fromEditPacket(unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid); static Particle fromEditPacket(unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid);
@ -286,7 +281,6 @@ public:
bool appendParticleData(OctreePacketData* packetData) const; bool appendParticleData(OctreePacketData* packetData) const;
int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
static int expectedBytes(); static int expectedBytes();
static int expectedEditMessageBytes();
static bool encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID id, const ParticleProperties& details, static bool encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID id, const ParticleProperties& details,
unsigned char* bufferOut, int sizeIn, int& sizeOut); unsigned char* bufferOut, int sizeIn, int& sizeOut);

View file

@ -45,10 +45,10 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
return 1; return 1;
case PACKET_TYPE_PARTICLE_ADD_OR_EDIT: case PACKET_TYPE_PARTICLE_ADD_OR_EDIT:
return 4; return 5;
case PACKET_TYPE_PARTICLE_DATA: case PACKET_TYPE_PARTICLE_DATA:
return 8; return 9;
case PACKET_TYPE_PING_REPLY: case PACKET_TYPE_PING_REPLY:
return 1; return 1;

View file

@ -607,7 +607,7 @@ int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput
return sizeof(quatParts); return sizeof(quatParts);
} }
int unpackOrientationQuatFromBytes(unsigned char* buffer, glm::quat& quatOutput) { int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput) {
uint16_t quatParts[4]; uint16_t quatParts[4];
memcpy(&quatParts, buffer, sizeof(quatParts)); memcpy(&quatParts, buffer, sizeof(quatParts));

View file

@ -152,7 +152,7 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo
// Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0 // Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0
// this allows us to encode each component in 16bits with great accuracy // this allows us to encode each component in 16bits with great accuracy
int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput); int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput);
int unpackOrientationQuatFromBytes(unsigned char* buffer, glm::quat& quatOutput); int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput);
// Ratios need the be highly accurate when less than 10, but not very accurate above 10, and they // Ratios need the be highly accurate when less than 10, but not very accurate above 10, and they
// are never greater than 1000 to 1, this allows us to encode each component in 16bits // are never greater than 1000 to 1, this allows us to encode each component in 16bits
@ -172,7 +172,7 @@ int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy);
int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix); int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix);
int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* destinationPointer, int radix); int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* destinationPointer, int radix);
// A convenience for sending vec3's as fixed-poimt floats // A convenience for sending vec3's as fixed-point floats
int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix); int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix);
int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix); int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix);