mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
Merge pull request 1435 into https://github.com/worklist/hifi 'master'
Conflicts: libraries/particles/src/ParticleCollisionSystem.cpp
This commit is contained in:
commit
f78b7cda6f
24 changed files with 778 additions and 122 deletions
|
@ -32,12 +32,12 @@ void Agent::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr&
|
|||
// PACKET_TYPE_JURISDICTION, first byte is the node type...
|
||||
switch (dataByteArray[headerBytes]) {
|
||||
case NODE_TYPE_VOXEL_SERVER:
|
||||
_scriptEngine.getVoxelScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
|
||||
_scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
|
||||
(unsigned char*) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
break;
|
||||
case NODE_TYPE_PARTICLE_SERVER:
|
||||
_scriptEngine.getParticleScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
|
||||
_scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
|
||||
(unsigned char*) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
break;
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
#include <ScriptEngine.h>
|
||||
#include <ThreadedAssignment.h>
|
||||
|
||||
#include <VoxelScriptingInterface.h>
|
||||
#include <ParticleScriptingInterface.h>
|
||||
|
||||
class Agent : public ThreadedAssignment {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
149
examples/collidingParticles.js
Normal file
149
examples/collidingParticles.js
Normal file
|
@ -0,0 +1,149 @@
|
|||
var currentIteration = 0;
|
||||
var NUM_ITERATIONS_BEFORE_SEND = 15; // every 1/4th seconds send another
|
||||
|
||||
var numberParticlesAdded = 0;
|
||||
var MAX_PARTICLES = 1;
|
||||
|
||||
var velocity = {
|
||||
x: 1/TREE_SCALE,
|
||||
y: 0/TREE_SCALE,
|
||||
z: 1/TREE_SCALE };
|
||||
|
||||
var gravity = {
|
||||
x: 0/TREE_SCALE,
|
||||
y: 0/TREE_SCALE,
|
||||
z: 0/TREE_SCALE };
|
||||
|
||||
var damping = 0.1;
|
||||
|
||||
var scriptA = " " +
|
||||
//" function update() { " +
|
||||
//" print('update()\\n'); " +
|
||||
//" var color = { red: 255, green: 127 + (Math.random() * 128), blue: 0 };" +
|
||||
//" Particle.setColor(color); " +
|
||||
//" } " +
|
||||
" function collisionWithParticle(other) { " +
|
||||
" print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " +
|
||||
" print('myID=' + Particle.getID() + '\\n'); " +
|
||||
" var colorBlack = { red: 0, green: 0, blue: 0 };" +
|
||||
" var otherColor = other.getColor();" +
|
||||
" print('otherColor=' + otherColor.red + ', ' + otherColor.green + ', ' + otherColor.blue + '\\n'); " +
|
||||
" var myColor = Particle.getColor();" +
|
||||
" print('myColor=' + myColor.red + ', ' + myColor.green + ', ' + myColor.blue + '\\n'); " +
|
||||
" Particle.setColor(otherColor); " +
|
||||
" other.setColor(myColor); " +
|
||||
" } " +
|
||||
" 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.collisionWithParticle.connect(collisionWithParticle); " +
|
||||
" Particle.collisionWithVoxel.connect(collisionWithVoxel); " +
|
||||
" ";
|
||||
|
||||
var scriptB = " " +
|
||||
" function collisionWithParticle(other) { " +
|
||||
" print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " +
|
||||
" print('myID=' + Particle.getID() + '\\n'); " +
|
||||
" var myPosition = Particle.getPosition();" +
|
||||
" var myRadius = Particle.getRadius();" +
|
||||
" var myColor = Particle.getColor();" +
|
||||
" Voxels.queueDestructiveVoxelAdd(myPosition.x, myPosition.y, myPosition.z, myRadius, myColor.red, myColor.green, myColor.blue); " +
|
||||
" Particle.setScript('Particle.setShouldDie(true);'); " +
|
||||
" } " +
|
||||
" 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.collisionWithParticle.connect(collisionWithParticle); " +
|
||||
" Particle.collisionWithVoxel.connect(collisionWithVoxel); " +
|
||||
" ";
|
||||
|
||||
var color = {
|
||||
red: 255,
|
||||
green: 255,
|
||||
blue: 0 };
|
||||
|
||||
function draw() {
|
||||
print("hello... draw()... currentIteration=" + currentIteration + "\n");
|
||||
|
||||
// on the first iteration, setup a single particle that's slowly moving
|
||||
if (currentIteration == 0) {
|
||||
var colorGreen = { red: 0, green: 255, blue: 0 };
|
||||
var startPosition = {
|
||||
x: 2/TREE_SCALE,
|
||||
y: 0/TREE_SCALE,
|
||||
z: 2/TREE_SCALE };
|
||||
var largeRadius = 0.5/TREE_SCALE;
|
||||
var verySlow = {
|
||||
x: 0.01/TREE_SCALE,
|
||||
y: 0/TREE_SCALE,
|
||||
z: 0.01/TREE_SCALE };
|
||||
|
||||
Particles.queueParticleAdd(startPosition, largeRadius, colorGreen, verySlow, gravity, damping, false, scriptA);
|
||||
print("hello... added particle... script=\n");
|
||||
print(scriptA);
|
||||
numberParticlesAdded++;
|
||||
}
|
||||
|
||||
if (currentIteration++ % NUM_ITERATIONS_BEFORE_SEND === 0) {
|
||||
print("draw()... sending another... currentIteration=" +currentIteration + "\n");
|
||||
|
||||
var center = {
|
||||
x: 0/TREE_SCALE,
|
||||
y: 0/TREE_SCALE,
|
||||
z: 0/TREE_SCALE };
|
||||
|
||||
var particleSize = 0.1 / TREE_SCALE;
|
||||
|
||||
print("number of particles=" + numberParticlesAdded +"\n");
|
||||
|
||||
var velocityStep = 0.1/TREE_SCALE;
|
||||
if (velocity.x > 0) {
|
||||
velocity.x -= velocityStep;
|
||||
velocity.z += velocityStep;
|
||||
color.blue = 0;
|
||||
color.green = 255;
|
||||
} else {
|
||||
velocity.x += velocityStep;
|
||||
velocity.z -= velocityStep;
|
||||
color.blue = 255;
|
||||
color.green = 0;
|
||||
}
|
||||
|
||||
if (numberParticlesAdded <= MAX_PARTICLES) {
|
||||
Particles.queueParticleAdd(center, particleSize, color, velocity, gravity, damping, false, scriptB);
|
||||
print("hello... added particle... script=\n");
|
||||
print(scriptB);
|
||||
numberParticlesAdded++;
|
||||
} else {
|
||||
Agent.stop();
|
||||
}
|
||||
|
||||
print("Particles Stats: " + Particles.getLifetimeInSeconds() + " seconds," +
|
||||
" Queued packets:" + Particles.getLifetimePacketsQueued() + "," +
|
||||
" PPS:" + Particles.getLifetimePPSQueued() + "," +
|
||||
" BPS:" + Particles.getLifetimeBPSQueued() + "," +
|
||||
" Sent packets:" + Particles.getLifetimePacketsSent() + "," +
|
||||
" PPS:" + Particles.getLifetimePPS() + "," +
|
||||
" BPS:" + Particles.getLifetimeBPS() +
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// register the call back so it fires before each data send
|
||||
print("here...\n");
|
||||
Particles.setPacketsPerSecond(40000);
|
||||
Agent.willSendVisualDataCallback.connect(draw);
|
||||
print("and here...\n");
|
98
examples/gun.js
Normal file
98
examples/gun.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
// initialize our triggers
|
||||
var triggerPulled = new Array();
|
||||
var numberOfTriggers = Controller.getNumberOfTriggers();
|
||||
for (t = 0; t < numberOfTriggers; t++) {
|
||||
triggerPulled[t] = false;
|
||||
}
|
||||
|
||||
function checkController() {
|
||||
var numberOfTriggers = Controller.getNumberOfTriggers();
|
||||
var numberOfSpatialControls = Controller.getNumberOfSpatialControls();
|
||||
var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers;
|
||||
//print("numberOfTriggers:" + numberOfTriggers + "\n");
|
||||
//print("numberOfSpatialControls:" + numberOfSpatialControls + "\n");
|
||||
//print("controllersPerTrigger:" + controllersPerTrigger + "\n");
|
||||
|
||||
// this is expected for hydras
|
||||
if (numberOfTriggers == 2 && controllersPerTrigger == 2) {
|
||||
for (var t = 0; t < numberOfTriggers; t++) {
|
||||
var shootABullet = false;
|
||||
var triggerValue = Controller.getTriggerValue(t);
|
||||
|
||||
if (triggerPulled[t]) {
|
||||
// must release to at least 0.1
|
||||
if (triggerValue < 0.1) {
|
||||
triggerPulled[t] = false; // unpulled
|
||||
}
|
||||
} else {
|
||||
// must pull to at least 0.9
|
||||
if (triggerValue > 0.9) {
|
||||
triggerPulled[t] = true; // pulled
|
||||
shootABullet = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shootABullet) {
|
||||
var palmController = t * controllersPerTrigger;
|
||||
var palmPosition = Controller.getSpatialControlPosition(palmController);
|
||||
|
||||
var fingerTipController = palmController + 1;
|
||||
var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController);
|
||||
|
||||
var bulletSize = 0.25/TREE_SCALE;
|
||||
|
||||
var palmInParticleSpace =
|
||||
{ x: palmPosition.x/TREE_SCALE,
|
||||
y: palmPosition.y/TREE_SCALE,
|
||||
z: palmPosition.z/TREE_SCALE };
|
||||
|
||||
var tipInParticleSpace =
|
||||
{ x: fingerTipPosition.x/TREE_SCALE,
|
||||
y: fingerTipPosition.y/TREE_SCALE,
|
||||
z: fingerTipPosition.z/TREE_SCALE };
|
||||
|
||||
var palmToFingerTipVector =
|
||||
{ x: (tipInParticleSpace.x - palmInParticleSpace.x),
|
||||
y: (tipInParticleSpace.y - palmInParticleSpace.y),
|
||||
z: (tipInParticleSpace.z - palmInParticleSpace.z) };
|
||||
|
||||
// just off the front of the finger tip
|
||||
var position = { x: tipInParticleSpace.x + palmToFingerTipVector.x/2,
|
||||
y: tipInParticleSpace.y + palmToFingerTipVector.y/2,
|
||||
z: tipInParticleSpace.z + palmToFingerTipVector.z/2};
|
||||
|
||||
var linearVelocity = 50; // 50 meters per second
|
||||
|
||||
var velocity = { x: palmToFingerTipVector.x * linearVelocity,
|
||||
y: palmToFingerTipVector.y * linearVelocity,
|
||||
z: palmToFingerTipVector.z * linearVelocity };
|
||||
|
||||
var gravity = { x: 0, y: -0.1/TREE_SCALE, z: 0 }; // gravity has no effect on these bullets
|
||||
var color = { red: 128, green: 128, blue: 128 };
|
||||
var damping = 0; // no damping
|
||||
var inHand = false;
|
||||
var 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); " +
|
||||
" 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); ";
|
||||
|
||||
Particles.queueParticleAdd(position, bulletSize, color, velocity, gravity, damping, inHand, script);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// register the call back so it fires before each data send
|
||||
Agent.willSendVisualDataCallback.connect(checkController);
|
|
@ -57,6 +57,7 @@
|
|||
#include "Util.h"
|
||||
#include "devices/LeapManager.h"
|
||||
#include "devices/OculusManager.h"
|
||||
#include "devices/TV3DManager.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
#include "ui/TextRenderer.h"
|
||||
#include "InfoView.h"
|
||||
|
@ -439,7 +440,10 @@ void Application::paintGL() {
|
|||
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::display(whichCamera);
|
||||
|
||||
} else if (TV3DManager::isConnected()) {
|
||||
_glowEffect.prepare();
|
||||
TV3DManager::display(whichCamera);
|
||||
_glowEffect.render();
|
||||
} else {
|
||||
_glowEffect.prepare();
|
||||
|
||||
|
@ -474,8 +478,10 @@ void Application::paintGL() {
|
|||
_mirrorCamera.update(1.0f/_fps);
|
||||
|
||||
// set the bounds of rear mirror view
|
||||
glViewport(_mirrorViewRect.x(), _glWidget->height() - _mirrorViewRect.y() - _mirrorViewRect.height(), _mirrorViewRect.width(), _mirrorViewRect.height());
|
||||
glScissor(_mirrorViewRect.x(), _glWidget->height() - _mirrorViewRect.y() - _mirrorViewRect.height(), _mirrorViewRect.width(), _mirrorViewRect.height());
|
||||
glViewport(_mirrorViewRect.x(), _glWidget->height() - _mirrorViewRect.y() - _mirrorViewRect.height(),
|
||||
_mirrorViewRect.width(), _mirrorViewRect.height());
|
||||
glScissor(_mirrorViewRect.x(), _glWidget->height() - _mirrorViewRect.y() - _mirrorViewRect.height(),
|
||||
_mirrorViewRect.width(), _mirrorViewRect.height());
|
||||
bool updateViewFrustum = false;
|
||||
updateProjectionMatrix(_mirrorCamera, updateViewFrustum);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
@ -506,7 +512,6 @@ void Application::paintGL() {
|
|||
// restore absolute translations
|
||||
_myAvatar.getSkeletonModel().setTranslation(absoluteSkeletonTranslation);
|
||||
_myAvatar.getHead().getFaceModel().setTranslation(absoluteFaceTranslation);
|
||||
|
||||
} else {
|
||||
displaySide(_mirrorCamera, true);
|
||||
}
|
||||
|
@ -531,7 +536,8 @@ void Application::paintGL() {
|
|||
void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) {
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::configureCamera(camera, width, height);
|
||||
|
||||
} else if (TV3DManager::isConnected()) {
|
||||
TV3DManager::configureCamera(camera, width, height);
|
||||
} else {
|
||||
camera.setAspectRatio((float)width / height);
|
||||
camera.setFieldOfView(Menu::getInstance()->getFieldOfView());
|
||||
|
@ -910,7 +916,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
case Qt::Key_J:
|
||||
if (isShifted) {
|
||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f);
|
||||
|
||||
if (TV3DManager::isConnected()) {
|
||||
TV3DManager::configureCamera(_myCamera, _glWidget->width(),_glWidget->height());
|
||||
}
|
||||
} else {
|
||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0));
|
||||
}
|
||||
|
@ -920,6 +928,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
case Qt::Key_M:
|
||||
if (isShifted) {
|
||||
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f);
|
||||
if (TV3DManager::isConnected()) {
|
||||
TV3DManager::configureCamera(_myCamera, _glWidget->width(),_glWidget->height());
|
||||
}
|
||||
|
||||
} else {
|
||||
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(0.001, 0, 0));
|
||||
|
@ -1518,10 +1529,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
|
||||
|
@ -1828,6 +1850,13 @@ void Application::init() {
|
|||
"trigger",
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
TV3DManager::connect();
|
||||
if (TV3DManager::isConnected()) {
|
||||
QMetaObject::invokeMethod(Menu::getInstance()->getActionForOption(MenuOption::Fullscreen),
|
||||
"trigger",
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
LeapManager::initialize();
|
||||
|
||||
|
@ -2415,7 +2444,7 @@ void Application::updateCamera(float deltaTime) {
|
|||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateCamera()");
|
||||
|
||||
if (!OculusManager::isConnected()) {
|
||||
if (!OculusManager::isConnected() && !TV3DManager::isConnected()) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
||||
_myCamera.setMode(CAMERA_MODE_MIRROR);
|
||||
|
@ -3800,7 +3829,7 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
return;
|
||||
}
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... Avatars...");
|
||||
"Application::renderAvatars()");
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
// Render avatars of other nodes
|
||||
|
@ -4089,7 +4118,7 @@ void Application::resetSensors() {
|
|||
if (OculusManager::isConnected()) {
|
||||
OculusManager::reset();
|
||||
}
|
||||
|
||||
|
||||
QCursor::setPos(_headMouseX, _headMouseY);
|
||||
_myAvatar.reset();
|
||||
_myTransmitter.resetLevels();
|
||||
|
@ -4455,8 +4484,8 @@ void Application::loadScript() {
|
|||
|
||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||
// we can use the same ones from the application.
|
||||
scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender);
|
||||
scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||
scriptEngine->getVoxelsScriptingInterface()->setPacketSender(&_voxelEditSender);
|
||||
scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||
|
||||
QThread* workerThread = new QThread(this);
|
||||
|
||||
|
|
|
@ -254,7 +254,6 @@ private slots:
|
|||
void shrinkMirrorView();
|
||||
void resetSensors();
|
||||
|
||||
|
||||
private:
|
||||
void resetCamerasOnResizeGL(Camera& camera, int width, int height);
|
||||
void updateProjectionMatrix();
|
||||
|
|
|
@ -232,6 +232,8 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H);
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false);
|
||||
|
||||
|
||||
QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size");
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ namespace MenuOption {
|
|||
const QString FilterSixense = "Smooth Sixense Movement";
|
||||
const QString DontRenderVoxels = "Don't call _voxels.render()";
|
||||
const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels";
|
||||
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
||||
const QString EnableOcclusionCulling = "Enable Occlusion Culling";
|
||||
const QString EnableVoxelPacketCompression = "Enable Voxel Packet Compression";
|
||||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
|
|
|
@ -118,7 +118,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
|
|||
NO_GRAVITY,
|
||||
NO_DAMPING,
|
||||
IN_HAND, // we just grabbed it!
|
||||
closestParticle->getUpdateScript());
|
||||
closestParticle->getScript());
|
||||
|
||||
|
||||
// now tell our hand about us having caught it...
|
||||
|
@ -127,12 +127,12 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
|
|||
//printf(">>>>>>> caught... handID:%d particle ID:%d _toyBallInHand[handID] = true\n", handID, closestParticle->getID());
|
||||
_ballParticleEditHandles[handID] = caughtParticle;
|
||||
caughtParticle = NULL;
|
||||
// Play a catch sound!
|
||||
|
||||
// set the position of the catch sound to the new position of the ball
|
||||
_catchInjector.setPosition(targetPosition);
|
||||
|
||||
// inject the catch sound to the mixer and play it locally
|
||||
_catchInjector.injectViaThread(app->getAudio());
|
||||
app->getAudio()->startDrumSound(1.0, 300, 0.75, 0.015);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
132
interface/src/devices/TV3DManager.cpp
Normal file
132
interface/src/devices/TV3DManager.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// TV3DManager.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/24/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Application.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "TV3DManager.h"
|
||||
#include "Menu.h"
|
||||
|
||||
int TV3DManager::_screenWidth = 1;
|
||||
int TV3DManager::_screenHeight = 1;
|
||||
double TV3DManager::_aspect = 1.0;
|
||||
eyeFrustum TV3DManager::_leftEye;
|
||||
eyeFrustum TV3DManager::_rightEye;
|
||||
|
||||
|
||||
bool TV3DManager::isConnected() {
|
||||
return Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode);
|
||||
}
|
||||
|
||||
void TV3DManager::connect() {
|
||||
Application* app = Application::getInstance();
|
||||
int width = app->getGLWidget()->width();
|
||||
int height = app->getGLWidget()->height();
|
||||
Camera& camera = *app->getCamera();
|
||||
|
||||
configureCamera(camera, width, height);
|
||||
}
|
||||
|
||||
|
||||
// The basic strategy of this stereoscopic rendering is explained here:
|
||||
// http://www.orthostereo.com/geometryopengl.html
|
||||
void TV3DManager::setFrustum(Camera& whichCamera) {
|
||||
const double DTR = 0.0174532925; // degree to radians
|
||||
const double IOD = 0.05; //intraocular distance
|
||||
double fovy = whichCamera.getFieldOfView(); // field of view in y-axis
|
||||
double nearZ = whichCamera.getNearClip(); // near clipping plane
|
||||
double screenZ = Application::getInstance()->getViewFrustum()->getFocalLength(); // screen projection plane
|
||||
|
||||
double top = nearZ * tan(DTR * fovy / 2); //sets top of frustum based on fovy and near clipping plane
|
||||
double right = _aspect * top; // sets right of frustum based on aspect ratio
|
||||
double frustumshift = (IOD / 2) * nearZ / screenZ;
|
||||
|
||||
_leftEye.top = top;
|
||||
_leftEye.bottom = -top;
|
||||
_leftEye.left = -right + frustumshift;
|
||||
_leftEye.right = right + frustumshift;
|
||||
_leftEye.modelTranslation = IOD / 2;
|
||||
|
||||
_rightEye.top = top;
|
||||
_rightEye.bottom = -top;
|
||||
_rightEye.left = -right - frustumshift;
|
||||
_rightEye.right = right - frustumshift;
|
||||
_rightEye.modelTranslation = -IOD / 2;
|
||||
}
|
||||
|
||||
void TV3DManager::configureCamera(Camera& whichCamera, int screenWidth, int screenHeight) {
|
||||
if (screenHeight == 0) {
|
||||
screenHeight = 1; // prevent divide by 0
|
||||
}
|
||||
_screenWidth = screenWidth;
|
||||
_screenHeight = screenHeight;
|
||||
_aspect= (double)_screenWidth / (double)_screenHeight;
|
||||
setFrustum(whichCamera);
|
||||
|
||||
glViewport (0, 0, _screenWidth, _screenHeight); // sets drawing viewport
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void TV3DManager::display(Camera& whichCamera) {
|
||||
double nearZ = whichCamera.getNearClip(); // near clipping plane
|
||||
double farZ = whichCamera.getFarClip(); // far clipping plane
|
||||
|
||||
// left eye portal
|
||||
int portalX = 0;
|
||||
int portalY = 0;
|
||||
int portalW = Application::getInstance()->getGLWidget()->width() / 2;
|
||||
int portalH = Application::getInstance()->getGLWidget()->height();
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// render left side view
|
||||
glViewport(portalX, portalY, portalW, portalH);
|
||||
glScissor(portalX, portalY, portalW, portalH);
|
||||
|
||||
glPushMatrix();
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // reset projection matrix
|
||||
glFrustum(_leftEye.left, _leftEye.right, _leftEye.bottom, _leftEye.top, nearZ, farZ); // set left view frustum
|
||||
glTranslatef(_leftEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
Application::getInstance()->displaySide(whichCamera);
|
||||
}
|
||||
glPopMatrix();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// render right side view
|
||||
portalX = Application::getInstance()->getGLWidget()->width() / 2;
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// render left side view
|
||||
glViewport(portalX, portalY, portalW, portalH);
|
||||
glScissor(portalX, portalY, portalW, portalH);
|
||||
glPushMatrix();
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // reset projection matrix
|
||||
glFrustum(_rightEye.left, _rightEye.right, _rightEye.bottom, _rightEye.top, nearZ, farZ); // set left view frustum
|
||||
glTranslatef(_rightEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
Application::getInstance()->displaySide(whichCamera);
|
||||
}
|
||||
glPopMatrix();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// reset the viewport to how we started
|
||||
glViewport(0, 0, Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height());
|
||||
}
|
41
interface/src/devices/TV3DManager.h
Normal file
41
interface/src/devices/TV3DManager.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// TV3DManager.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/24/2013
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__TV3DManager__
|
||||
#define __hifi__TV3DManager__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class Camera;
|
||||
|
||||
struct eyeFrustum {
|
||||
double left;
|
||||
double right;
|
||||
double bottom;
|
||||
double top;
|
||||
float modelTranslation;
|
||||
};
|
||||
|
||||
|
||||
/// Handles interaction with 3D TVs
|
||||
class TV3DManager {
|
||||
public:
|
||||
static void connect();
|
||||
static bool isConnected();
|
||||
static void configureCamera(Camera& camera, int screenWidth, int screenHeight);
|
||||
static void display(Camera& whichCamera);
|
||||
private:
|
||||
static void setFrustum(Camera& whichCamera);
|
||||
static int _screenWidth;
|
||||
static int _screenHeight;
|
||||
static double _aspect;
|
||||
static eyeFrustum _leftEye;
|
||||
static eyeFrustum _rightEye;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__TV3DManager__) */
|
|
@ -14,9 +14,14 @@
|
|||
#include <SharedUtil.h> // usecTimestampNow()
|
||||
#include <Octree.h>
|
||||
|
||||
#include <VoxelsScriptingInterface.h>
|
||||
#include "ParticlesScriptingInterface.h"
|
||||
|
||||
#include "Particle.h"
|
||||
|
||||
uint32_t Particle::_nextID = 0;
|
||||
VoxelsScriptingInterface* Particle::_voxelsScriptingInterface = NULL;
|
||||
ParticlesScriptingInterface* Particle::_particlesScriptingInterface = NULL;
|
||||
|
||||
|
||||
Particle::Particle(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, glm::vec3 gravity,
|
||||
|
@ -53,8 +58,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 +101,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 +212,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 +305,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;
|
||||
|
||||
|
@ -320,6 +326,7 @@ void Particle::debugDump() const {
|
|||
printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z);
|
||||
printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z);
|
||||
printf(" gravity:%f,%f,%f\n", _gravity.x, _gravity.y, _gravity.z);
|
||||
printf(" color:%d,%d,%d\n", _color[0], _color[1], _color[2]);
|
||||
}
|
||||
|
||||
bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, const ParticleDetail* details,
|
||||
|
@ -471,7 +478,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;
|
||||
|
@ -482,7 +489,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) {
|
||||
|
@ -504,11 +511,9 @@ void Particle::update() {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -521,9 +526,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();
|
||||
|
@ -532,6 +537,100 @@ void Particle::runScript() {
|
|||
}
|
||||
}
|
||||
|
||||
void Particle::collisionWithParticle(Particle* other) {
|
||||
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);
|
||||
|
||||
ParticleScriptObject otherParticleScriptable(other);
|
||||
particleScriptable.emitCollisionWithParticle(&otherParticleScriptable);
|
||||
|
||||
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::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;
|
||||
_created = usecTimestampNow() - lifetimeInUsecs;
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
#include <SharedUtil.h>
|
||||
#include <OctreePacketData.h>
|
||||
|
||||
class VoxelsScriptingInterface;
|
||||
class ParticlesScriptingInterface;
|
||||
|
||||
|
||||
const uint32_t NEW_PARTICLE = 0xFFFFFFFF;
|
||||
const uint32_t UNKNOWN_TOKEN = 0xFFFFFFFF;
|
||||
|
||||
|
@ -79,7 +83,7 @@ public:
|
|||
float getEditedAgo() const { return static_cast<float>(usecTimestampNow() - _lastEdited) / static_cast<float>(USECS_PER_SECOND); }
|
||||
uint32_t getID() const { return _id; }
|
||||
bool getShouldDie() const { return _shouldDie; }
|
||||
QString getUpdateScript() const { return _updateScript; }
|
||||
QString getScript() const { return _script; }
|
||||
uint32_t getCreatorTokenID() const { return _creatorTokenID; }
|
||||
bool isNewlyCreated() const { return _newlyCreated; }
|
||||
|
||||
|
@ -96,7 +100,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 setScript(QString updateScript) { _script = updateScript; }
|
||||
void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; }
|
||||
|
||||
bool appendParticleData(OctreePacketData* packetData) const;
|
||||
|
@ -110,14 +114,28 @@ public:
|
|||
static void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
|
||||
|
||||
void update();
|
||||
void collisionWithParticle(Particle* other);
|
||||
void collisionWithVoxel(VoxelDetail* voxel);
|
||||
|
||||
void debugDump() const;
|
||||
|
||||
// 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 void setVoxelsScriptingInterface(VoxelsScriptingInterface* interface)
|
||||
{ _voxelsScriptingInterface = interface; }
|
||||
|
||||
static void setParticlesScriptingInterface(ParticlesScriptingInterface* interface)
|
||||
{ _particlesScriptingInterface = interface; }
|
||||
|
||||
protected:
|
||||
void runScript();
|
||||
static VoxelsScriptingInterface* _voxelsScriptingInterface;
|
||||
static ParticlesScriptingInterface* _particlesScriptingInterface;
|
||||
|
||||
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 +152,7 @@ protected:
|
|||
bool _shouldDie;
|
||||
glm::vec3 _gravity;
|
||||
float _damping;
|
||||
QString _updateScript;
|
||||
QString _script;
|
||||
bool _inHand;
|
||||
|
||||
uint32_t _creatorTokenID;
|
||||
|
@ -152,7 +170,12 @@ class ParticleScriptObject : public QObject {
|
|||
public:
|
||||
ParticleScriptObject(Particle* particle) { _particle = particle; }
|
||||
|
||||
void emitUpdate() { emit update(); }
|
||||
void emitCollisionWithParticle(QObject* other) { emit collisionWithParticle(other); }
|
||||
void emitCollisionWithVoxel(QObject* voxel) { emit collisionWithVoxel(voxel); }
|
||||
|
||||
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(); }
|
||||
|
@ -169,6 +192,12 @@ public slots:
|
|||
void setColor(xColor value) { _particle->setColor(value); }
|
||||
void setRadius(float value) { _particle->setRadius(value); }
|
||||
void setShouldDie(bool value) { _particle->setShouldDie(value); }
|
||||
void setScript(const QString& script) { _particle->setScript(script); }
|
||||
|
||||
signals:
|
||||
void update();
|
||||
void collisionWithVoxel(QObject* voxel);
|
||||
void collisionWithParticle(QObject* other);
|
||||
|
||||
private:
|
||||
Particle* _particle;
|
||||
|
|
|
@ -73,11 +73,17 @@ void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) {
|
|||
const float VOXEL_DAMPING = 0.0f;
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +96,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);
|
||||
penetratedParticle->collisionWithParticle(particle);
|
||||
|
||||
penetration /= (float)TREE_SCALE;
|
||||
updateCollisionSound(particle, penetration, VOXEL_COLLISION_FREQUENCY);
|
||||
// apply a hard collision to both particles of half the penetration each
|
||||
|
@ -240,8 +251,7 @@ void ParticleCollisionSystem::applyHardCollision(Particle* particle, const glm::
|
|||
|
||||
ParticleEditHandle particleEditHandle(_packetSender, _particles, particle->getID());
|
||||
particleEditHandle.updateParticle(position, particle->getRadius(), particle->getXColor(), velocity,
|
||||
particle->getGravity(), particle->getDamping(), particle->getInHand(),
|
||||
particle->getUpdateScript());
|
||||
particle->getGravity(), particle->getDamping(), particle->getInHand(), particle->getScript());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
//
|
||||
// ParticleScriptingInterface.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "ParticleScriptingInterface.h"
|
||||
|
||||
|
||||
|
||||
void ParticleScriptingInterface::queueParticleAdd(PACKET_TYPE addPacketType, ParticleDetail& addParticleDetails) {
|
||||
getParticlePacketSender()->queueParticleEditMessages(addPacketType, 1, &addParticleDetails);
|
||||
}
|
||||
|
||||
unsigned int ParticleScriptingInterface::queueParticleAdd(glm::vec3 position, float radius,
|
||||
xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, bool inHand, QString updateScript) {
|
||||
|
||||
// The application will keep track of creatorTokenID
|
||||
uint32_t creatorTokenID = _nextCreatorTokenID;
|
||||
_nextCreatorTokenID++;
|
||||
|
||||
// setup a ParticleDetail struct with the data
|
||||
uint64_t now = usecTimestampNow();
|
||||
ParticleDetail addParticleDetail = { NEW_PARTICLE, now,
|
||||
position, radius, {color.red, color.green, color.blue }, velocity,
|
||||
gravity, damping, inHand, updateScript, creatorTokenID };
|
||||
|
||||
// queue the packet
|
||||
queueParticleAdd(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, addParticleDetail);
|
||||
|
||||
return creatorTokenID;
|
||||
}
|
48
libraries/particles/src/ParticlesScriptingInterface.cpp
Normal file
48
libraries/particles/src/ParticlesScriptingInterface.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// ParticlesScriptingInterface.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "ParticlesScriptingInterface.h"
|
||||
|
||||
|
||||
|
||||
void ParticlesScriptingInterface::queueParticleMessage(PACKET_TYPE packetType, ParticleDetail& particleDetails) {
|
||||
getParticlePacketSender()->queueParticleEditMessages(packetType, 1, &particleDetails);
|
||||
}
|
||||
|
||||
unsigned int ParticlesScriptingInterface::queueParticleAdd(glm::vec3 position, float radius,
|
||||
xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, bool inHand, QString script) {
|
||||
|
||||
// The application will keep track of creatorTokenID
|
||||
uint32_t creatorTokenID = _nextCreatorTokenID;
|
||||
_nextCreatorTokenID++;
|
||||
|
||||
// setup a ParticleDetail struct with the data
|
||||
uint64_t now = usecTimestampNow();
|
||||
ParticleDetail addParticleDetail = { NEW_PARTICLE, now,
|
||||
position, radius, {color.red, color.green, color.blue }, velocity,
|
||||
gravity, damping, inHand, script, creatorTokenID };
|
||||
|
||||
// queue the packet
|
||||
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, addParticleDetail);
|
||||
|
||||
return creatorTokenID;
|
||||
}
|
||||
|
||||
|
||||
void ParticlesScriptingInterface::queueParticleEdit(unsigned int particleID, glm::vec3 position, float radius,
|
||||
xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, bool inHand, QString script) {
|
||||
|
||||
// setup a ParticleDetail struct with the data
|
||||
uint64_t now = usecTimestampNow();
|
||||
ParticleDetail editParticleDetail = { particleID, now,
|
||||
position, radius, {color.red, color.green, color.blue }, velocity,
|
||||
gravity, damping, inHand, script, UNKNOWN_TOKEN };
|
||||
|
||||
// queue the packet
|
||||
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, editParticleDetail);
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
//
|
||||
// ParticleScriptingInterface.h
|
||||
// ParticlesScriptingInterface.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/6/13
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__ParticleScriptingInterface__
|
||||
#define __hifi__ParticleScriptingInterface__
|
||||
#ifndef __hifi__ParticlesScriptingInterface__
|
||||
#define __hifi__ParticlesScriptingInterface__
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
|||
#include "ParticleEditPacketSender.h"
|
||||
|
||||
/// handles scripting of Particle commands from JS passed to assigned clients
|
||||
class ParticleScriptingInterface : public OctreeScriptingInterface {
|
||||
class ParticlesScriptingInterface : public OctreeScriptingInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ParticleEditPacketSender* getParticlePacketSender() const { return (ParticleEditPacketSender*)getPacketSender(); }
|
||||
|
@ -27,12 +27,15 @@ public slots:
|
|||
/// queues the creation of a Particle which will be sent by calling process on the PacketSender
|
||||
/// returns the creatorTokenID for the newly created particle
|
||||
unsigned int queueParticleAdd(glm::vec3 position, float radius,
|
||||
xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, bool inHand, QString updateScript);
|
||||
xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, bool inHand, QString script);
|
||||
|
||||
void queueParticleEdit(unsigned int particleID, glm::vec3 position, float radius,
|
||||
xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, bool inHand, QString script);
|
||||
|
||||
private:
|
||||
void queueParticleAdd(PACKET_TYPE addPacketType, ParticleDetail& addParticleDetails);
|
||||
void queueParticleMessage(PACKET_TYPE packetType, ParticleDetail& particleDetails);
|
||||
|
||||
uint32_t _nextCreatorTokenID;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__ParticleScriptingInterface__) */
|
||||
#endif /* defined(__hifi__ParticlesScriptingInterface__) */
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Agent.cpp
|
||||
// ScriptEngine.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/14/13.
|
||||
|
@ -23,6 +23,9 @@
|
|||
#include "ScriptEngine.h"
|
||||
|
||||
int ScriptEngine::_scriptNumber = 1;
|
||||
VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface;
|
||||
ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface;
|
||||
|
||||
|
||||
ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems,
|
||||
const char* scriptMenuName, AbstractMenuInterface* menu,
|
||||
|
@ -43,6 +46,15 @@ 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() {
|
||||
|
@ -74,8 +86,8 @@ void ScriptEngine::run() {
|
|||
_isRunning = true;
|
||||
QScriptEngine engine;
|
||||
|
||||
_voxelScriptingInterface.init();
|
||||
_particleScriptingInterface.init();
|
||||
_voxelsScriptingInterface.init();
|
||||
_particlesScriptingInterface.init();
|
||||
|
||||
// register meta-type for glm::vec3 conversions
|
||||
registerMetaTypes(&engine);
|
||||
|
@ -83,10 +95,10 @@ void ScriptEngine::run() {
|
|||
QScriptValue agentValue = engine.newQObject(this);
|
||||
engine.globalObject().setProperty("Agent", agentValue);
|
||||
|
||||
QScriptValue voxelScripterValue = engine.newQObject(&_voxelScriptingInterface);
|
||||
QScriptValue voxelScripterValue = engine.newQObject(&_voxelsScriptingInterface);
|
||||
engine.globalObject().setProperty("Voxels", voxelScripterValue);
|
||||
|
||||
QScriptValue particleScripterValue = engine.newQObject(&_particleScriptingInterface);
|
||||
QScriptValue particleScripterValue = engine.newQObject(&_particlesScriptingInterface);
|
||||
engine.globalObject().setProperty("Particles", particleScripterValue);
|
||||
|
||||
if (_controllerScriptingInterface) {
|
||||
|
@ -100,8 +112,8 @@ void ScriptEngine::run() {
|
|||
const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
|
||||
|
||||
// let the VoxelPacketSender know how frequently we plan to call it
|
||||
_voxelScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
||||
_particleScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
||||
_voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
||||
_particlesScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
||||
|
||||
//qDebug() << "Script:\n" << _scriptContents << "\n";
|
||||
|
||||
|
@ -135,29 +147,29 @@ void ScriptEngine::run() {
|
|||
}
|
||||
|
||||
bool willSendVisualDataCallBack = false;
|
||||
if (_voxelScriptingInterface.getVoxelPacketSender()->serversExist()) {
|
||||
if (_voxelsScriptingInterface.getVoxelPacketSender()->serversExist()) {
|
||||
// allow the scripter's call back to setup visual data
|
||||
willSendVisualDataCallBack = true;
|
||||
|
||||
// release the queue of edit voxel messages.
|
||||
_voxelScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages();
|
||||
_voxelsScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages();
|
||||
|
||||
// since we're in non-threaded mode, call process so that the packets are sent
|
||||
if (!_voxelScriptingInterface.getVoxelPacketSender()->isThreaded()) {
|
||||
_voxelScriptingInterface.getVoxelPacketSender()->process();
|
||||
if (!_voxelsScriptingInterface.getVoxelPacketSender()->isThreaded()) {
|
||||
_voxelsScriptingInterface.getVoxelPacketSender()->process();
|
||||
}
|
||||
}
|
||||
|
||||
if (_particleScriptingInterface.getParticlePacketSender()->serversExist()) {
|
||||
if (_particlesScriptingInterface.getParticlePacketSender()->serversExist()) {
|
||||
// allow the scripter's call back to setup visual data
|
||||
willSendVisualDataCallBack = true;
|
||||
|
||||
// release the queue of edit voxel messages.
|
||||
_particleScriptingInterface.getParticlePacketSender()->releaseQueuedMessages();
|
||||
_particlesScriptingInterface.getParticlePacketSender()->releaseQueuedMessages();
|
||||
|
||||
// since we're in non-threaded mode, call process so that the packets are sent
|
||||
if (!_particleScriptingInterface.getParticlePacketSender()->isThreaded()) {
|
||||
_particleScriptingInterface.getParticlePacketSender()->process();
|
||||
if (!_particlesScriptingInterface.getParticlePacketSender()->isThreaded()) {
|
||||
_particlesScriptingInterface.getParticlePacketSender()->process();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include <QtCore/QUrl>
|
||||
|
||||
#include <AbstractMenuInterface.h>
|
||||
#include <ParticleScriptingInterface.h>
|
||||
#include <VoxelScriptingInterface.h>
|
||||
#include <ParticlesScriptingInterface.h>
|
||||
#include <VoxelsScriptingInterface.h>
|
||||
#include "AbstractControllerScriptingInterface.h"
|
||||
|
||||
const QString NO_SCRIPT("");
|
||||
|
@ -31,11 +31,11 @@ public:
|
|||
|
||||
~ScriptEngine();
|
||||
|
||||
/// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
||||
VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; }
|
||||
/// Access the VoxelsScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
||||
VoxelsScriptingInterface* getVoxelsScriptingInterface() { return &_voxelsScriptingInterface; }
|
||||
|
||||
/// Access the ParticleScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
||||
ParticleScriptingInterface* getParticleScriptingInterface() { return &_particleScriptingInterface; }
|
||||
/// Access the ParticlesScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
|
||||
ParticlesScriptingInterface* getParticlesScriptingInterface() { return &_particlesScriptingInterface; }
|
||||
|
||||
/// sets the script contents, will return false if failed, will fail if script is already running
|
||||
bool setScriptContents(const QString& scriptContents);
|
||||
|
@ -58,8 +58,8 @@ protected:
|
|||
|
||||
|
||||
private:
|
||||
VoxelScriptingInterface _voxelScriptingInterface;
|
||||
ParticleScriptingInterface _particleScriptingInterface;
|
||||
static VoxelsScriptingInterface _voxelsScriptingInterface;
|
||||
static ParticlesScriptingInterface _particlesScriptingInterface;
|
||||
AbstractControllerScriptingInterface* _controllerScriptingInterface;
|
||||
bool _wantMenuItems;
|
||||
QString _scriptMenuName;
|
||||
|
|
|
@ -294,9 +294,9 @@ void NodeList::clear() {
|
|||
Node* node = nodeBucket[i % NODES_PER_BUCKET];
|
||||
|
||||
node->lock();
|
||||
delete node;
|
||||
notifyHooksOfKilledNode(&*node);
|
||||
|
||||
node = NULL;
|
||||
delete node;
|
||||
}
|
||||
|
||||
_numNodes = 0;
|
||||
|
|
|
@ -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__) */
|
|
@ -1,18 +1,18 @@
|
|||
//
|
||||
// VoxelScriptingInterface.cpp
|
||||
// VoxelsScriptingInterface.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 9/17/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "VoxelScriptingInterface.h"
|
||||
#include "VoxelsScriptingInterface.h"
|
||||
|
||||
void VoxelScriptingInterface::queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails) {
|
||||
void VoxelsScriptingInterface::queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails) {
|
||||
getVoxelPacketSender()->queueVoxelEditMessages(addPacketType, 1, &addVoxelDetails);
|
||||
}
|
||||
|
||||
void VoxelScriptingInterface::queueVoxelAdd(float x, float y, float z, float scale, uchar red, uchar green, uchar blue) {
|
||||
void VoxelsScriptingInterface::queueVoxelAdd(float x, float y, float z, float scale, uchar red, uchar green, uchar blue) {
|
||||
// setup a VoxelDetail struct with the data
|
||||
VoxelDetail addVoxelDetail = {x, y, z, scale, red, green, blue};
|
||||
|
||||
|
@ -20,7 +20,7 @@ void VoxelScriptingInterface::queueVoxelAdd(float x, float y, float z, float sca
|
|||
queueVoxelAdd(PACKET_TYPE_VOXEL_SET, addVoxelDetail);
|
||||
}
|
||||
|
||||
void VoxelScriptingInterface::queueDestructiveVoxelAdd(float x, float y, float z, float scale,
|
||||
void VoxelsScriptingInterface::queueDestructiveVoxelAdd(float x, float y, float z, float scale,
|
||||
uchar red, uchar green, uchar blue) {
|
||||
// setup a VoxelDetail struct with the data
|
||||
VoxelDetail addVoxelDetail = {x, y, z, scale, red, green, blue};
|
||||
|
@ -29,7 +29,7 @@ void VoxelScriptingInterface::queueDestructiveVoxelAdd(float x, float y, float z
|
|||
queueVoxelAdd(PACKET_TYPE_VOXEL_SET_DESTRUCTIVE, addVoxelDetail);
|
||||
}
|
||||
|
||||
void VoxelScriptingInterface::queueVoxelDelete(float x, float y, float z, float scale) {
|
||||
void VoxelsScriptingInterface::queueVoxelDelete(float x, float y, float z, float scale) {
|
||||
|
||||
// setup a VoxelDetail struct with data
|
||||
VoxelDetail deleteVoxelDetail = {x, y, z, scale, 0, 0, 0};
|
|
@ -1,13 +1,13 @@
|
|||
//
|
||||
// VoxelScriptingInterface.h
|
||||
// VoxelsScriptingInterface.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 9/17/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__VoxelScriptingInterface__
|
||||
#define __hifi__VoxelScriptingInterface__
|
||||
#ifndef __hifi__VoxelsScriptingInterface__
|
||||
#define __hifi__VoxelsScriptingInterface__
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
|||
#include "VoxelEditPacketSender.h"
|
||||
|
||||
/// handles scripting of voxel commands from JS passed to assigned clients
|
||||
class VoxelScriptingInterface : public OctreeScriptingInterface {
|
||||
class VoxelsScriptingInterface : public OctreeScriptingInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); }
|
||||
|
@ -56,4 +56,18 @@ private:
|
|||
void queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails);
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__VoxelScriptingInterface__) */
|
||||
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