first cut at particle meshes

This commit is contained in:
ZappoMan 2014-01-28 09:26:47 -08:00
parent 5e4813ab11
commit 568d5bc05d
7 changed files with 229 additions and 52 deletions

View file

@ -7,6 +7,8 @@
//
//
#include <glm/gtx/quaternion.hpp>
#include "InterfaceConfig.h"
#include "ParticleTreeRenderer.h"
@ -16,8 +18,18 @@ ParticleTreeRenderer::ParticleTreeRenderer() :
}
ParticleTreeRenderer::~ParticleTreeRenderer() {
// delete the models in _particleModels
foreach(Model* model, _particleModels) {
delete model;
}
_particleModels.clear();
}
void ParticleTreeRenderer::init() {
OctreeRenderer::init();
}
void ParticleTreeRenderer::update() {
if (_tree) {
ParticleTree* tree = (ParticleTree*)_tree;
@ -27,6 +39,39 @@ void ParticleTreeRenderer::update() {
}
}
void ParticleTreeRenderer::render() {
OctreeRenderer::render();
}
//_testModel->setURL(QUrl("http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/lotus.fbx"));
//_testModel->setURL(QUrl("http://www.fungibleinsight.com/faces/tie.fbx"));
//_testModel->setURL(QUrl("http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Angie1.fbx"));
//_testModel->setURL(QUrl("http://public.highfidelity.io/meshes/orb_model.fbx"));
//_testModel->setURL(QUrl("http://public.highfidelity.io/meshes/space_frigate_6.FBX"));
//_testModel->setURL(QUrl("http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/soccer_ball.fbx"));
//_testModel->setURL(QUrl("http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/top%20fbx.FBX"));
//_testModel->setURL(QUrl("http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/golfball_FBX2010.fbx"));
//_testModel->setURL(QUrl("http://public.highfidelity.io/meshes/Combat_tank_V01.FBX"));
//_testModel->setURL(QUrl("http://public.highfidelity.io/meshes/orc.fbx"));
//_testModel->setURL(QUrl("http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX"));
Model* ParticleTreeRenderer::getModel(const QString& url) {
Model* model = NULL;
// if we don't already have this model then create it and initialize it
if (_particleModels.find(url) == _particleModels.end()) {
model = new Model();
model->init();
qDebug() << "calling model->setURL()";
model->setURL(QUrl(url));
qDebug() << "after calling setURL()";
} else {
model = _particleModels[url];
}
return model;
}
void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) {
// actually render it here...
// we need to iterate the actual particles of the element
@ -36,8 +81,6 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg
uint16_t numberOfParticles = particles.size();
bool drawAsSphere = true;
for (uint16_t i = 0; i < numberOfParticles; i++) {
const Particle& particle = particles[i];
// render particle aspoints
@ -45,18 +88,41 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg
glColor3ub(particle.getColor()[RED_INDEX],particle.getColor()[GREEN_INDEX],particle.getColor()[BLUE_INDEX]);
float sphereRadius = particle.getRadius() * (float)TREE_SCALE;
bool drawAsModel = particle.hasModel();
args->_renderedItems++;
if (drawAsSphere) {
if (drawAsModel) {
glPushMatrix();
const float alpha = 1.0f;
Model* model = getModel(particle.getModelURL());
glm::vec3 translationAdjustment = particle.getModelTranslation();
// set the position
glm::vec3 translation(position.x, position.y, position.z);
model->setTranslation(translation + translationAdjustment);
// glm::angleAxis(-90.0f, 1.0f, 0.0f, 0.0f)
// set the rotation
glm::quat rotation = particle.getModelRotation();
model->setRotation(rotation);
// scale
const float MODEL_SCALE = 0.0006f; // need to figure out correct scale adjust
glm::vec3 scale(1.0f,1.0f,1.0f);
model->setScale(scale * MODEL_SCALE);
model->simulate(0.0f);
model->render(alpha);
//qDebug() << "called _testModel->render(alpha);";
glPopMatrix();
} else {
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glutSolidSphere(sphereRadius, 15, 15);
glPopMatrix();
} else {
glPointSize(sphereRadius);
glBegin(GL_POINTS);
glVertex3f(position.x, position.y, position.z);
glEnd();
}
}
}

View file

@ -20,6 +20,7 @@
#include <OctreeRenderer.h>
#include <ParticleTree.h>
#include <ViewFrustum.h>
#include "renderer/Model.h"
// Generic client side Octree renderer class.
class ParticleTreeRenderer : public OctreeRenderer {
@ -39,7 +40,13 @@ public:
void processEraseMessage(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr, Node* sourceNode);
virtual void init();
virtual void render();
protected:
Model* getModel(const QString& url);
QMap<QString, Model*> _particleModels;
};
#endif /* defined(__hifi__ParticleTreeRenderer__) */

View file

@ -46,7 +46,7 @@ public:
virtual void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr, Node* sourceNode);
/// initialize and GPU/rendering related resources
void init();
virtual void init();
/// render the content of the octree
virtual void render();

