scripting for particle to voxel collisions

This commit is contained in:
ZappoMan 2013-12-31 11:33:43 -08:00
parent 651d2d0c81
commit 48b2d7d3fa
7 changed files with 112 additions and 6 deletions

View file

@ -1518,10 +1518,21 @@ void Application::shootParticle() {
glm::vec3 velocity = lookingAt - position;
glm::vec3 gravity = DEFAULT_GRAVITY * 0.f;
float damping = DEFAULT_DAMPING * 0.01f;
QString updateScript("");
QString script(
" function collisionWithVoxel(voxel) { "
" print('collisionWithVoxel(voxel)... '); "
" print('myID=' + Particle.getID() + '\\n'); "
" var voxelColor = voxel.getColor();"
" print('voxelColor=' + voxelColor.red + ', ' + voxelColor.green + ', ' + voxelColor.blue + '\\n'); "
" var myColor = Particle.getColor();"
" print('myColor=' + myColor.red + ', ' + myColor.green + ', ' + myColor.blue + '\\n'); "
" Particle.setColor(voxelColor); "
" } "
" Particle.collisionWithVoxel.connect(collisionWithVoxel); " );
ParticleEditHandle* particleEditHandle = makeParticle(position / (float)TREE_SCALE, radius, color,
velocity / (float)TREE_SCALE, gravity, damping, NOT_IN_HAND, updateScript);
velocity / (float)TREE_SCALE, gravity, damping, NOT_IN_HAND, script);
// If we wanted to be able to edit this particle after shooting, then we could store this value
// and use it for editing later. But we don't care about that for "shooting" and therefore we just

View file

@ -586,6 +586,53 @@ void Particle::collisionWithParticle(Particle* other) {
}
}
void Particle::collisionWithVoxel(VoxelDetail* voxelDetails) {
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);
if (getVoxelsScriptingInterface()) {
QScriptValue voxelScripterValue = engine.newQObject(getVoxelsScriptingInterface());
engine.globalObject().setProperty("Voxels", voxelScripterValue);
}
if (getParticlesScriptingInterface()) {
QScriptValue particleScripterValue = engine.newQObject(getParticlesScriptingInterface());
engine.globalObject().setProperty("Particles", particleScripterValue);
}
QScriptValue result = engine.evaluate(_script);
VoxelDetailScriptObject voxelDetailsScriptable(voxelDetails);
particleScriptable.emitCollisionWithVoxel(&voxelDetailsScriptable);
if (getVoxelsScriptingInterface()) {
getVoxelsScriptingInterface()->getPacketSender()->releaseQueuedMessages();
}
if (getParticlesScriptingInterface()) {
getParticlesScriptingInterface()->getPacketSender()->releaseQueuedMessages();
}
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;

View file

@ -115,6 +115,7 @@ public:
void update();
void collisionWithParticle(Particle* other);
void collisionWithVoxel(VoxelDetail* voxel);
void debugDump() const;
@ -171,7 +172,7 @@ public:
void emitUpdate() { emit update(); }
void emitCollisionWithParticle(QObject* other) { emit collisionWithParticle(other); }
void emitCollisionWithVoxel() { emit collisionWithVoxel(); }
void emitCollisionWithVoxel(QObject* voxel) { emit collisionWithVoxel(voxel); }
public slots:
unsigned int getID() const { return _particle->getID(); }
@ -195,7 +196,7 @@ public slots:
signals:
void update();
void collisionWithVoxel();
void collisionWithVoxel(QObject* voxel);
void collisionWithParticle(QObject* other);
private:

View file

@ -73,11 +73,17 @@ void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) {
const float VOXEL_DAMPING = 0.0;
const float VOXEL_COLLISION_FREQUENCY = 0.5f;
glm::vec3 penetration;
if (_voxels->findSpherePenetration(center, radius, penetration)) {
VoxelDetail* voxelDetails = NULL;
if (_voxels->findSpherePenetration(center, radius, penetration, (void**)&voxelDetails)) {
// let the particles run their collision scripts if they have them
particle->collisionWithVoxel(voxelDetails);
penetration /= (float)TREE_SCALE;
updateCollisionSound(particle, penetration, VOXEL_COLLISION_FREQUENCY);
//qDebug("voxel collision\n");
applyHardCollision(particle, penetration, VOXEL_ELASTICITY, VOXEL_DAMPING);
delete voxelDetails; // cleanup returned details
}
}

View file

@ -239,3 +239,26 @@ bool VoxelTreeElement::collapseChildren() {
return allChildrenMatch;
}
bool VoxelTreeElement::findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const {
if (_box.findSpherePenetration(center, radius, penetration)) {
// if the caller wants details about the voxel, then return them here...
if (penetratedObject) {
VoxelDetail* voxelDetails = new VoxelDetail;
voxelDetails->x = _box.getCorner().x;
voxelDetails->y = _box.getCorner().y;
voxelDetails->z = _box.getCorner().z;
voxelDetails->s = _box.getScale();
voxelDetails->red = getTrueColor()[RED_INDEX];
voxelDetails->green = getTrueColor()[GREEN_INDEX];
voxelDetails->blue = getTrueColor()[BLUE_INDEX];
*penetratedObject = (void*)voxelDetails;
}
return true;
}
return false;
}

View file

@ -44,6 +44,9 @@ public:
virtual int readElementDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
virtual void calculateAverageFromChildren();
virtual bool collapseChildren();
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const;
glBufferIndex getBufferIndex() const { return _glBufferIndex; }
@ -88,4 +91,5 @@ protected:
nodeColor _currentColor; /// Client only, false color of this voxel, 4 bytes
};
#endif /* defined(__hifi__VoxelTreeElement__) */

View file

@ -56,4 +56,18 @@ private:
void queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails);
};
class VoxelDetailScriptObject : public QObject {
Q_OBJECT
public:
VoxelDetailScriptObject(VoxelDetail* voxelDetail) { _voxelDetail = voxelDetail; }
public slots:
glm::vec3 getPosition() const { return glm::vec3(_voxelDetail->x, _voxelDetail->y, _voxelDetail->z); }
xColor getColor() const { return { _voxelDetail->red, _voxelDetail->green, _voxelDetail->blue }; }
float getScale() const { return _voxelDetail->s; }
private:
VoxelDetail* _voxelDetail;
};
#endif /* defined(__hifi__VoxelsScriptingInterface__) */