more scripting support, including adding a Quat helper class that makes JS quat math easier

This commit is contained in:
ZappoMan 2014-01-29 00:56:08 -08:00
parent 434756a40f
commit 98cdc656c4
11 changed files with 100 additions and 31 deletions

View file

@ -105,34 +105,6 @@ glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) {
return glm::angleAxis(angle, axis);
}
// Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's
// http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde,
// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)
glm::vec3 safeEulerAngles(const glm::quat& q) {
float sy = 2.0f * (q.y * q.w - q.x * q.z);
if (sy < 1.0f - EPSILON) {
if (sy > -1.0f + EPSILON) {
return glm::degrees(glm::vec3(
atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)),
asinf(sy),
atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z))));
} else {
// not a unique solution; x + z = atan2(-m21, m11)
return glm::degrees(glm::vec3(
0.0f,
PIf * -0.5f,
atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z))));
}
} else {
// not a unique solution; x - z = atan2(-m21, m11)
return glm::degrees(glm::vec3(
0.0f,
PIf * 0.5f,
-atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z))));
}
}
// Safe version of glm::mix; based on the code in Nick Bobick's article,
// http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde,
// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)

View file

@ -54,8 +54,6 @@ float angleBetween(const glm::vec3& v1, const glm::vec3& v2);
glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2);
glm::vec3 safeEulerAngles(const glm::quat& q);
glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float alpha);
glm::vec3 extractTranslation(const glm::mat4& matrix);

View file

@ -9,8 +9,9 @@
#ifndef __interface__world__
#define __interface__world__
#ifndef PIf
#define PIf 3.14159265f
#endif
const float GRAVITY_EARTH = 9.80665f;
const float EDGE_SIZE_GROUND_PLANE = 20.f;

View file

@ -276,3 +276,10 @@ void AvatarData::setClampedTargetScale(float targetScale) {
_targetScale = targetScale;
qDebug() << "Changed scale to " << _targetScale;
}
void AvatarData::setOrientation(const glm::quat& orientation) {
glm::vec3 eulerAngles = safeEulerAngles(orientation);
_bodyPitch = eulerAngles.x;
_bodyYaw = eulerAngles.y;
_bodyRoll = eulerAngles.z;
}

View file

@ -69,6 +69,9 @@ class AvatarData : public NodeData {
Q_PROPERTY(float bodyPitch READ getBodyPitch WRITE setBodyPitch)
Q_PROPERTY(float bodyRoll READ getBodyRoll WRITE setBodyRoll)
Q_PROPERTY(QString chatMessage READ getQStringChatMessage WRITE setChatMessage)
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
public:
AvatarData();
~AvatarData();
@ -91,6 +94,7 @@ public:
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; }
glm::quat getOrientation() const { return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); }
void setOrientation(const glm::quat& orientation);
// Scale
float getTargetScale() const { return _targetScale; }

View file

@ -0,0 +1,20 @@
//
// Quat.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 1/29/14
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// Scriptable Quaternion class library.
//
//
#include "Quat.h"
glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) {
return q1 * q2;
}
glm::quat Quat::fromVec3(const glm::vec3& vec3) {
return glm::quat(vec3);
}

View file

@ -0,0 +1,29 @@
//
// Quat.h
// hifi
//
// Created by Brad Hefta-Gaub on 1/29/14
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// Scriptable Quaternion class library.
//
//
#ifndef __hifi__Quat__
#define __hifi__Quat__
#include <glm/gtc/quaternion.hpp>
#include <QtCore/QObject>
/// Scriptable interface a Quaternion helper class object. Used exclusively in the JavaScript API
class Quat : public QObject {
Q_OBJECT
public slots:
glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
glm::quat fromVec3(const glm::vec3& vec3);
};
#endif /* defined(__hifi__Quat__) */

View file

@ -134,6 +134,8 @@ void ScriptEngine::init() {
registerGlobalObject("Controller", _controllerScriptingInterface);
registerGlobalObject("Data", &_dataServerScriptingInterface);
registerGlobalObject("Particles", &_particlesScriptingInterface);
registerGlobalObject("Quat", &_quatLibrary);
registerGlobalObject("Voxels", &_voxelsScriptingInterface);
QScriptValue treeScaleValue = _engine.newVariant(QVariant(TREE_SCALE));

View file

@ -25,6 +25,7 @@ class ParticlesScriptingInterface;
#include "AbstractControllerScriptingInterface.h"
#include "DataServerScriptingInterface.h"
#include "Quat.h"
const QString NO_SCRIPT("");
@ -94,6 +95,7 @@ private:
QString _fileNameString;
AbstractMenuInterface* _menu;
static int _scriptNumber;
Quat _quatLibrary;
};
#endif /* defined(__hifi__ScriptEngine__) */

View file

@ -715,3 +715,31 @@ void debug::checkDeadBeef(void* memoryVoid, int size) {
assert(memcmp(memoryAt, DEADBEEF, std::min(size, DEADBEEF_SIZE)) != 0);
}
// Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's
// http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde,
// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)
glm::vec3 safeEulerAngles(const glm::quat& q) {
float sy = 2.0f * (q.y * q.w - q.x * q.z);
if (sy < 1.0f - EPSILON) {
if (sy > -1.0f + EPSILON) {
return glm::degrees(glm::vec3(
atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)),
asinf(sy),
atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z))));
} else {
// not a unique solution; x + z = atan2(-m21, m11)
return glm::degrees(glm::vec3(
0.0f,
PIf * -0.5f,
atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z))));
}
} else {
// not a unique solution; x - z = atan2(-m21, m11)
return glm::degrees(glm::vec3(
0.0f,
PIf * 0.5f,
-atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z))));
}
}

View file

@ -176,4 +176,10 @@ int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* de
int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix);
int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix);
#ifndef PIf
#define PIf 3.14159265f
#endif
glm::vec3 safeEulerAngles(const glm::quat& q);
#endif /* defined(__hifi__SharedUtil__) */