implement support for pose ScriptEndpoints

This commit is contained in:
Brad Hefta-Gaub 2015-12-16 21:28:27 -08:00
parent 76da3a14ac
commit 0b9bd858a7
4 changed files with 117 additions and 2 deletions

View file

@ -34,6 +34,48 @@ var mappingJSON = {
mapping = Controller.parseMapping(JSON.stringify(mappingJSON));
mapping.enable();
var MAPPING_NAME = "com.highfidelity.testing.reticleWithHand";
var mapping2 = Controller.newMapping(MAPPING_NAME);
//mapping2.from(Controller.Standard.RightHand).debug(true).to(Controller.Actions.LeftHand);
/*
mapping2.from(Controller.Standard.RightHand).peek().to(function(pose) {
print("Controller.Standard.RightHand value:" + JSON.stringify(pose));
});
*/
var translation = { x: 0, y: 0.1, z: 0 };
var translationDx = 0.01;
var translationDy = 0.01;
var translationDz = 0.01;
var TRANSLATION_LIMIT = 0.5;
var rotation = Quat.fromPitchYawRollDegrees(45, 0, 45);
mapping2.from(function() {
translation.x = translation.x + translationDx;
translation.y = translation.y + translationDy;
translation.z = translation.z + translationDz;
if ((translation.x > TRANSLATION_LIMIT) || (translation.x < (-1 *TRANSLATION_LIMIT))) {
translationDx = translationDx * -1;
}
if ((translation.y > TRANSLATION_LIMIT) || (translation.y < (-1 *TRANSLATION_LIMIT))) {
translationDy = translationDy * -1;
}
if ((translation.z > TRANSLATION_LIMIT) || (translation.z < (-1 *TRANSLATION_LIMIT))) {
translationDz = translationDz * -1;
}
var pose = {
translation: translation,
rotation: rotation,
velocity: { x: 0, y: 0, z: 0 },
angularVelocity: { x: 0, y: 0, z: 0, w: 1 }
};
return pose;
}).debug(true).to(Controller.Standard.LeftHand);
Controller.enableMapping(MAPPING_NAME);
Script.scriptEnding.connect(function(){
mapping.disable();
});

View file

@ -42,7 +42,23 @@ namespace controller {
}
void Pose::fromScriptValue(const QScriptValue& object, Pose& pose) {
// nothing for now...
bool isValid = true;
auto translation = object.property("translation");
auto rotation = object.property("rotation");
auto velocity = object.property("velocity");
auto angularVelocity = object.property("angularVelocity");
if (translation.isValid() &&
rotation.isValid() &&
velocity.isValid() &&
angularVelocity.isValid()) {
vec3FromScriptValue(translation, pose.translation);
quatFromScriptValue(rotation, pose.rotation);
vec3FromScriptValue(velocity, pose.velocity);
quatFromScriptValue(angularVelocity, pose.angularVelocity);
pose.valid = true;
} else {
pose.valid = false;
}
}
}

View file

@ -10,6 +10,8 @@
#include <QtCore/QThread>
#include <StreamUtils.h>
using namespace controller;
float ScriptEndpoint::peek() const {
@ -23,7 +25,16 @@ void ScriptEndpoint::updateValue() {
return;
}
_lastValueRead = (float)_callable.call().toNumber();
QScriptValue result = _callable.call();
// If the callable ever returns a non-number, we assume it's a pose
// and start reporting ourselves as a pose.
if (result.isNumber()) {
_lastValueRead = (float)_callable.call().toNumber();
} else {
Pose::fromScriptValue(result, _lastPoseRead);
_returnPose = true;
}
}
void ScriptEndpoint::apply(float value, const Pointer& source) {
@ -44,3 +55,36 @@ void ScriptEndpoint::internalApply(float value, int sourceID) {
_callable.call(QScriptValue(),
QScriptValueList({ QScriptValue(value), QScriptValue(sourceID) }));
}
Pose ScriptEndpoint::peekPose() const {
const_cast<ScriptEndpoint*>(this)->updatePose();
return _lastPoseRead;
}
void ScriptEndpoint::updatePose() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "updatePose", Qt::QueuedConnection);
return;
}
QScriptValue result = _callable.call();
Pose::fromScriptValue(result, _lastPoseRead);
}
void ScriptEndpoint::apply(const Pose& newPose, const Pointer& source) {
if (newPose == _lastPoseWritten) {
return;
}
internalApply(newPose, source->getInput().getID());
}
void ScriptEndpoint::internalApply(const Pose& newPose, int sourceID) {
_lastPoseWritten = newPose;
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "internalApply", Qt::QueuedConnection,
Q_ARG(const Pose&, newPose),
Q_ARG(int, sourceID));
return;
}
_callable.call(QScriptValue(),
QScriptValueList({ Pose::toScriptValue(_callable.engine(), newPose), QScriptValue(sourceID) }));
}

View file

@ -27,13 +27,26 @@ public:
virtual float peek() const override;
virtual void apply(float newValue, const Pointer& source) override;
virtual Pose peekPose() const override;
virtual void apply(const Pose& newValue, const Pointer& source) override;
virtual bool isPose() const override { return _returnPose; }
protected:
Q_INVOKABLE void updateValue();
Q_INVOKABLE virtual void internalApply(float newValue, int sourceID);
Q_INVOKABLE void updatePose();
Q_INVOKABLE virtual void internalApply(const Pose& newValue, int sourceID);
private:
QScriptValue _callable;
float _lastValueRead { 0.0f };
float _lastValueWritten { 0.0f };
bool _returnPose { false };
Pose _lastPoseRead;
Pose _lastPoseWritten;
};
}