mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 10:13:15 +02:00
use ScriptEngine in Particle::collideWithXXX() methods so that we get all script interfaces
This commit is contained in:
parent
3efc1ea410
commit
0df02618ee
5 changed files with 670 additions and 657 deletions
|
@ -44,6 +44,7 @@
|
|||
#include <OctalCode.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <PairingHandler.h>
|
||||
#include <ParticlesScriptingInterface.h>
|
||||
#include <PerfStat.h>
|
||||
#include <UUID.h>
|
||||
#include <VoxelSceneStats.h>
|
||||
|
@ -239,6 +240,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_voxelEditSender.setVoxelServerJurisdictions(&_voxelServerJurisdictions);
|
||||
_particleEditSender.setServerJurisdictions(&_particleServerJurisdictions);
|
||||
|
||||
Particle::setVoxelEditPacketSender(&_voxelEditSender);
|
||||
Particle::setParticleEditPacketSender(&_particleEditSender);
|
||||
|
||||
// For now we're going to set the PPS for outbound packets to be super high, this is
|
||||
// probably not the right long term solution. But for now, we're going to do this to
|
||||
// allow you to move a particle around in your hand
|
||||
|
@ -1555,6 +1559,10 @@ void Application::shootParticle() {
|
|||
" var myColor = Particle.getColor();"
|
||||
" print('myColor=' + myColor.red + ', ' + myColor.green + ', ' + myColor.blue + '\\n'); "
|
||||
" Particle.setColor(voxelColor); "
|
||||
" var voxelAt = voxel.getPosition();"
|
||||
" var voxelScale = voxel.getScale();"
|
||||
" Voxels.queueVoxelDelete(voxelAt.x, voxelAt.y, voxelAt.z, voxelScale); "
|
||||
" print('Voxels.queueVoxelDelete(' + voxelAt.x + ', ' + voxelAt.y + ', ' + voxelAt.z + ', ' + voxelScale + ')... \\n'); "
|
||||
" } "
|
||||
" Particle.collisionWithVoxel.connect(collisionWithVoxel); " );
|
||||
|
||||
|
|
|
@ -7,21 +7,25 @@
|
|||
//
|
||||
//
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <Octree.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <SharedUtil.h> // usecTimestampNow()
|
||||
#include <Octree.h>
|
||||
|
||||
#include <VoxelsScriptingInterface.h>
|
||||
#include "ParticlesScriptingInterface.h"
|
||||
|
||||
// This is not ideal, but adding script-engine as a linked library, will cause a circular reference
|
||||
// I'm open to other potential solutions. Could we change cmake to allow libraries to reference each others
|
||||
// headers, but not link to each other, this is essentially what this construct is doing, but would be
|
||||
// better to add includes to the include path, but not link
|
||||
#include "../../script-engine/src/ScriptEngine.h"
|
||||
|
||||
#include "ParticlesScriptingInterface.h"
|
||||
#include "Particle.h"
|
||||
|
||||
uint32_t Particle::_nextID = 0;
|
||||
VoxelsScriptingInterface* Particle::_voxelsScriptingInterface = NULL;
|
||||
ParticlesScriptingInterface* Particle::_particlesScriptingInterface = NULL;
|
||||
VoxelEditPacketSender* Particle::_voxelEditSender = NULL;
|
||||
ParticleEditPacketSender* Particle::_particleEditSender = NULL;
|
||||
|
||||
|
||||
Particle::Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, glm::vec3 gravity,
|
||||
|
@ -532,45 +536,30 @@ void Particle::runUpdateScript() {
|
|||
void Particle::collisionWithParticle(Particle* other) {
|
||||
if (!_script.isEmpty()) {
|
||||
|
||||
QScriptEngine engine;
|
||||
ScriptEngine engine(_script); // no menu or controller interface...
|
||||
|
||||
// register meta-type for glm::vec3 and rgbColor conversions
|
||||
registerMetaTypes(&engine);
|
||||
if (_voxelEditSender) {
|
||||
engine.getVoxelsScriptingInterface()->setPacketSender(_voxelEditSender);
|
||||
}
|
||||
if (_particleEditSender) {
|
||||
engine.getParticlesScriptingInterface()->setPacketSender(_particleEditSender);
|
||||
}
|
||||
|
||||
// Add the Particle object
|
||||
ParticleScriptObject particleScriptable(this);
|
||||
QScriptValue particleValue = engine.newQObject(&particleScriptable);
|
||||
engine.globalObject().setProperty("Particle", particleValue);
|
||||
engine.registerGlobalObject("Particle", &particleScriptable);
|
||||
|
||||
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);
|
||||
// init and evaluate the script, but return so we can emit the collision
|
||||
engine.evaluate();
|
||||
|
||||
ParticleScriptObject otherParticleScriptable(other);
|
||||
particleScriptable.emitCollisionWithParticle(&otherParticleScriptable);
|
||||
|
||||
if (getVoxelsScriptingInterface()) {
|
||||
getVoxelsScriptingInterface()->getPacketSender()->releaseQueuedMessages();
|
||||
if (_voxelEditSender) {
|
||||
_voxelEditSender->releaseQueuedMessages();
|
||||
}
|
||||
|
||||
if (getParticlesScriptingInterface()) {
|
||||
getParticlesScriptingInterface()->getPacketSender()->releaseQueuedMessages();
|
||||
}
|
||||
|
||||
if (engine.hasUncaughtException()) {
|
||||
int line = engine.uncaughtExceptionLineNumber();
|
||||
qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
|
||||
if (_particleEditSender) {
|
||||
_particleEditSender->releaseQueuedMessages();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -578,45 +567,32 @@ void Particle::collisionWithParticle(Particle* other) {
|
|||
void Particle::collisionWithVoxel(VoxelDetail* voxelDetails) {
|
||||
if (!_script.isEmpty()) {
|
||||
|
||||
QScriptEngine engine;
|
||||
ScriptEngine engine(_script); // no menu or controller interface...
|
||||
|
||||
// register meta-type for glm::vec3 and rgbColor conversions
|
||||
registerMetaTypes(&engine);
|
||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||
// we can use the same ones as our context.
|
||||
if (_voxelEditSender) {
|
||||
engine.getVoxelsScriptingInterface()->setPacketSender(_voxelEditSender);
|
||||
}
|
||||
if (_particleEditSender) {
|
||||
engine.getParticlesScriptingInterface()->setPacketSender(_particleEditSender);
|
||||
}
|
||||
|
||||
// Add the Particle object
|
||||
ParticleScriptObject particleScriptable(this);
|
||||
QScriptValue particleValue = engine.newQObject(&particleScriptable);
|
||||
engine.globalObject().setProperty("Particle", particleValue);
|
||||
engine.registerGlobalObject("Particle", &particleScriptable);
|
||||
|
||||
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);
|
||||
// init and evaluate the script, but return so we can emit the collision
|
||||
engine.evaluate();
|
||||
|
||||
VoxelDetailScriptObject voxelDetailsScriptable(voxelDetails);
|
||||
particleScriptable.emitCollisionWithVoxel(&voxelDetailsScriptable);
|
||||
|
||||
if (getVoxelsScriptingInterface()) {
|
||||
getVoxelsScriptingInterface()->getPacketSender()->releaseQueuedMessages();
|
||||
if (_voxelEditSender) {
|
||||
_voxelEditSender->releaseQueuedMessages();
|
||||
}
|
||||
|
||||
if (getParticlesScriptingInterface()) {
|
||||
getParticlesScriptingInterface()->getPacketSender()->releaseQueuedMessages();
|
||||
}
|
||||
|
||||
if (engine.hasUncaughtException()) {
|
||||
int line = engine.uncaughtExceptionLineNumber();
|
||||
qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
|
||||
if (_particleEditSender) {
|
||||
_particleEditSender->releaseQueuedMessages();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
class VoxelsScriptingInterface;
|
||||
class ParticlesScriptingInterface;
|
||||
class VoxelEditPacketSender;
|
||||
class ParticleEditPacketSender;
|
||||
|
||||
|
||||
const uint32_t NEW_PARTICLE = 0xFFFFFFFF;
|
||||
|
@ -122,18 +124,19 @@ public:
|
|||
// similar to assignment/copy, but it handles keeping lifetime accurate
|
||||
void copyChangedProperties(const Particle& other);
|
||||
|
||||
static VoxelsScriptingInterface* getVoxelsScriptingInterface() { return _voxelsScriptingInterface; }
|
||||
static ParticlesScriptingInterface* getParticlesScriptingInterface() { return _particlesScriptingInterface; }
|
||||
static VoxelEditPacketSender* getVoxelEditPacketSender() { return _voxelEditSender; }
|
||||
static ParticleEditPacketSender* getParticleEditPacketSender() { return _particleEditSender; }
|
||||
|
||||
static void setVoxelsScriptingInterface(VoxelsScriptingInterface* interface)
|
||||
{ _voxelsScriptingInterface = interface; }
|
||||
static void setVoxelEditPacketSender(VoxelEditPacketSender* interface)
|
||||
{ _voxelEditSender = interface; }
|
||||
|
||||
static void setParticleEditPacketSender(ParticleEditPacketSender* interface)
|
||||
{ _particleEditSender = interface; }
|
||||
|
||||
static void setParticlesScriptingInterface(ParticlesScriptingInterface* interface)
|
||||
{ _particlesScriptingInterface = interface; }
|
||||
|
||||
protected:
|
||||
static VoxelsScriptingInterface* _voxelsScriptingInterface;
|
||||
static ParticlesScriptingInterface* _particlesScriptingInterface;
|
||||
static VoxelEditPacketSender* _voxelEditSender;
|
||||
static ParticleEditPacketSender* _particleEditSender;
|
||||
|
||||
void runUpdateScript();
|
||||
static QScriptValue vec3toScriptValue(QScriptEngine *engine, const glm::vec3 &vec3);
|
||||
|
|
|
@ -19,11 +19,14 @@
|
|||
#include <PacketHeaders.h>
|
||||
#include <UUID.h>
|
||||
#include <VoxelConstants.h>
|
||||
#include <ParticlesScriptingInterface.h>
|
||||
|
||||
#include <Sound.h>
|
||||
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
|
||||
|
||||
int ScriptEngine::_scriptNumber = 1;
|
||||
VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface;
|
||||
ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface;
|
||||
|
@ -41,6 +44,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems,
|
|||
_scriptContents = scriptContents;
|
||||
_isFinished = false;
|
||||
_isRunning = false;
|
||||
_isInitialized = false;
|
||||
|
||||
// some clients will use these menu features
|
||||
_wantMenuItems = wantMenuItems;
|
||||
|
@ -54,15 +58,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems,
|
|||
}
|
||||
_menu = menu;
|
||||
_controllerScriptingInterface = controllerScriptingInterface;
|
||||
|
||||
// hook up our interfaces
|
||||
if (!Particle::getVoxelsScriptingInterface()) {
|
||||
Particle::setVoxelsScriptingInterface(getVoxelsScriptingInterface());
|
||||
}
|
||||
|
||||
if (!Particle::getParticlesScriptingInterface()) {
|
||||
Particle::setParticlesScriptingInterface(getParticlesScriptingInterface());
|
||||
}
|
||||
}
|
||||
|
||||
ScriptEngine::~ScriptEngine() {
|
||||
|
@ -92,57 +87,83 @@ bool ScriptEngine::setScriptContents(const QString& scriptContents) {
|
|||
|
||||
Q_SCRIPT_DECLARE_QMETAOBJECT(AudioInjectorOptions, QObject*)
|
||||
|
||||
void ScriptEngine::run() {
|
||||
_isRunning = true;
|
||||
QScriptEngine engine;
|
||||
void ScriptEngine::init() {
|
||||
if (_isInitialized) {
|
||||
return; // only initialize once
|
||||
}
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
_voxelsScriptingInterface.init();
|
||||
_particlesScriptingInterface.init();
|
||||
|
||||
// register meta-type for glm::vec3 conversions
|
||||
registerMetaTypes(&engine);
|
||||
registerMetaTypes(&_engine);
|
||||
|
||||
QScriptValue agentValue = engine.newQObject(this);
|
||||
engine.globalObject().setProperty("Agent", agentValue);
|
||||
QScriptValue agentValue = _engine.newQObject(this);
|
||||
_engine.globalObject().setProperty("Agent", agentValue);
|
||||
|
||||
QScriptValue voxelScripterValue = engine.newQObject(&_voxelsScriptingInterface);
|
||||
engine.globalObject().setProperty("Voxels", voxelScripterValue);
|
||||
QScriptValue voxelScripterValue = _engine.newQObject(&_voxelsScriptingInterface);
|
||||
_engine.globalObject().setProperty("Voxels", voxelScripterValue);
|
||||
|
||||
QScriptValue particleScripterValue = engine.newQObject(&_particlesScriptingInterface);
|
||||
engine.globalObject().setProperty("Particles", particleScripterValue);
|
||||
QScriptValue particleScripterValue = _engine.newQObject(&_particlesScriptingInterface);
|
||||
_engine.globalObject().setProperty("Particles", particleScripterValue);
|
||||
|
||||
QScriptValue soundConstructorValue = _engine.newFunction(soundConstructor);
|
||||
QScriptValue soundMetaObject = _engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue);
|
||||
_engine.globalObject().setProperty("Sound", soundMetaObject);
|
||||
|
||||
QScriptValue soundConstructorValue = engine.newFunction(soundConstructor);
|
||||
QScriptValue soundMetaObject = engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue);
|
||||
engine.globalObject().setProperty("Sound", soundMetaObject);
|
||||
QScriptValue injectionOptionValue = _engine.scriptValueFromQMetaObject<AudioInjectorOptions>();
|
||||
_engine.globalObject().setProperty("AudioInjectionOptions", injectionOptionValue);
|
||||
|
||||
QScriptValue injectionOptionValue = engine.scriptValueFromQMetaObject<AudioInjectorOptions>();
|
||||
engine.globalObject().setProperty("AudioInjectionOptions", injectionOptionValue);
|
||||
|
||||
QScriptValue audioScriptingInterfaceValue = engine.newQObject(&_audioScriptingInterface);
|
||||
engine.globalObject().setProperty("Audio", audioScriptingInterfaceValue);
|
||||
QScriptValue audioScriptingInterfaceValue = _engine.newQObject(&_audioScriptingInterface);
|
||||
_engine.globalObject().setProperty("Audio", audioScriptingInterfaceValue);
|
||||
|
||||
if (_controllerScriptingInterface) {
|
||||
QScriptValue controllerScripterValue = engine.newQObject(_controllerScriptingInterface);
|
||||
engine.globalObject().setProperty("Controller", controllerScripterValue);
|
||||
QScriptValue controllerScripterValue = _engine.newQObject(_controllerScriptingInterface);
|
||||
_engine.globalObject().setProperty("Controller", controllerScripterValue);
|
||||
}
|
||||
|
||||
QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE));
|
||||
engine.globalObject().setProperty("TREE_SCALE", treeScaleValue);
|
||||
|
||||
const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
|
||||
QScriptValue treeScaleValue = _engine.newVariant(QVariant(TREE_SCALE));
|
||||
_engine.globalObject().setProperty("TREE_SCALE", treeScaleValue);
|
||||
|
||||
// let the VoxelPacketSender know how frequently we plan to call it
|
||||
_voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
||||
_particlesScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
||||
|
||||
//qDebug() << "Script:\n" << _scriptContents << "\n";
|
||||
}
|
||||
|
||||
QScriptValue result = engine.evaluate(_scriptContents);
|
||||
void ScriptEngine::registerGlobalObject(const QString& name, QObject* object) {
|
||||
QScriptValue value = _engine.newQObject(object);
|
||||
_engine.globalObject().setProperty(name, value);
|
||||
}
|
||||
|
||||
void ScriptEngine::evaluate() {
|
||||
if (!_isInitialized) {
|
||||
init();
|
||||
}
|
||||
|
||||
QScriptValue result = _engine.evaluate(_scriptContents);
|
||||
qDebug() << "Evaluated script.\n";
|
||||
|
||||
if (engine.hasUncaughtException()) {
|
||||
int line = engine.uncaughtExceptionLineNumber();
|
||||
if (_engine.hasUncaughtException()) {
|
||||
int line = _engine.uncaughtExceptionLineNumber();
|
||||
qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::run() {
|
||||
if (!_isInitialized) {
|
||||
init();
|
||||
}
|
||||
_isRunning = true;
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
|
@ -198,9 +219,9 @@ void ScriptEngine::run() {
|
|||
emit willSendVisualDataCallback();
|
||||
}
|
||||
|
||||
if (engine.hasUncaughtException()) {
|
||||
int line = engine.uncaughtExceptionLineNumber();
|
||||
qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n";
|
||||
if (_engine.hasUncaughtException()) {
|
||||
int line = _engine.uncaughtExceptionLineNumber();
|
||||
qDebug() << "Uncaught exception at line" << line << ":" << _engine.uncaughtException().toString() << "\n";
|
||||
}
|
||||
}
|
||||
cleanMenuItems();
|
||||
|
@ -213,7 +234,6 @@ void ScriptEngine::run() {
|
|||
emit finished();
|
||||
_isRunning = false;
|
||||
}
|
||||
|
||||
void ScriptEngine::stop() {
|
||||
_isFinished = true;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
#include <AbstractMenuInterface.h>
|
||||
#include <AudioScriptingInterface.h>
|
||||
#include <ParticlesScriptingInterface.h>
|
||||
#include <VoxelsScriptingInterface.h>
|
||||
|
||||
class ParticlesScriptingInterface;
|
||||
|
||||
#include "AbstractControllerScriptingInterface.h"
|
||||
|
||||
const QString NO_SCRIPT("");
|
||||
|
@ -45,9 +46,13 @@ public:
|
|||
void setupMenuItems();
|
||||
void cleanMenuItems();
|
||||
|
||||
void registerGlobalObject(const QString& name, QObject* object); /// registers a global object by name
|
||||
|
||||
public slots:
|
||||
void run();
|
||||
void init();
|
||||
void run(); /// runs continuously until Agent.stop() is called
|
||||
void stop();
|
||||
void evaluate(); /// initializes the engine, and evaluates the script, but then returns control to caller
|
||||
|
||||
signals:
|
||||
void willSendAudioDataCallback();
|
||||
|
@ -57,7 +62,8 @@ protected:
|
|||
QString _scriptContents;
|
||||
bool _isFinished;
|
||||
bool _isRunning;
|
||||
|
||||
bool _isInitialized;
|
||||
QScriptEngine _engine;
|
||||
|
||||
private:
|
||||
static VoxelsScriptingInterface _voxelsScriptingInterface;
|
||||
|
|
Loading…
Reference in a new issue