mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 02:56:31 +02:00
more work with particles added javascript support to particle update
This commit is contained in:
parent
99e3a58a68
commit
7a828794be
10 changed files with 191 additions and 14 deletions
|
@ -21,7 +21,9 @@ ParticleTreeRenderer::~ParticleTreeRenderer() {
|
||||||
void ParticleTreeRenderer::update() {
|
void ParticleTreeRenderer::update() {
|
||||||
if (_tree) {
|
if (_tree) {
|
||||||
ParticleTree* tree = (ParticleTree*)_tree;
|
ParticleTree* tree = (ParticleTree*)_tree;
|
||||||
|
_tree->lockForWrite();
|
||||||
tree->update();
|
tree->update();
|
||||||
|
_tree->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +38,6 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element) {
|
||||||
|
|
||||||
bool drawAsSphere = true;
|
bool drawAsSphere = true;
|
||||||
|
|
||||||
if (!drawAsSphere) {
|
|
||||||
glPointSize(20.0f);
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint16_t i = 0; i < numberOfParticles; i++) {
|
for (uint16_t i = 0; i < numberOfParticles; i++) {
|
||||||
const Particle& particle = particles[i];
|
const Particle& particle = particles[i];
|
||||||
// render particle aspoints
|
// render particle aspoints
|
||||||
|
@ -49,18 +46,18 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element) {
|
||||||
glColor3ub(particle.getColor()[RED_INDEX],particle.getColor()[GREEN_INDEX],particle.getColor()[BLUE_INDEX]);
|
glColor3ub(particle.getColor()[RED_INDEX],particle.getColor()[GREEN_INDEX],particle.getColor()[BLUE_INDEX]);
|
||||||
|
|
||||||
//printf("particle at... (%f, %f, %f)\n", position.x, position.y, position.z);
|
//printf("particle at... (%f, %f, %f)\n", position.x, position.y, position.z);
|
||||||
|
float sphereRadius = particle.getRadius() * (float)TREE_SCALE;
|
||||||
|
|
||||||
if (drawAsSphere) {
|
if (drawAsSphere) {
|
||||||
float sphereRadius = particle.getRadius() * (float)TREE_SCALE;
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(position.x, position.y, position.z);
|
glTranslatef(position.x, position.y, position.z);
|
||||||
glutSolidSphere(sphereRadius, 15, 15);
|
glutSolidSphere(sphereRadius, 15, 15);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
} else {
|
} else {
|
||||||
|
glPointSize(sphereRadius);
|
||||||
|
glBegin(GL_POINTS);
|
||||||
glVertex3f(position.x, position.y, position.z);
|
glVertex3f(position.x, position.y, position.z);
|
||||||
|
glEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!drawAsSphere) {
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,12 @@ bool OctreePersistThread::process() {
|
||||||
|
|
||||||
if (isStillRunning()) {
|
if (isStillRunning()) {
|
||||||
uint64_t MSECS_TO_USECS = 1000;
|
uint64_t MSECS_TO_USECS = 1000;
|
||||||
uint64_t USECS_TO_SLEEP = 100 * MSECS_TO_USECS; // every 100ms
|
uint64_t USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms
|
||||||
usleep(USECS_TO_SLEEP);
|
usleep(USECS_TO_SLEEP);
|
||||||
|
|
||||||
|
// do our updates then check to save...
|
||||||
|
_tree->update();
|
||||||
|
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
uint64_t sinceLastSave = now - _lastCheck;
|
uint64_t sinceLastSave = now - _lastCheck;
|
||||||
uint64_t intervalToCheck = _persistInterval * MSECS_TO_USECS;
|
uint64_t intervalToCheck = _persistInterval * MSECS_TO_USECS;
|
||||||
|
|
|
@ -187,6 +187,9 @@ public:
|
||||||
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
|
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
|
||||||
unsigned char* editData, int maxLength) { return 0; }
|
unsigned char* editData, int maxLength) { return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
virtual void update() { }; // nothing to do by default
|
||||||
|
|
||||||
OctreeElement* getRoot() { return _rootNode; }
|
OctreeElement* getRoot() { return _rootNode; }
|
||||||
|
|
||||||
void eraseAllOctreeElements();
|
void eraseAllOctreeElements();
|
||||||
|
|
|
@ -126,7 +126,8 @@ public:
|
||||||
|
|
||||||
bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) {
|
bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) {
|
||||||
RenderArgs* args = static_cast<RenderArgs*>(extraData);
|
RenderArgs* args = static_cast<RenderArgs*>(extraData);
|
||||||
if (true || element->isInView(*args->_viewFrustum)) {
|
//if (true || element->isInView(*args->_viewFrustum)) {
|
||||||
|
if (element) {
|
||||||
if (element->hasContent()) {
|
if (element->hasContent()) {
|
||||||
args->_renderer->renderElement(element);
|
args->_renderer->renderElement(element);
|
||||||
}
|
}
|
||||||
|
@ -139,6 +140,8 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) {
|
||||||
void OctreeRenderer::render() {
|
void OctreeRenderer::render() {
|
||||||
RenderArgs args = { this, _viewFrustum };
|
RenderArgs args = { this, _viewFrustum };
|
||||||
if (_tree) {
|
if (_tree) {
|
||||||
|
_tree->lockForRead();
|
||||||
_tree->recurseTreeWithOperation(renderOperation, &args);
|
_tree->recurseTreeWithOperation(renderOperation, &args);
|
||||||
|
_tree->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QtScript/QScriptEngine>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include <SharedUtil.h> // usecTimestampNow()
|
#include <SharedUtil.h> // usecTimestampNow()
|
||||||
|
|
||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
|
@ -211,9 +214,115 @@ void Particle::update() {
|
||||||
//printf("velocity=%f, %f, %f\n", getVelocity().x, getVelocity().y, getVelocity().z);
|
//printf("velocity=%f, %f, %f\n", getVelocity().x, getVelocity().y, getVelocity().z);
|
||||||
|
|
||||||
_position += _velocity * timeElapsed;
|
_position += _velocity * timeElapsed;
|
||||||
|
|
||||||
|
float gravity = -9.8f / TREE_SCALE;
|
||||||
|
|
||||||
|
glm::vec3 velocity = getVelocity() * (float)TREE_SCALE;
|
||||||
|
//printf("OLD velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
|
||||||
|
|
||||||
|
// handle bounces off the ground...
|
||||||
|
if (_position.y <= 0) {
|
||||||
|
_velocity = _velocity * glm::vec3(1,-1,1);
|
||||||
|
|
||||||
|
velocity = getVelocity() * (float)TREE_SCALE;
|
||||||
|
//printf("NEW from ground BOUNCE velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
|
||||||
|
|
||||||
|
_position.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle gravity....
|
||||||
|
_velocity += glm::vec3(0,gravity,0) * timeElapsed;
|
||||||
|
velocity = getVelocity() * (float)TREE_SCALE;
|
||||||
|
//printf("NEW from gravity.... velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
|
||||||
|
|
||||||
|
// handle air resistance....
|
||||||
|
glm::vec3 airResistance = _velocity * glm::vec3(-0.25,-0.25,-0.25);
|
||||||
|
_velocity += airResistance * timeElapsed;
|
||||||
|
|
||||||
|
velocity = getVelocity() * (float)TREE_SCALE;
|
||||||
|
//printf("NEW from air resistance.... velocity=%f, %f, %f\n", velocity.x, velocity.y, velocity.z);
|
||||||
|
|
||||||
position = getPosition() * (float)TREE_SCALE;
|
position = getPosition() * (float)TREE_SCALE;
|
||||||
//printf("NEW position=%f, %f, %f\n", position.x, position.y, position.z);
|
//printf("NEW position=%f, %f, %f\n", position.x, position.y, position.z);
|
||||||
|
|
||||||
|
runScript(); // test this...
|
||||||
|
|
||||||
|
position = getPosition() * (float)TREE_SCALE;
|
||||||
|
//printf("AFTER SCRIPT NEW position=%f, %f, %f\n", position.x, position.y, position.z);
|
||||||
|
|
||||||
_lastUpdated = now;
|
_lastUpdated = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(glm::vec3);
|
||||||
|
Q_DECLARE_METATYPE(xColor);
|
||||||
|
|
||||||
|
QScriptValue Particle::vec3toScriptValue(QScriptEngine *engine, const glm::vec3 &vec3) {
|
||||||
|
QScriptValue obj = engine->newObject();
|
||||||
|
obj.setProperty("x", vec3.x);
|
||||||
|
obj.setProperty("y", vec3.y);
|
||||||
|
obj.setProperty("z", vec3.z);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Particle::vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3) {
|
||||||
|
vec3.x = object.property("x").toVariant().toFloat();
|
||||||
|
vec3.y = object.property("y").toVariant().toFloat();
|
||||||
|
vec3.z = object.property("z").toVariant().toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue Particle::xColorToScriptValue(QScriptEngine *engine, const xColor& color) {
|
||||||
|
QScriptValue obj = engine->newObject();
|
||||||
|
obj.setProperty("red", color.red);
|
||||||
|
obj.setProperty("green", color.green);
|
||||||
|
obj.setProperty("blue", color.blue);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Particle::xColorFromScriptValue(const QScriptValue &object, xColor& color) {
|
||||||
|
color.red = object.property("red").toVariant().toInt();
|
||||||
|
color.green = object.property("green").toVariant().toInt();
|
||||||
|
color.blue = object.property("blue").toVariant().toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Particle::runScript() {
|
||||||
|
QString scriptContents(""
|
||||||
|
//"print(\"hello world\\n\");\n"
|
||||||
|
//"var position = Particle.getPosition();\n"
|
||||||
|
//"print(\"position.x=\" + position.x + \"\\n\");\n"
|
||||||
|
//"position.x = position.x * 0.9;\n"
|
||||||
|
//"Particle.setPosition(position);\n"
|
||||||
|
//"print(\"position.x=\" + position.x + \"\\n\");\n"
|
||||||
|
//"var color = Particle.getColor();\n"
|
||||||
|
//"color.red = color.red - 1;\n"
|
||||||
|
//"if (color.red < 10) { color.red = 255; }\n"
|
||||||
|
//"Particle.setColor(color);\n"
|
||||||
|
//"print(\"position=\" + position.x + \",\" + position.y + \",\" + position.z + \"\\n\");\n"
|
||||||
|
);
|
||||||
|
QScriptEngine engine;
|
||||||
|
|
||||||
|
// register meta-type for glm::vec3 and rgbColor conversions
|
||||||
|
qScriptRegisterMetaType(&engine, vec3toScriptValue, vec3FromScriptValue);
|
||||||
|
qScriptRegisterMetaType(&engine, xColorToScriptValue, xColorFromScriptValue);
|
||||||
|
|
||||||
|
ParticleScriptObject particleScriptable(this);
|
||||||
|
QScriptValue particleValue = engine.newQObject(&particleScriptable);
|
||||||
|
engine.globalObject().setProperty("Particle", particleValue);
|
||||||
|
|
||||||
|
//QScriptValue voxelScripterValue = engine.newQObject(&_voxelScriptingInterface);
|
||||||
|
//engine.globalObject().setProperty("Voxels", voxelScripterValue);
|
||||||
|
|
||||||
|
//QScriptValue particleScripterValue = engine.newQObject(&_particleScriptingInterface);
|
||||||
|
//engine.globalObject().setProperty("Particles", particleScripterValue);
|
||||||
|
|
||||||
|
QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE));
|
||||||
|
engine.globalObject().setProperty("TREE_SCALE", TREE_SCALE);
|
||||||
|
|
||||||
|
//qDebug() << "Downloaded script:" << scriptContents << "\n";
|
||||||
|
QScriptValue result = engine.evaluate(scriptContents);
|
||||||
|
//qDebug() << "Evaluated script.\n";
|
||||||
|
|
||||||
|
if (engine.hasUncaughtException()) {
|
||||||
|
int line = engine.uncaughtExceptionLineNumber();
|
||||||
|
qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <QtScript/QScriptEngine>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <OctreePacketData.h>
|
#include <OctreePacketData.h>
|
||||||
|
|
||||||
|
@ -24,7 +27,9 @@ public:
|
||||||
glm::vec3 velocity;
|
glm::vec3 velocity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Particle {
|
class Particle {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Particle();
|
Particle();
|
||||||
Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity);
|
Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity);
|
||||||
|
@ -37,11 +42,22 @@ public:
|
||||||
|
|
||||||
const glm::vec3& getPosition() const { return _position; }
|
const glm::vec3& getPosition() const { return _position; }
|
||||||
const rgbColor& getColor() const { return _color; }
|
const rgbColor& getColor() const { return _color; }
|
||||||
|
xColor getColor() { return { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; }
|
||||||
|
|
||||||
float getRadius() const { return _radius; }
|
float getRadius() const { return _radius; }
|
||||||
const glm::vec3& getVelocity() const { return _velocity; }
|
const glm::vec3& getVelocity() const { return _velocity; }
|
||||||
uint64_t getLastUpdated() const { return _lastUpdated; }
|
uint64_t getLastUpdated() const { return _lastUpdated; }
|
||||||
uint32_t getID() const { return _id; }
|
uint32_t getID() const { return _id; }
|
||||||
|
|
||||||
|
void setPosition(const glm::vec3& value) { _position = value; }
|
||||||
|
void setVelocity(const glm::vec3& value) { _velocity = value; }
|
||||||
|
void setColor(const rgbColor& value) { memcpy(_color, value, sizeof(_color)); }
|
||||||
|
void setColor(const xColor& value) {
|
||||||
|
_color[RED_INDEX] = value.red;
|
||||||
|
_color[GREEN_INDEX] = value.green;
|
||||||
|
_color[BLUE_INDEX] = value.blue;
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
@ -50,6 +66,12 @@ public:
|
||||||
unsigned char* bufferOut, int sizeIn, int& sizeOut);
|
unsigned char* bufferOut, int sizeIn, int& sizeOut);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
void runScript();
|
||||||
|
|
||||||
|
static QScriptValue vec3toScriptValue(QScriptEngine *engine, const glm::vec3 &vec3);
|
||||||
|
static void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3);
|
||||||
|
static QScriptValue xColorToScriptValue(QScriptEngine *engine, const xColor& color);
|
||||||
|
static void xColorFromScriptValue(const QScriptValue &object, xColor& color);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
|
@ -61,4 +83,22 @@ protected:
|
||||||
static uint32_t _nextID;
|
static uint32_t _nextID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ParticleScriptObject : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ParticleScriptObject(Particle* particle) { _particle = particle; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
glm::vec3 getPosition() const { return _particle->getPosition(); }
|
||||||
|
glm::vec3 getVelocity() const { return _particle->getVelocity(); }
|
||||||
|
xColor getColor() const { return _particle->getColor(); }
|
||||||
|
|
||||||
|
void setPosition(glm::vec3 value) { return _particle->setPosition(value); }
|
||||||
|
void setVelocity(glm::vec3 value) { return _particle->setVelocity(value); }
|
||||||
|
void setColor(xColor value) { return _particle->setColor(value); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Particle* _particle;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__Particle__) */
|
#endif /* defined(__hifi__Particle__) */
|
|
@ -74,14 +74,25 @@ bool ParticleTree::updateOperation(OctreeElement* element, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleTree::update() {
|
void ParticleTree::update() {
|
||||||
|
_isDirty = true;
|
||||||
|
|
||||||
ParticleTreeUpdateArgs args = { };
|
ParticleTreeUpdateArgs args = { };
|
||||||
recurseTreeWithOperation(updateOperation, &args);
|
recurseTreeWithOperation(updateOperation, &args);
|
||||||
|
|
||||||
// now add back any of the particles that moved elements....
|
// now add back any of the particles that moved elements....
|
||||||
int movingParticles = args._movingParticles.size();
|
int movingParticles = args._movingParticles.size();
|
||||||
for (int i = 0; i < movingParticles; i++) {
|
for (int i = 0; i < movingParticles; i++) {
|
||||||
printf("re-storing moved particle...\n");
|
// if the particle is still inside our total bounds, then re-add it
|
||||||
storeParticle(args._movingParticles[i]);
|
AABox treeBounds = getRoot()->getAABox();
|
||||||
|
float velocityScalar = glm::length(args._movingParticles[i].getVelocity());
|
||||||
|
const float STILL_MOVING = 0.0001;
|
||||||
|
|
||||||
|
if (velocityScalar > STILL_MOVING && treeBounds.contains(args._movingParticles[i].getPosition())) {
|
||||||
|
printf("re-storing moved particle...\n");
|
||||||
|
storeParticle(args._movingParticles[i]);
|
||||||
|
} else {
|
||||||
|
printf("out of bounds or !velocityScalar=[%f], not re-storing moved particle...\n",velocityScalar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
|
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
|
||||||
unsigned char* editData, int maxLength);
|
unsigned char* editData, int maxLength);
|
||||||
|
|
||||||
void update();
|
virtual void update();
|
||||||
private:
|
private:
|
||||||
void storeParticle(const Particle& particle);
|
void storeParticle(const Particle& particle);
|
||||||
|
|
||||||
|
|
|
@ -60,10 +60,13 @@ bool ParticleTreeElement::appendElementData(OctreePacketData* packetData) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleTreeElement::update(ParticleTreeUpdateArgs& args) {
|
void ParticleTreeElement::update(ParticleTreeUpdateArgs& args) {
|
||||||
|
markWithChangedTime();
|
||||||
|
|
||||||
// update our contained particles
|
// update our contained particles
|
||||||
uint16_t numberOfParticles = _particles.size();
|
uint16_t numberOfParticles = _particles.size();
|
||||||
for (uint16_t i = 0; i < numberOfParticles; i++) {
|
for (uint16_t i = 0; i < numberOfParticles; i++) {
|
||||||
_particles[i].update();
|
_particles[i].update();
|
||||||
|
|
||||||
// what if this update moves the particle to a new element??
|
// what if this update moves the particle to a new element??
|
||||||
if (!_box.contains(_particles[i].getPosition())) {
|
if (!_box.contains(_particles[i].getPosition())) {
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,13 @@ typedef unsigned char colorPart;
|
||||||
typedef unsigned char nodeColor[BYTES_PER_COLOR + BYTES_PER_FLAGS];
|
typedef unsigned char nodeColor[BYTES_PER_COLOR + BYTES_PER_FLAGS];
|
||||||
typedef unsigned char rgbColor[BYTES_PER_COLOR];
|
typedef unsigned char rgbColor[BYTES_PER_COLOR];
|
||||||
|
|
||||||
|
struct xColor {
|
||||||
|
unsigned char red;
|
||||||
|
unsigned char green;
|
||||||
|
unsigned char blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static const float ZERO = 0.0f;
|
static const float ZERO = 0.0f;
|
||||||
static const float ONE = 1.0f;
|
static const float ONE = 1.0f;
|
||||||
static const float ONE_HALF = 0.5f;
|
static const float ONE_HALF = 0.5f;
|
||||||
|
|
Loading…
Reference in a new issue