mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
scripting for particle to voxel collisions
This commit is contained in:
parent
651d2d0c81
commit
48b2d7d3fa
7 changed files with 112 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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__) */
|
|
@ -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__) */
|
||||
|
|
Loading…
Reference in a new issue