View file

@ -391,49 +391,49 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe
// radius
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_RADIUS) == PACKET_CONTAINS_RADIUS)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_RADIUS) == CONTAINS_RADIUS)) {
memcpy(&newParticle._radius, dataAt, sizeof(newParticle._radius));
dataAt += sizeof(newParticle._radius);
processedBytes += sizeof(newParticle._radius);
}
// position
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_POSITION) == PACKET_CONTAINS_POSITION)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_POSITION) == CONTAINS_POSITION)) {
memcpy(&newParticle._position, dataAt, sizeof(newParticle._position));
dataAt += sizeof(newParticle._position);
processedBytes += sizeof(newParticle._position);
}
// color
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_COLOR) == PACKET_CONTAINS_COLOR)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_COLOR) == CONTAINS_COLOR)) {
memcpy(newParticle._color, dataAt, sizeof(newParticle._color));
dataAt += sizeof(newParticle._color);
processedBytes += sizeof(newParticle._color);
}
// velocity
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_VELOCITY) == PACKET_CONTAINS_VELOCITY)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_VELOCITY) == CONTAINS_VELOCITY)) {
memcpy(&newParticle._velocity, dataAt, sizeof(newParticle._velocity));
dataAt += sizeof(newParticle._velocity);
processedBytes += sizeof(newParticle._velocity);
}
// gravity
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_GRAVITY) == PACKET_CONTAINS_GRAVITY)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_GRAVITY) == CONTAINS_GRAVITY)) {
memcpy(&newParticle._gravity, dataAt, sizeof(newParticle._gravity));
dataAt += sizeof(newParticle._gravity);
processedBytes += sizeof(newParticle._gravity);
}
// damping
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_DAMPING) == PACKET_CONTAINS_DAMPING)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_DAMPING) == CONTAINS_DAMPING)) {
memcpy(&newParticle._damping, dataAt, sizeof(newParticle._damping));
dataAt += sizeof(newParticle._damping);
processedBytes += sizeof(newParticle._damping);
}
// lifetime
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_LIFETIME) == PACKET_CONTAINS_LIFETIME)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_LIFETIME) == CONTAINS_LIFETIME)) {
memcpy(&newParticle._lifetime, dataAt, sizeof(newParticle._lifetime));
dataAt += sizeof(newParticle._lifetime);
processedBytes += sizeof(newParticle._lifetime);
@ -441,21 +441,21 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe
// TODO: make inHand and shouldDie into single bits
// inHand
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_INHAND) == PACKET_CONTAINS_INHAND)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_INHAND) == CONTAINS_INHAND)) {
memcpy(&newParticle._inHand, dataAt, sizeof(newParticle._inHand));
dataAt += sizeof(newParticle._inHand);
processedBytes += sizeof(newParticle._inHand);
}
// shouldDie
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_SHOULDDIE) == PACKET_CONTAINS_SHOULDDIE)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_SHOULDDIE) == CONTAINS_SHOULDDIE)) {
memcpy(&newParticle._shouldDie, dataAt, sizeof(newParticle._shouldDie));
dataAt += sizeof(newParticle._shouldDie);
processedBytes += sizeof(newParticle._shouldDie);
}
// script
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_SCRIPT) == PACKET_CONTAINS_SCRIPT)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_SCRIPT) == CONTAINS_SCRIPT)) {
uint16_t scriptLength;
memcpy(&scriptLength, dataAt, sizeof(scriptLength));
dataAt += sizeof(scriptLength);
@ -556,7 +556,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// radius
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_RADIUS) == PACKET_CONTAINS_RADIUS)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_RADIUS) == CONTAINS_RADIUS)) {
float radius = properties.getRadius() / (float) TREE_SCALE;
memcpy(copyAt, &radius, sizeof(radius));
copyAt += sizeof(radius);
@ -564,7 +564,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// position
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_POSITION) == PACKET_CONTAINS_POSITION)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_POSITION) == CONTAINS_POSITION)) {
glm::vec3 position = properties.getPosition() / (float)TREE_SCALE;
memcpy(copyAt, &position, sizeof(position));
copyAt += sizeof(position);
@ -572,7 +572,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// color
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_COLOR) == PACKET_CONTAINS_COLOR)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_COLOR) == CONTAINS_COLOR)) {
rgbColor color = { properties.getColor().red, properties.getColor().green, properties.getColor().blue };
memcpy(copyAt, color, sizeof(color));
copyAt += sizeof(color);
@ -580,7 +580,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// velocity
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_VELOCITY) == PACKET_CONTAINS_VELOCITY)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_VELOCITY) == CONTAINS_VELOCITY)) {
glm::vec3 velocity = properties.getVelocity() / (float)TREE_SCALE;
memcpy(copyAt, &velocity, sizeof(velocity));
copyAt += sizeof(velocity);
@ -588,7 +588,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// gravity
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_GRAVITY) == PACKET_CONTAINS_GRAVITY)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_GRAVITY) == CONTAINS_GRAVITY)) {
glm::vec3 gravity = properties.getGravity() / (float)TREE_SCALE;
memcpy(copyAt, &gravity, sizeof(gravity));
copyAt += sizeof(gravity);
@ -596,7 +596,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// damping
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_DAMPING) == PACKET_CONTAINS_DAMPING)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_DAMPING) == CONTAINS_DAMPING)) {
float damping = properties.getDamping();
memcpy(copyAt, &damping, sizeof(damping));
copyAt += sizeof(damping);
@ -604,7 +604,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// lifetime
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_LIFETIME) == PACKET_CONTAINS_LIFETIME)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_LIFETIME) == CONTAINS_LIFETIME)) {
float lifetime = properties.getLifetime();
memcpy(copyAt, &lifetime, sizeof(lifetime));
copyAt += sizeof(lifetime);
@ -612,7 +612,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// inHand
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_INHAND) == PACKET_CONTAINS_INHAND)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_INHAND) == CONTAINS_INHAND)) {
bool inHand = properties.getInHand();
memcpy(copyAt, &inHand, sizeof(inHand));
copyAt += sizeof(inHand);
@ -620,7 +620,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// shoulDie
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_SHOULDDIE) == PACKET_CONTAINS_SHOULDDIE)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_SHOULDDIE) == CONTAINS_SHOULDDIE)) {
bool shouldDie = properties.getShouldDie();
memcpy(copyAt, &shouldDie, sizeof(shouldDie));
copyAt += sizeof(shouldDie);
@ -628,7 +628,7 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
}
// script
if (isNewParticle || ((packetContainsBits & PACKET_CONTAINS_SCRIPT) == PACKET_CONTAINS_SCRIPT)) {
if (isNewParticle || ((packetContainsBits & CONTAINS_SCRIPT) == CONTAINS_SCRIPT)) {
uint16_t scriptLength = properties.getScript().size() + 1;
memcpy(copyAt, &scriptLength, sizeof(scriptLength));
copyAt += sizeof(scriptLength);
@ -857,10 +857,15 @@ ParticleProperties::ParticleProperties() :
_script(""),
_inHand(false),
_shouldDie(false),
_modelURL(""),
_modelTranslation(DEFAULT_MODEL_TRANSLATION),
_modelRotation(DEFAULT_MODEL_ROTATION),
_modelScale(DEFAULT_MODEL_SCALE),
_id(UNKNOWN_PARTICLE_ID),
_idSet(false),
_lastEdited(usecTimestampNow()),
_positionChanged(false),
_colorChanged(false),
_radiusChanged(false),
@ -871,6 +876,10 @@ ParticleProperties::ParticleProperties() :
_scriptChanged(false),
_inHandChanged(false),
_shouldDieChanged(false),
_modelURLChanged(false),
_modelTranslationChanged(false),
_modelRotationChanged(false),
_modelScaleChanged(false),
_defaultSettings(true)
{
}
@ -879,44 +888,59 @@ ParticleProperties::ParticleProperties() :
uint16_t ParticleProperties::getChangedBits() const {
uint16_t changedBits = 0;
if (_radiusChanged) {
changedBits += PACKET_CONTAINS_RADIUS;
changedBits += CONTAINS_RADIUS;
}
if (_positionChanged) {
changedBits += PACKET_CONTAINS_POSITION;
changedBits += CONTAINS_POSITION;
}
if (_colorChanged) {
changedBits += PACKET_CONTAINS_COLOR;
changedBits += CONTAINS_COLOR;
}
if (_velocityChanged) {
changedBits += PACKET_CONTAINS_VELOCITY;
changedBits += CONTAINS_VELOCITY;
}
if (_gravityChanged) {
changedBits += PACKET_CONTAINS_GRAVITY;
changedBits += CONTAINS_GRAVITY;
}
if (_dampingChanged) {
changedBits += PACKET_CONTAINS_DAMPING;
changedBits += CONTAINS_DAMPING;
}
if (_lifetimeChanged) {
changedBits += PACKET_CONTAINS_LIFETIME;
changedBits += CONTAINS_LIFETIME;
}
if (_inHandChanged) {
changedBits += PACKET_CONTAINS_INHAND;
changedBits += CONTAINS_INHAND;
}
if (_scriptChanged) {
changedBits += PACKET_CONTAINS_SCRIPT;
changedBits += CONTAINS_SCRIPT;
}
// how do we want to handle this?
if (_shouldDieChanged) {
changedBits += PACKET_CONTAINS_SHOULDDIE;
changedBits += CONTAINS_SHOULDDIE;
}
if (_modelURLChanged) {
changedBits += CONTAINS_MODEL_URL;
}
if (_modelTranslationChanged) {
changedBits += CONTAINS_MODEL_TRANSLATION;
}
if (_modelRotationChanged) {
changedBits += CONTAINS_MODEL_ROTATION;
}
if (_modelScaleChanged) {
changedBits += CONTAINS_MODEL_SCALE;
}
return changedBits;
@ -945,7 +969,18 @@ QScriptValue ParticleProperties::copyToScriptValue(QScriptEngine* engine) const
properties.setProperty("script", _script);
properties.setProperty("inHand", _inHand);
properties.setProperty("shouldDie", _shouldDie);
properties.setProperty("modelURL", _modelURL);
QScriptValue modelTranslation = vec3toScriptValue(engine, _modelTranslation);
properties.setProperty("modelTranslation", modelTranslation);
QScriptValue modelRotation = quatToScriptValue(engine, _modelRotation);
properties.setProperty("modelRotation", modelRotation);
properties.setProperty("modelScale", _modelScale);
if (_idSet) {
properties.setProperty("id", _id);
properties.setProperty("isKnownID", (_id == UNKNOWN_PARTICLE_ID));

View file

@ -31,16 +31,20 @@ const uint32_t NEW_PARTICLE = 0xFFFFFFFF;
const uint32_t UNKNOWN_TOKEN = 0xFFFFFFFF;
const uint32_t UNKNOWN_PARTICLE_ID = 0xFFFFFFFF;
const uint16_t PACKET_CONTAINS_RADIUS = 1;
const uint16_t PACKET_CONTAINS_POSITION = 2;
const uint16_t PACKET_CONTAINS_COLOR = 4;
const uint16_t PACKET_CONTAINS_VELOCITY = 8;
const uint16_t PACKET_CONTAINS_GRAVITY = 16;
const uint16_t PACKET_CONTAINS_DAMPING = 32;
const uint16_t PACKET_CONTAINS_LIFETIME = 64;
const uint16_t PACKET_CONTAINS_INHAND = 128;
const uint16_t PACKET_CONTAINS_SCRIPT = 256;
const uint16_t PACKET_CONTAINS_SHOULDDIE = 512;
const uint16_t CONTAINS_RADIUS = 1;
const uint16_t CONTAINS_POSITION = 2;
const uint16_t CONTAINS_COLOR = 4;
const uint16_t CONTAINS_VELOCITY = 8;
const uint16_t CONTAINS_GRAVITY = 16;
const uint16_t CONTAINS_DAMPING = 32;
const uint16_t CONTAINS_LIFETIME = 64;
const uint16_t CONTAINS_INHAND = 128;
const uint16_t CONTAINS_SCRIPT = 256;
const uint16_t CONTAINS_SHOULDDIE = 512;
const uint16_t CONTAINS_MODEL_URL = 1024;
const uint16_t CONTAINS_MODEL_TRANSLATION = 1024;
const uint16_t CONTAINS_MODEL_ROTATION = 2048;
const uint16_t CONTAINS_MODEL_SCALE = 4096;
const float DEFAULT_LIFETIME = 10.0f; // particles live for 10 seconds by default
const float DEFAULT_DAMPING = 0.99f;
@ -48,9 +52,13 @@ const float DEFAULT_RADIUS = 0.1f / TREE_SCALE;
const float MINIMUM_PARTICLE_ELEMENT_SIZE = (1.0f / 100000.0f) / TREE_SCALE; // smallest size container
const glm::vec3 DEFAULT_GRAVITY(0, (-9.8f / TREE_SCALE), 0);
const QString DEFAULT_SCRIPT("");
const glm::vec3 DEFAULT_MODEL_TRANSLATION(0, 0, 0);
const glm::quat DEFAULT_MODEL_ROTATION(0, 0, 0, 0);
const float DEFAULT_MODEL_SCALE = 1.0f;
const bool IN_HAND = true; // it's in a hand
const bool NOT_IN_HAND = !IN_HAND; // it's not in a hand
/// A collection of properties of a particle used in the scripting API. Translates between the actual properties of a particle
/// and a JavaScript style hash/QScriptValue storing a set of properties. Used in scripting to set/get the complete set of
/// particle properties via JavaScript hashes/QScriptValues
@ -75,6 +83,10 @@ public:
const QString& getScript() const { return _script; }
bool getInHand() const { return _inHand; }
bool getShouldDie() const { return _shouldDie; }
const QString& getModelURL() const { return _modelURL; }
const glm::vec3& getModelTranslation() const { return _modelTranslation; }
const glm::quat& getModelRotation() const { return _modelRotation; }
float getModelScale() const { return _modelScale; }
uint64_t getLastEdited() const { return _lastEdited; }
uint16_t getChangedBits() const;
@ -93,7 +105,14 @@ public:
void setDamping(float value) { _damping = value; _dampingChanged = true; }
void setShouldDie(bool shouldDie) { _shouldDie = shouldDie; _shouldDieChanged = true; }
void setLifetime(float value) { _lifetime = value; _lifetimeChanged = true; }
void setScript(QString updateScript) { _script = updateScript; _scriptChanged = true; }
void setScript(const QString& updateScript) { _script = updateScript; _scriptChanged = true; }
// model related properties
void setModelURL(const QString& url) { _modelURL = url; _modelURLChanged = true; }
void setModelTranslation(const glm::vec3& translation) { _modelTranslation = translation;
_modelTranslationChanged = true; }
void setModelRotation(const glm::quat& rotation) { _modelRotation = rotation; _modelRotationChanged = true; }
void setModelScale(float scale) { _modelScale = scale; _modelScaleChanged = true; }
/// used by ParticleScriptingInterface to return ParticleProperties for unknown particles
void setIsUnknownID() { _id = UNKNOWN_PARTICLE_ID; _idSet = true; }
@ -109,10 +128,15 @@ private:
QString _script;
bool _inHand;
bool _shouldDie;
QString _modelURL;
glm::vec3 _modelTranslation;
glm::quat _modelRotation;
float _modelScale;
uint32_t _id;
bool _idSet;
uint64_t _lastEdited;
bool _positionChanged;
bool _colorChanged;
bool _radiusChanged;
@ -123,6 +147,10 @@ private:
bool _scriptChanged;
bool _inHandChanged;
bool _shouldDieChanged;
bool _modelURLChanged;
bool _modelTranslationChanged;
bool _modelRotationChanged;
bool _modelScaleChanged;
bool _defaultSettings;
};
Q_DECLARE_METATYPE(ParticleProperties);
@ -196,6 +224,14 @@ public:
bool getInHand() const { return _inHand; }
float getDamping() const { return _damping; }
float getLifetime() const { return _lifetime; }
// model related properties
bool hasModel() const { return !_modelURL.isEmpty(); }
const QString& getModelURL() const { return _modelURL; }
const glm::vec3& getModelTranslation() const { return _modelTranslation; }
const glm::quat& getModelRotation() const { return _modelRotation; }
float getModelScale() const { return _modelScale; }
ParticleProperties getProperties() const;
/// The last updated/simulated time of this particle from the time perspective of the authoritative server/source
@ -238,6 +274,13 @@ public:
void setLifetime(float value) { _lifetime = value; }
void setScript(QString updateScript) { _script = updateScript; }
void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; }
// model related properties
void setModelURL(const QString& url) { _modelURL = url; }
void setModelTranslation(const glm::vec3& translation) { _modelTranslation = translation; }
void setModelRotation(const glm::quat& rotation) { _modelRotation = rotation; }
void setModelScale(float scale) { _modelScale = scale; }
void setProperties(const ParticleProperties& properties);
bool appendParticleData(OctreePacketData* packetData) const;
@ -300,6 +343,12 @@ protected:
QString _script;
bool _inHand;
// model related items
QString _modelURL;
glm::vec3 _modelTranslation;
glm::quat _modelRotation;
float _modelScale;
uint32_t _creatorTokenID;
bool _newlyCreated;

View file

@ -13,6 +13,7 @@
void registerMetaTypes(QScriptEngine* engine) {
qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue);
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
}
@ -42,6 +43,21 @@ void vec2FromScriptValue(const QScriptValue &object, glm::vec2 &vec2) {
vec2.y = object.property("y").toVariant().toFloat();
}
QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat) {
QScriptValue obj = engine->newObject();
obj.setProperty("x", quat.x);
obj.setProperty("y", quat.y);
obj.setProperty("z", quat.z);
obj.setProperty("w", quat.w);
return obj;
}
void quatFromScriptValue(const QScriptValue &object, glm::quat& quat) {
quat.x = object.property("x").toVariant().toFloat();
quat.y = object.property("y").toVariant().toFloat();
quat.z = object.property("z").toVariant().toFloat();
quat.w = object.property("w").toVariant().toFloat();
}
QScriptValue xColorToScriptValue(QScriptEngine *engine, const xColor& color) {
QScriptValue obj = engine->newObject();

View file

@ -19,6 +19,7 @@
Q_DECLARE_METATYPE(glm::vec3)
Q_DECLARE_METATYPE(glm::vec2)
Q_DECLARE_METATYPE(glm::quat)
Q_DECLARE_METATYPE(xColor)
void registerMetaTypes(QScriptEngine* engine);
@ -29,6 +30,9 @@ void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3);
QScriptValue vec2toScriptValue(QScriptEngine* engine, const glm::vec2 &vec2);
void vec2FromScriptValue(const QScriptValue &object, glm::vec2 &vec2);
QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat);
void quatFromScriptValue(const QScriptValue &object, glm::quat& quat);
QScriptValue xColorToScriptValue(QScriptEngine* engine, const xColor& color);
void xColorFromScriptValue(const QScriptValue &object, xColor& color);