first cut at running scripts on particle collisions

This commit is contained in:
ZappoMan 2013-12-30 14:59:00 -08:00
parent ebdf80a4ed
commit f4b28041fa
3 changed files with 61 additions and 19 deletions

View file

@ -53,8 +53,9 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3
_velocity = velocity;
_damping = damping;
_gravity = gravity;
_updateScript = updateScript;
_script = updateScript;
_inHand = inHand;
_shouldDie = false;
}
@ -95,10 +96,10 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
success = packetData->appendValue(getInHand());
}
if (success) {
uint16_t scriptLength = _updateScript.size() + 1; // include NULL
uint16_t scriptLength = _script.size() + 1; // include NULL
success = packetData->appendValue(scriptLength);
if (success) {
success = packetData->appendRawData((const unsigned char*)qPrintable(_updateScript), scriptLength);
success = packetData->appendRawData((const unsigned char*)qPrintable(_script), scriptLength);
}
}
return success;
@ -206,7 +207,7 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef
dataAt += sizeof(scriptLength);
bytesRead += sizeof(scriptLength);
QString tempString((const char*)dataAt);
_updateScript = tempString;
_script = tempString;
dataAt += scriptLength;
bytesRead += scriptLength;
@ -299,7 +300,7 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe
dataAt += sizeof(scriptLength);
processedBytes += sizeof(scriptLength);
QString tempString((const char*)dataAt);
newParticle._updateScript = tempString;
newParticle._script = tempString;
dataAt += scriptLength;
processedBytes += scriptLength;
@ -472,7 +473,7 @@ void Particle::update() {
const float REALLY_OLD = 30.0f; // 30 seconds
bool isReallyOld = (getLifetime() > REALLY_OLD);
bool isInHand = getInHand();
bool shouldDie = !isInHand && !isStillMoving && isReallyOld;
bool shouldDie = getShouldDie() || (!isInHand && !isStillMoving && isReallyOld);
setShouldDie(shouldDie);
const bool wantDebug = false;
@ -483,7 +484,7 @@ void Particle::update() {
debug::valueOf(isReallyOld), debug::valueOf(shouldDie));
}
runScript(); // allow the javascript to alter our state
runUpdateScript(); // allow the javascript to alter our state
// If the ball is in hand, it doesn't move or have gravity effect it
if (!isInHand) {
@ -507,11 +508,9 @@ void Particle::update() {
_lastUpdated = now;
}
void Particle::runScript() {
if (!_updateScript.isEmpty()) {
//qDebug() << "Script: " << _updateScript << "\n";
void Particle::runUpdateScript() {
if (!_script.isEmpty()) {
QScriptEngine engine;
// register meta-type for glm::vec3 and rgbColor conversions
@ -524,9 +523,9 @@ void Particle::runScript() {
QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE));
engine.globalObject().setProperty("TREE_SCALE", TREE_SCALE);
//qDebug() << "Downloaded script:" << _updateScript << "\n";
QScriptValue result = engine.evaluate(_updateScript);
//qDebug() << "Evaluated script.\n";
QScriptValue result = engine.evaluate(_script);
particleScriptable.emitUpdate();
if (engine.hasUncaughtException()) {
int line = engine.uncaughtExceptionLineNumber();
@ -535,6 +534,33 @@ void Particle::runScript() {
}
}
void Particle::collisionWithParticle(unsigned int otherID) {
if (!_script.isEmpty()) {
QScriptEngine engine;
// register meta-type for glm::vec3 and rgbColor conversions
registerMetaTypes(&engine);
ParticleScriptObject particleScriptable(this);
QScriptValue particleValue = engine.newQObject(&particleScriptable);
engine.globalObject().setProperty("Particle", particleValue);
QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE));
engine.globalObject().setProperty("TREE_SCALE", TREE_SCALE);
QScriptValue result = engine.evaluate(_script);
particleScriptable.emitCollisionWithParticle(otherID);
if (engine.hasUncaughtException()) {
int line = engine.uncaughtExceptionLineNumber();
qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
}
}
}
void Particle::setLifetime(float lifetime) {
uint64_t lifetimeInUsecs = lifetime * USECS_PER_SECOND;
_created = usecTimestampNow() - lifetimeInUsecs;

View file

@ -79,7 +79,7 @@ public:
float getEditedAgo() const { return (float)(usecTimestampNow() - _lastEdited) / (float)USECS_PER_SECOND; }
uint32_t getID() const { return _id; }
bool getShouldDie() const { return _shouldDie; }
QString getUpdateScript() const { return _updateScript; }
QString getUpdateScript() const { return _script; }
uint32_t getCreatorTokenID() const { return _creatorTokenID; }
bool isNewlyCreated() const { return _newlyCreated; }
@ -96,7 +96,7 @@ public:
void setInHand(bool inHand) { _inHand = inHand; }
void setDamping(float value) { _damping = value; }
void setShouldDie(bool shouldDie) { _shouldDie = shouldDie; }
void setUpdateScript(QString updateScript) { _updateScript = updateScript; }
void setUpdateScript(QString updateScript) { _script = updateScript; }
void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; }
bool appendParticleData(OctreePacketData* packetData) const;
@ -110,6 +110,7 @@ public:
static void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
void update();
void collisionWithParticle(unsigned int otherID);
void debugDump() const;
@ -117,7 +118,7 @@ public:
void copyChangedProperties(const Particle& other);
protected:
void runScript();
void runUpdateScript();
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);
@ -134,7 +135,7 @@ protected:
bool _shouldDie;
glm::vec3 _gravity;
float _damping;
QString _updateScript;
QString _script;
bool _inHand;
uint32_t _creatorTokenID;
@ -152,7 +153,12 @@ class ParticleScriptObject : public QObject {
public:
ParticleScriptObject(Particle* particle) { _particle = particle; }
void emitUpdate() { emit update(); }
void emitCollisionWithParticle(uint32_t otherID) { emit collisionWithParticle(otherID); }
void emitCollisionWithVoxel() { emit collisionWithVoxel(); }
public slots:
unsigned int getID() const { return _particle->getID(); }
glm::vec3 getPosition() const { return _particle->getPosition(); }
glm::vec3 getVelocity() const { return _particle->getVelocity(); }
xColor getColor() const { return _particle->getXColor(); }
@ -170,6 +176,11 @@ public slots:
void setRadius(float value) { _particle->setRadius(value); }
void setShouldDie(bool value) { _particle->setShouldDie(value); }
signals:
void update();
void collisionWithVoxel();
void collisionWithParticle(unsigned int otherID);
private:
Particle* _particle;
};

View file

@ -90,6 +90,11 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particle) {
glm::vec3 penetration;
Particle* penetratedParticle;
if (_particles->findSpherePenetration(center, radius, penetration, (void**)&penetratedParticle)) {
// let the particles run their collision scripts if they have them
particle->collisionWithParticle(penetratedParticle->getID());
penetratedParticle->collisionWithParticle(particle->getID());
penetration /= (float)TREE_SCALE;
updateCollisionSound(particle, penetration, VOXEL_COLLISION_FREQUENCY);
// apply a hard collision to both particles of half the penetration each