spaces instead of tabs

This commit is contained in:
Jonathan Bosson
2017-07-13 13:09:25 -06:00
parent 78c301ec8d
commit c4e4e141af
13 changed files with 1359 additions and 1359 deletions

View File

@@ -1,4 +1,4 @@
/*
/*
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files(the "Software"), to deal in the Software without
@@ -30,12 +30,12 @@ OTHER DEALINGS IN THE SOFTWARE.
// set parameters required by levmarq() to default values
void levmarq_init(LMstat *lmstat) {
lmstat->verbose = false;
lmstat->max_it = 3000;
lmstat->init_lambda = 1e-6;
lmstat->up_factor = 10;
lmstat->down_factor = 10;
lmstat->target_derr = 1e-12;
lmstat->verbose = false;
lmstat->max_it = 3000;
lmstat->init_lambda = 1e-6;
lmstat->up_factor = 10;
lmstat->down_factor = 10;
lmstat->target_derr = 1e-12;
}
@@ -58,222 +58,222 @@ Before calling levmarq, several of the parameters in lmstat must be set.
For default values, call levmarq_init(lmstat).
*/
bool levmarq(int npar, double *par, int ny, double *dysq,
double (*func)(double *, int, void *, LMstat*),
void (*grad)(double *, double *, int, void *, LMstat*),
void *fdata, LMstat *lmstat) {
double (*func)(double *, int, void *, LMstat*),
void (*grad)(double *, double *, int, void *, LMstat*),
void *fdata, LMstat *lmstat) {
int x, i, j, it, nit, ill;
bool verbose;
std::string data = "";
double lambda, up, down, mult, weight, err, newerr, derr, target_derr;
int x, i, j, it, nit, ill;
bool verbose;
std::string data = "";
double lambda, up, down, mult, weight, err, newerr, derr, target_derr;
// allocate the arrays
double** h = new double*[npar];
double** ch = new double*[npar];
for (int i = 0; i < npar; i++) {
h[i] = new double[npar];
ch[i] = new double[npar];
}
double* g = new double[npar];
double* d = new double[npar];
double* delta = new double[npar];
double* newpar = new double[npar];
// allocate the arrays
double** h = new double*[npar];
double** ch = new double*[npar];
for (int i = 0; i < npar; i++) {
h[i] = new double[npar];
ch[i] = new double[npar];
}
double* g = new double[npar];
double* d = new double[npar];
double* delta = new double[npar];
double* newpar = new double[npar];
verbose = lmstat->verbose;
nit = lmstat->max_it;
lambda = lmstat->init_lambda;
up = lmstat->up_factor;
down = 1/lmstat->down_factor;
target_derr = lmstat->target_derr;
weight = 1;
derr = newerr = 0; // to avoid compiler warnings
verbose = lmstat->verbose;
nit = lmstat->max_it;
lambda = lmstat->init_lambda;
up = lmstat->up_factor;
down = 1/lmstat->down_factor;
target_derr = lmstat->target_derr;
weight = 1;
derr = newerr = 0; // to avoid compiler warnings
if (verbose) {
std::ostringstream qs, gs, ds, ps, oss;
for (i = 0; i < npar; ++i) {
qs << "q" << i;
gs << "g" << i;
ds << "d" << i;
if (i + 1 < npar) {
qs << ",";
gs << ",";
ds << ",";
}
}
for (i = 0; i < ny; ++i) {
for (j = 0; j < 2; ++j) {
std::string s = (j == 0) ? "x" : "y";
ps << "p" << i << s;
if (j + 1 < ny) {
ps << ",";
}
}
if (i + 1 < ny) {
ps << ",";
}
}
oss << "it,err,derr," << qs.str() << "," << gs.str() << "," << ds.str() << "," << ps.str() << "\n";
data = oss.str();
}
if (verbose) {
std::ostringstream qs, gs, ds, ps, oss;
for (i = 0; i < npar; ++i) {
qs << "q" << i;
gs << "g" << i;
ds << "d" << i;
if (i + 1 < npar) {
qs << ",";
gs << ",";
ds << ",";
}
}
for (i = 0; i < ny; ++i) {
for (j = 0; j < 2; ++j) {
std::string s = (j == 0) ? "x" : "y";
ps << "p" << i << s;
if (j + 1 < ny) {
ps << ",";
}
}
if (i + 1 < ny) {
ps << ",";
}
}
oss << "it,err,derr," << qs.str() << "," << gs.str() << "," << ds.str() << "," << ps.str() << "\n";
data = oss.str();
}
// calculate the initial error ("chi-squared")
lmstat->pos.clear();
err = error_func(par, ny, dysq, func, fdata, lmstat);
// calculate the initial error ("chi-squared")
lmstat->pos.clear();
err = error_func(par, ny, dysq, func, fdata, lmstat);
// main iteration
for (it = 0; it < nit; it++) {
// calculate the approximation to the Hessian and the "derivative" d
for (i = 0; i < npar; i++) {
d[i] = 0;
for (j = 0; j <= i; j++)
h[i][j] = 0;
}
for (x = 0; x < ny; x++) {
if (dysq)
weight = 1/dysq[x]; // for weighted least-squares
grad(g, par, x, fdata, lmstat);
for (i = 0; i < npar; i++) {
d[i] += (0.0 - func(par, x, fdata, lmstat)) * g[i] * weight; //(y[x] - func(par, x, fdata)) * g[i] * weight;
for (j = 0; j <= i; j++)
h[i][j] += g[i] * g[j] * weight;
}
}
// make a step "delta." If the step is rejected, increase lambda and try again
mult = 1 + lambda;
ill = 1; // ill-conditioned?
while (ill && (it < nit)) {
for (i = 0; i < npar; i++)
h[i][i] = h[i][i]*mult;
ill = cholesky_decomp(npar, ch, h);
if (!ill) {
solve_axb_cholesky(npar, ch, delta, d);
for (i = 0; i < npar; i++)
newpar[i] = par[i] + delta[i];
lmstat->pos.clear();
newerr = error_func(newpar, ny, dysq, func, fdata, lmstat);
derr = newerr - err;
ill = (derr > 0);
}
if (verbose) { // store iteration, error, gradient, step
/*printf("it = %4d, lambda = %10g, err = %10g, derr = %10g (%d)\n", it, lambda, err, derr, !(newerr > err));
for (int i = 0; i < npar; ++i) {
printf("g[%d] = %g, ", i, g[i]);
}
printf("\n");*/
// main iteration
for (it = 0; it < nit; it++) {
// calculate the approximation to the Hessian and the "derivative" d
for (i = 0; i < npar; i++) {
d[i] = 0;
for (j = 0; j <= i; j++)
h[i][j] = 0;
}
for (x = 0; x < ny; x++) {
if (dysq)
weight = 1/dysq[x]; // for weighted least-squares
grad(g, par, x, fdata, lmstat);
for (i = 0; i < npar; i++) {
d[i] += (0.0 - func(par, x, fdata, lmstat)) * g[i] * weight; //(y[x] - func(par, x, fdata)) * g[i] * weight;
for (j = 0; j <= i; j++)
h[i][j] += g[i] * g[j] * weight;
}
}
// make a step "delta." If the step is rejected, increase lambda and try again
mult = 1 + lambda;
ill = 1; // ill-conditioned?
while (ill && (it < nit)) {
for (i = 0; i < npar; i++)
h[i][i] = h[i][i]*mult;
ill = cholesky_decomp(npar, ch, h);
if (!ill) {
solve_axb_cholesky(npar, ch, delta, d);
for (i = 0; i < npar; i++)
newpar[i] = par[i] + delta[i];
lmstat->pos.clear();
newerr = error_func(newpar, ny, dysq, func, fdata, lmstat);
derr = newerr - err;
ill = (derr > 0);
}
if (verbose) { // store iteration, error, gradient, step
/*printf("it = %4d, lambda = %10g, err = %10g, derr = %10g (%d)\n", it, lambda, err, derr, !(newerr > err));
for (int i = 0; i < npar; ++i) {
printf("g[%d] = %g, ", i, g[i]);
}
printf("\n");*/
std::ostringstream gString, qString, dString, pString, os;
for (i = 0; i < npar; ++i) {
gString << g[i];
qString << par[i];
dString << d[i];
if (i + 1 < npar) {
gString << ",";
qString << ",";
dString << ",";
}
}
for (i = 0; i < ny; ++i) {
pString << lmstat->pos.at(i).x << "," << lmstat->pos.at(i).y;
if (i + 1 < ny) {
pString << ",";
}
}
os << it << "," << err << "," << derr << "," << qString.str() << "," << gString.str() << "," << dString.str() << "," << pString.str() << "\n";
data.append(os.str());
}
if (ill) {
mult = (1 + lambda * up) / (1 + lambda);
lambda *= up;
it++;
}
}
for (i = 0; i < npar; i++)
par[i] = newpar[i];
err = newerr;
lambda *= down;
std::ostringstream gString, qString, dString, pString, os;
for (i = 0; i < npar; ++i) {
gString << g[i];
qString << par[i];
dString << d[i];
if (i + 1 < npar) {
gString << ",";
qString << ",";
dString << ",";
}
}
for (i = 0; i < ny; ++i) {
pString << lmstat->pos.at(i).x << "," << lmstat->pos.at(i).y;
if (i + 1 < ny) {
pString << ",";
}
}
os << it << "," << err << "," << derr << "," << qString.str() << "," << gString.str() << "," << dString.str() << "," << pString.str() << "\n";
data.append(os.str());
}
if (ill) {
mult = (1 + lambda * up) / (1 + lambda);
lambda *= up;
it++;
}
}
for (i = 0; i < npar; i++)
par[i] = newpar[i];
err = newerr;
lambda *= down;
if ((!ill) && (-derr < target_derr))
break;
}
if ((!ill) && (-derr < target_derr))
break;
}
lmstat->final_it = it;
lmstat->final_err = err;
lmstat->final_derr = derr;
lmstat->data = data;
lmstat->final_it = it;
lmstat->final_err = err;
lmstat->final_derr = derr;
lmstat->data = data;
// deallocate the arrays
for (i = 0; i < npar; i++) {
delete[] h[i];
delete[] ch[i];
}
delete[] h;
delete[] ch;
delete[] g;
delete[] d;
delete[] delta;
delete[] newpar;
// deallocate the arrays
for (i = 0; i < npar; i++) {
delete[] h[i];
delete[] ch[i];
}
delete[] h;
delete[] ch;
delete[] g;
delete[] d;
delete[] delta;
delete[] newpar;
return (it != lmstat->max_it);
return (it != lmstat->max_it);
}
// calculate the error function (chi-squared)
double error_func(double *par, int ny, double *dysq,
double (*func)(double *, int, void *, LMstat*), void *fdata, LMstat *lmstat) {
int x;
double res, e = 0;
double (*func)(double *, int, void *, LMstat*), void *fdata, LMstat *lmstat) {
int x;
double res, e = 0;
for (x = 0; x < ny; x++) {
res = func(par, x, fdata, lmstat);
if (dysq) // weighted least-squares
e += res*res/dysq[x];
else
e += res*res;
}
return e;
for (x = 0; x < ny; x++) {
res = func(par, x, fdata, lmstat);
if (dysq) // weighted least-squares
e += res*res/dysq[x];
else
e += res*res;
}
return e;
}
// solve Ax=b for a symmetric positive-definite matrix A using the Cholesky decomposition A=LL^T, L is passed in "l", elements above the diagonal are ignored.
void solve_axb_cholesky(int n, double** l, double* x, double* b) { // n = npar, l = ch, x = delta (solution), b = d (func(par, x, fdata) * g[i]);
int i, j;
double sum;
// solve L*y = b for y (where x[] is used to store y)
for (i = 0; i < n; i++) {
sum = 0;
for (j = 0; j < i; j++)
sum += l[i][j] * x[j];
x[i] = (b[i] - sum) / l[i][i];
}
// solve L^T*x = y for x (where x[] is used to store both y and x)
for (i = n-1; i >= 0; i--) {
sum = 0;
for (j = i+1; j < n; j++)
sum += l[j][i] * x[j];
x[i] = (x[i] - sum) / l[i][i];
}
int i, j;
double sum;
// solve L*y = b for y (where x[] is used to store y)
for (i = 0; i < n; i++) {
sum = 0;
for (j = 0; j < i; j++)
sum += l[i][j] * x[j];
x[i] = (b[i] - sum) / l[i][i];
}
// solve L^T*x = y for x (where x[] is used to store both y and x)
for (i = n-1; i >= 0; i--) {
sum = 0;
for (j = i+1; j < n; j++)
sum += l[j][i] * x[j];
x[i] = (x[i] - sum) / l[i][i];
}
}
// symmetric, positive-definite matrix "a" and returns its (lower-triangular) Cholesky factor in "l", if l=a the decomposition is performed in place, elements above the diagonal are ignored.
int cholesky_decomp(int n, double** l, double** a) {
int i, j, k;
double sum;
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++) {
sum = 0;
for (k = 0; k < j; k++)
sum += l[i][k] * l[j][k];
l[i][j] = (a[i][j] - sum) / l[j][j];
}
sum = 0;
for (k = 0; k < i; k++)
sum += l[i][k] * l[i][k];
sum = a[i][i] - sum;
if (sum < TOL)
return 1; // not positive-definite
l[i][i] = sqrt(sum);
}
return 0;
int i, j, k;
double sum;
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++) {
sum = 0;
for (k = 0; k < j; k++)
sum += l[i][k] * l[j][k];
l[i][j] = (a[i][j] - sum) / l[j][j];
}
sum = 0;
for (k = 0; k < i; k++)
sum += l[i][k] * l[i][k];
sum = a[i][i] - sum;
if (sum < TOL)
return 1; // not positive-definite
l[i][i] = sqrt(sum);
}
return 0;
}

View File

@@ -1,4 +1,4 @@
/*
/*
levmarq.c and levmarq.h are provided under the MIT license.
Copyright(c) 2008 - 2016 Ron Babich
@@ -29,17 +29,17 @@ OTHER DEALINGS IN THE SOFTWARE.
#include <glm/glm.hpp>
typedef struct {
bool verbose;
std::string data;
std::vector<glm::dvec2> pos;
int max_it;
double init_lambda;
double up_factor;
double down_factor;
double target_derr;
int final_it;
double final_err;
double final_derr;
bool verbose;
std::string data;
std::vector<glm::dvec2> pos;
int max_it;
double init_lambda;
double up_factor;
double down_factor;
double target_derr;
int final_it;
double final_err;
double final_derr;
} LMstat;
/**
@@ -51,15 +51,15 @@ void levmarq_init(LMstat *lmstat);
* Main function call, finds appropriate values for par[nDOF] that manipulates the camera correctly to direct-manipulation
*/
bool levmarq(int npar, double *par, int ny, double *dysq,
double (*func)(double *, int, void *, LMstat*),
void (*grad)(double *, double *, int, void *, LMstat*),
void *fdata, LMstat *lmstat);
double (*func)(double *, int, void *, LMstat*),
void (*grad)(double *, double *, int, void *, LMstat*),
void *fdata, LMstat *lmstat);
/**
* Returns the total L2 error (to be minimized) with each contact point's distance from the projected coordinates depending on par[nDOF].
*/
double error_func(double *par, int ny, double *dysq,
double (*func)(double *, int, void *, LMstat*), void *fdata, LMstat* lmstat);
double (*func)(double *, int, void *, LMstat*), void *fdata, LMstat* lmstat);
void solve_axb_cholesky(int n, double** l, double* x, double* b);

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -48,151 +48,151 @@ namespace openspace {
class TouchInteraction : public properties::PropertyOwner
{
using Point = std::pair<int, TUIO::TuioPoint>;
using Point = std::pair<int, TUIO::TuioPoint>;
public:
TouchInteraction();
public:
TouchInteraction();
// for interpretInteraction()
enum Type { ROT = 0, PINCH, PAN, ROLL, PICK };
// for interpretInteraction()
enum Type { ROT = 0, PINCH, PAN, ROLL, PICK };
// Stores the velocity in all 6DOF
struct VelocityStates {
glm::dvec2 orbit;
double zoom;
double roll;
glm::dvec2 pan;
};
// Stores the selected node, the cursor ID as well as the surface coordinates the cursor touched
struct SelectedBody {
int id;
SceneGraphNode* node;
glm::dvec3 coordinates;
};
// Used in the LM algorithm
struct FunctionData {
std::vector<glm::dvec3> selectedPoints;
std::vector<glm::dvec2> screenPoints;
int nDOF;
glm::dvec2(*castToNDC)(glm::dvec3, Camera&, SceneGraphNode*);
double(*distToMinimize)(double* par, int x, void* fdata, LMstat* lmstat);
Camera* camera;
SceneGraphNode* node;
LMstat stats;
double objectScreenRadius;
};
// Stores the velocity in all 6DOF
struct VelocityStates {
glm::dvec2 orbit;
double zoom;
double roll;
glm::dvec2 pan;
};
// Stores the selected node, the cursor ID as well as the surface coordinates the cursor touched
struct SelectedBody {
int id;
SceneGraphNode* node;
glm::dvec3 coordinates;
};
// Used in the LM algorithm
struct FunctionData {
std::vector<glm::dvec3> selectedPoints;
std::vector<glm::dvec2> screenPoints;
int nDOF;
glm::dvec2(*castToNDC)(glm::dvec3, Camera&, SceneGraphNode*);
double(*distToMinimize)(double* par, int x, void* fdata, LMstat* lmstat);
Camera* camera;
SceneGraphNode* node;
LMstat stats;
double objectScreenRadius;
};
/* Main function call
* 1, Checks if doubleTap occured
* 2, Goes through the guiMode() function
* 3, Continues if GUI isn't on
* 4, If the node in focus is large enough and all contact points have selected it,
* calls directControl() function for direct-manipulation
* 5, Updates std::vector<SelectedBody> _selected (only if LMA successfully
* converged, avoids interaction to snap on LMA fails)
* 6, If directControl() wasn't called this frame, interpret the incoming
* list and decide what type of interaction this frame should do
* 7, Compute the new total velocities after interaction
* 8, Evaluate if directControl should be called next frame - true if all contact points
* select the same node and said node is larger than _nodeRadiusThreshold
*/
void updateStateFromInput(const std::vector<TUIO::TuioCursor>& list, std::vector<Point>& lastProcessed);
/* Main function call
* 1, Checks if doubleTap occured
* 2, Goes through the guiMode() function
* 3, Continues if GUI isn't on
* 4, If the node in focus is large enough and all contact points have selected it,
* calls directControl() function for direct-manipulation
* 5, Updates std::vector<SelectedBody> _selected (only if LMA successfully
* converged, avoids interaction to snap on LMA fails)
* 6, If directControl() wasn't called this frame, interpret the incoming
* list and decide what type of interaction this frame should do
* 7, Compute the new total velocities after interaction
* 8, Evaluate if directControl should be called next frame - true if all contact points
* select the same node and said node is larger than _nodeRadiusThreshold
*/
void updateStateFromInput(const std::vector<TUIO::TuioCursor>& list, std::vector<Point>& lastProcessed);
/* Calculates the new camera state with velocities and time since last frame */
void step(double dt);
/* Calculates the new camera state with velocities and time since last frame */
void step(double dt);
/* Used to save LMA data for one frame if the user chose to */
void unitTest();
/* Used to save LMA data for one frame if the user chose to */
void unitTest();
/* Called each frame we have no new input, used to reset data */
void resetAfterInput();
/* Called each frame we have no new input, used to reset data */
void resetAfterInput();
/* Sets _tap to true, called if tap occured current frame (called from touchmodule) */
void tap();
/* Set touchactive as true from the touchmodule if incoming list isn't empty, used to void mouse input */
void touchActive(bool active);
/* Sets _tap to true, called if tap occured current frame (called from touchmodule) */
void tap();
/* Set touchactive as true from the touchmodule if incoming list isn't empty, used to void mouse input */
void touchActive(bool active);
// Get & Setters
Camera* getCamera();
SceneGraphNode* getFocusNode();
void setFocusNode(SceneGraphNode* focusNode);
void setCamera(Camera* cam);
// Get & Setters
Camera* getCamera();
SceneGraphNode* getFocusNode();
void setFocusNode(SceneGraphNode* focusNode);
void setCamera(Camera* cam);
private:
private:
/* Returns true if we have the GUI window open
If so, emulates the incoming touch input to a mouse such that we can interact with the GUI
*/
bool guiMode(const std::vector<TUIO::TuioCursor>& list);
/* Returns true if we have the GUI window open
If so, emulates the incoming touch input to a mouse such that we can interact with the GUI
*/
bool guiMode(const std::vector<TUIO::TuioCursor>& list);
/* Function that calculates the new camera state such that it minimizes the L2 error in screenspace
* between contact points and surface coordinates projected to clip space using LMA
*/
void directControl(const std::vector<TUIO::TuioCursor>& list);
/* Function that calculates the new camera state such that it minimizes the L2 error in screenspace
* between contact points and surface coordinates projected to clip space using LMA
*/
void directControl(const std::vector<TUIO::TuioCursor>& list);
/* Traces each contact point into the scene as a ray
* if the ray hits a node, save the id, node and surface coordinates the cursor hit in the list _selected
*/
void findSelectedNode(const std::vector<TUIO::TuioCursor>& list);
/* Traces each contact point into the scene as a ray
* if the ray hits a node, save the id, node and surface coordinates the cursor hit in the list _selected
*/
void findSelectedNode(const std::vector<TUIO::TuioCursor>& list);
/* Returns an int (ROT = 0, PINCH, PAN, ROLL, PICK) for what interaction to be used,
depending on what input was gotten */
int interpretInteraction(const std::vector<TUIO::TuioCursor>& list, const std::vector<Point>& lastProcessed);
/* Returns an int (ROT = 0, PINCH, PAN, ROLL, PICK) for what interaction to be used,
depending on what input was gotten */
int interpretInteraction(const std::vector<TUIO::TuioCursor>& list, const std::vector<Point>& lastProcessed);
/* Compute new velocity according to the interpreted action */
void computeVelocities(const std::vector<TUIO::TuioCursor>& list, const std::vector<Point>& lastProcessed);
/* Compute new velocity according to the interpreted action */
void computeVelocities(const std::vector<TUIO::TuioCursor>& list, const std::vector<Point>& lastProcessed);
/* Decelerate the velocities,
* function is called in step() but is dereferenced from frame time to assure same behaviour on all systems
*/
void decelerate(double dt);
/* Decelerate the velocities,
* function is called in step() but is dereferenced from frame time to assure same behaviour on all systems
*/
void decelerate(double dt);
/* Resets all properties that can be changed in the GUI to default */
void resetToDefault();
/* Resets all properties that can be changed in the GUI to default */
void resetToDefault();
Camera* _camera;
SceneGraphNode* _focusNode = nullptr;
Camera* _camera;
SceneGraphNode* _focusNode = nullptr;
// Property variables
properties::StringProperty _origin;
properties::BoolProperty _unitTest;
properties::BoolProperty _touchActive;
properties::BoolProperty _reset;
properties::IntProperty _maxTapTime;
properties::IntProperty _deceleratesPerSecond;
properties::FloatProperty _touchScreenSize;
properties::FloatProperty _tapZoomFactor;
properties::FloatProperty _nodeRadiusThreshold;
properties::FloatProperty _rollAngleThreshold;
properties::FloatProperty _orbitSpeedThreshold;
properties::FloatProperty _spinSensitivity;
properties::FloatProperty _inputStillThreshold;
properties::FloatProperty _centroidStillThreshold;
properties::FloatProperty _interpretPan;
properties::FloatProperty _slerpTime;
properties::IVec2Property _guiButton;
properties::Vec4Property _friction;
// Property variables
properties::StringProperty _origin;
properties::BoolProperty _unitTest;
properties::BoolProperty _touchActive;
properties::BoolProperty _reset;
properties::IntProperty _maxTapTime;
properties::IntProperty _deceleratesPerSecond;
properties::FloatProperty _touchScreenSize;
properties::FloatProperty _tapZoomFactor;
properties::FloatProperty _nodeRadiusThreshold;
properties::FloatProperty _rollAngleThreshold;
properties::FloatProperty _orbitSpeedThreshold;
properties::FloatProperty _spinSensitivity;
properties::FloatProperty _inputStillThreshold;
properties::FloatProperty _centroidStillThreshold;
properties::FloatProperty _interpretPan;
properties::FloatProperty _slerpTime;
properties::IVec2Property _guiButton;
properties::Vec4Property _friction;
// Class variables
VelocityStates _vel;
VelocityStates _lastVel;
VelocityStates _sensitivity;
// Class variables
VelocityStates _vel;
VelocityStates _lastVel;
VelocityStates _sensitivity;
double _projectionScaleFactor;
double _currentRadius;
double _slerpdT;
double _timeSlack;
int _numOfTests;
TUIO::TuioTime _time;
bool _directTouchMode;
bool _tap;
bool _doubleTap;
bool _lmSuccess;
bool _guiON;
std::vector<SelectedBody> _selected;
LMstat _lmstat;
glm::dquat _toSlerp;
glm::dvec3 _centroid;
double _projectionScaleFactor;
double _currentRadius;
double _slerpdT;
double _timeSlack;
int _numOfTests;
TUIO::TuioTime _time;
bool _directTouchMode;
bool _tap;
bool _doubleTap;
bool _lmSuccess;
bool _guiON;
std::vector<SelectedBody> _selected;
LMstat _lmstat;
glm::dquat _toSlerp;
glm::dvec3 _centroid;
};

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -43,7 +43,7 @@
namespace ghoul {
namespace opengl {
class ProgramObject;
class ProgramObject;
} // namespace opengl
} // namespace ghoul
@@ -52,29 +52,29 @@ namespace openspace {
class TouchMarker : public properties::PropertyOwner
{
public:
TouchMarker();
public:
TouchMarker();
bool initialize();
bool deinitialize();
bool initialize();
bool deinitialize();
void render(const std::vector<TUIO::TuioCursor> list);
void render(const std::vector<TUIO::TuioCursor> list);
private:
void createVertexList(const std::vector<TUIO::TuioCursor> list);
private:
void createVertexList(const std::vector<TUIO::TuioCursor> list);
properties::BoolProperty _visible;
properties::FloatProperty _radiusSize;
properties::FloatProperty _transparency;
properties::FloatProperty _thickness;
properties::Vec3Property _color;
properties::BoolProperty _visible;
properties::FloatProperty _radiusSize;
properties::FloatProperty _transparency;
properties::FloatProperty _thickness;
properties::Vec3Property _color;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
GLuint _quad;
GLuint _vertexPositionBuffer;
int _numFingers;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
GLuint _quad;
GLuint _vertexPositionBuffer;
int _numFingers;
};
} // openspace namespace

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -40,68 +40,68 @@
class TuioEar : public TUIO::TuioListener {
public:
TuioEar();
~TuioEar() {
_tuioClient->disconnect();
delete _tuioClient;
delete _oscReceiver;
}
/**
* Callback functions, listens to the TUIO server
*/
void addTuioObject(TUIO::TuioObject *tobj);
void updateTuioObject(TUIO::TuioObject *tobj);
void removeTuioObject(TUIO::TuioObject *tobj);
public:
TuioEar();
~TuioEar() {
_tuioClient->disconnect();
delete _tuioClient;
delete _oscReceiver;
}
/**
* Callback functions, listens to the TUIO server
*/
void addTuioObject(TUIO::TuioObject *tobj);
void updateTuioObject(TUIO::TuioObject *tobj);
void removeTuioObject(TUIO::TuioObject *tobj);
void addTuioCursor(TUIO::TuioCursor *tcur);
void updateTuioCursor(TUIO::TuioCursor *tcur);
void removeTuioCursor(TUIO::TuioCursor *tcur);
void addTuioCursor(TUIO::TuioCursor *tcur);
void updateTuioCursor(TUIO::TuioCursor *tcur);
void removeTuioCursor(TUIO::TuioCursor *tcur);
void addTuioBlob(TUIO::TuioBlob *tblb);
void updateTuioBlob(TUIO::TuioBlob *tblb);
void removeTuioBlob(TUIO::TuioBlob *tblb);
void addTuioBlob(TUIO::TuioBlob *tblb);
void updateTuioBlob(TUIO::TuioBlob *tblb);
void removeTuioBlob(TUIO::TuioBlob *tblb);
void refresh(TUIO::TuioTime frameTime);
void refresh(TUIO::TuioTime frameTime);
/**
* Returns a list of all touch history that happened since the last frame
*/
std::vector<TUIO::TuioCursor> getInput();
/**
* Returns a list of all touch history that happened since the last frame
*/
std::vector<TUIO::TuioCursor> getInput();
/**
* Returns true if a tap occured since the last frame
*/
bool tap();
/**
* Returns true if a tap occured since the last frame
*/
bool tap();
/**
* Returns tap's cursor coordinates and time information
*/
TUIO::TuioCursor getTap();
/**
* Returns tap's cursor coordinates and time information
*/
TUIO::TuioCursor getTap();
/**
* Clears the input list, function called after getInput() each frame
*/
void clearInput();
private:
bool _tap;
TUIO::TuioCursor _tapCo = TUIO::TuioCursor(-1, -1, -1.0f, -1.0f);
std::mutex _mx;
/**
* Clears the input list, function called after getInput() each frame
*/
void clearInput();
private:
bool _tap;
TUIO::TuioCursor _tapCo = TUIO::TuioCursor(-1, -1, -1.0f, -1.0f);
std::mutex _mx;
TUIO::TuioClient *_tuioClient;
TUIO::OscReceiver *_oscReceiver;
TUIO::TuioClient *_tuioClient;
TUIO::OscReceiver *_oscReceiver;
std::vector<TUIO::TuioCursor> _list;
std::vector<TUIO::TuioCursor> _list;
/**
* A list that tracks all of the cursor ID's that got removed since last frame
*/
std::vector<int> _removeList;
/**
* A list that tracks all of the cursor ID's that got removed since last frame
*/
std::vector<int> _removeList;
};
#endif // __OPENSPACE_MODULE_TOUCH___TOUCHWRAPPER___H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -32,111 +32,111 @@
#include <ghoul/logging/logmanager.h>
namespace {
const std::string _loggerCat = "TouchMarker";
const int MAX_FINGERS = 20;
const std::string _loggerCat = "TouchMarker";
const int MAX_FINGERS = 20;
}
namespace openspace {
TouchMarker::TouchMarker()
: properties::PropertyOwner("TouchMarker")
, _visible("TouchMarkers visible", "Toggle visibility of markers", true)
, _radiusSize("Marker size", "Marker radius", 30, 0, 100)
, _transparency("Transparency of marker", "Marker transparency", 0.8, 0, 1.0)
, _thickness("Thickness of marker", "Marker thickness", 2.0, 0, 4.0)
, _color(
"MarkerColor",
"Marker color",
glm::vec3(204.f / 255.f, 51.f / 255.f, 51.f / 255.f),
glm::vec3(0.f),
glm::vec3(1.f)
)
, _shader(nullptr)
, _numFingers(0)
: properties::PropertyOwner("TouchMarker")
, _visible("TouchMarkers visible", "Toggle visibility of markers", true)
, _radiusSize("Marker size", "Marker radius", 30, 0, 100)
, _transparency("Transparency of marker", "Marker transparency", 0.8, 0, 1.0)
, _thickness("Thickness of marker", "Marker thickness", 2.0, 0, 4.0)
, _color(
"MarkerColor",
"Marker color",
glm::vec3(204.f / 255.f, 51.f / 255.f, 51.f / 255.f),
glm::vec3(0.f),
glm::vec3(1.f)
)
, _shader(nullptr)
, _numFingers(0)
{
addProperty(_visible);
addProperty(_radiusSize);
addProperty(_transparency);
addProperty(_thickness);
_color.setViewOption(properties::Property::ViewOptions::Color);
addProperty(_color);
addProperty(_visible);
addProperty(_radiusSize);
addProperty(_transparency);
addProperty(_thickness);
_color.setViewOption(properties::Property::ViewOptions::Color);
addProperty(_color);
}
bool TouchMarker::initialize() {
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
try {
_shader = OsEng.renderEngine().buildRenderProgram("MarkerProgram",
"${MODULE_TOUCH}/shaders/marker_vs.glsl",
"${MODULE_TOUCH}/shaders/marker_fs.glsl"
);
}
catch (const ghoul::opengl::ShaderObject::ShaderCompileError& e) {
LERRORC(e.component, e.what());
}
return (_shader != nullptr);
try {
_shader = OsEng.renderEngine().buildRenderProgram("MarkerProgram",
"${MODULE_TOUCH}/shaders/marker_vs.glsl",
"${MODULE_TOUCH}/shaders/marker_fs.glsl"
);
}
catch (const ghoul::opengl::ShaderObject::ShaderCompileError& e) {
LERRORC(e.component, e.what());
}
return (_shader != nullptr);
}
bool TouchMarker::deinitialize() {
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
RenderEngine& renderEngine = OsEng.renderEngine();
if (_shader) {
renderEngine.removeRenderProgram(_shader);
_shader = nullptr;
}
return true;
RenderEngine& renderEngine = OsEng.renderEngine();
if (_shader) {
renderEngine.removeRenderProgram(_shader);
_shader = nullptr;
}
return true;
}
void TouchMarker::render(const std::vector<TUIO::TuioCursor> list) {
if (_visible && !list.empty()) {
createVertexList(list);
_shader->activate();
if (_visible && !list.empty()) {
createVertexList(list);
_shader->activate();
_shader->setUniform("radius", _radiusSize);
_shader->setUniform("transparency", _transparency);
_shader->setUniform("thickness", _thickness);
_shader->setUniform("color", _color.value());
_shader->setUniform("radius", _radiusSize);
_shader->setUniform("transparency", _transparency);
_shader->setUniform("thickness", _thickness);
_shader->setUniform("color", _color.value());
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_PROGRAM_POINT_SIZE); // Enable gl_PointSize in vertex shader
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
glBindVertexArray(_quad);
glDrawArrays(GL_POINTS, 0, _numFingers);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_PROGRAM_POINT_SIZE); // Enable gl_PointSize in vertex shader
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
glBindVertexArray(_quad);
glDrawArrays(GL_POINTS, 0, _numFingers);
_shader->deactivate();
}
_shader->deactivate();
}
}
void TouchMarker::createVertexList(const std::vector<TUIO::TuioCursor> list) {
_numFingers = list.size();
GLfloat vertexData[MAX_FINGERS];
int i = 0;
for (const TUIO::TuioCursor& c : list) {
vertexData[i] = 2 * (c.getX() - 0.5);
vertexData[i + 1] = -2 * (c.getY() - 0.5);
i += 2;
}
_numFingers = list.size();
GLfloat vertexData[MAX_FINGERS];
int i = 0;
for (const TUIO::TuioCursor& c : list) {
vertexData[i] = 2 * (c.getX() - 0.5);
vertexData[i + 1] = -2 * (c.getY() - 0.5);
i += 2;
}
glBindVertexArray(_quad);
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
0,
0
);
glBindVertexArray(_quad);
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
0,
0
);
}
} // openspace namespace

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -35,7 +35,7 @@
using namespace TUIO;
namespace {
const std::string _loggerCat = "TuioEar";
const std::string _loggerCat = "TuioEar";
}
void TuioEar::addTuioObject(TuioObject *tobj) { }
@@ -45,61 +45,61 @@ void TuioEar::updateTuioObject(TuioObject *tobj) { }
void TuioEar::removeTuioObject(TuioObject *tobj) { }
void TuioEar::addTuioCursor(TuioCursor *tcur) {
_mx.lock();
_tap = false;
// find same id in _list if it exists in _removeList (new input with same ID as a previously stored)
int i = tcur->getSessionID();
std::vector<int>::iterator foundID = std::find_if(
_removeList.begin(),
_removeList.end(),
[&i](int id) { return id == i; });
_mx.lock();
_tap = false;
// find same id in _list if it exists in _removeList (new input with same ID as a previously stored)
int i = tcur->getSessionID();
std::vector<int>::iterator foundID = std::find_if(
_removeList.begin(),
_removeList.end(),
[&i](int id) { return id == i; });
// if found, remove id from _removeList and update, otherwise add new id to list
if (foundID != _removeList.end()) {
std::find_if(
_list.begin(),
_list.end(),
[&i](const TuioCursor& cursor) {
return cursor.getSessionID() == i;
})->update(tcur);
_removeList.erase(foundID);
}
else {
_list.push_back(TuioCursor(*tcur));
}
_mx.unlock();
// if found, remove id from _removeList and update, otherwise add new id to list
if (foundID != _removeList.end()) {
std::find_if(
_list.begin(),
_list.end(),
[&i](const TuioCursor& cursor) {
return cursor.getSessionID() == i;
})->update(tcur);
_removeList.erase(foundID);
}
else {
_list.push_back(TuioCursor(*tcur));
}
_mx.unlock();
}
void TuioEar::updateTuioCursor(TuioCursor *tcur) {
_mx.lock();
_tap = false;
int i = tcur->getSessionID();
std::find_if(
_list.begin(),
_list.end(),
[&i](const TuioCursor& cursor) {
return cursor.getSessionID() == i;
})->update(tcur);
_mx.unlock();
_mx.lock();
_tap = false;
int i = tcur->getSessionID();
std::find_if(
_list.begin(),
_list.end(),
[&i](const TuioCursor& cursor) {
return cursor.getSessionID() == i;
})->update(tcur);
_mx.unlock();
}
// save id to be removed and remove it in clearInput
void TuioEar::removeTuioCursor(TuioCursor *tcur) {
_mx.lock();
_removeList.push_back(tcur->getSessionID());
_mx.lock();
_removeList.push_back(tcur->getSessionID());
// Check if the cursor ID could be considered a tap
double dist = 0;
for (const TuioPoint& p : tcur->getPath()) {
dist += glm::length(glm::dvec2(p.getX(), p.getY()) - glm::dvec2(tcur->getX(), tcur->getY()));
}
dist /= tcur->getPath().size();
double heldTime = tcur->getPath().back().getTuioTime().getTotalMilliseconds() - tcur->getPath().front().getTuioTime().getTotalMilliseconds();
if (heldTime < 180 && dist < 0.0004 && _list.size() == 1 && _removeList.size() == 1) {
_tapCo = TuioCursor(*tcur);
_tap = true;
}
_mx.unlock();
// Check if the cursor ID could be considered a tap
double dist = 0;
for (const TuioPoint& p : tcur->getPath()) {
dist += glm::length(glm::dvec2(p.getX(), p.getY()) - glm::dvec2(tcur->getX(), tcur->getY()));
}
dist /= tcur->getPath().size();
double heldTime = tcur->getPath().back().getTuioTime().getTotalMilliseconds() - tcur->getPath().front().getTuioTime().getTotalMilliseconds();
if (heldTime < 180 && dist < 0.0004 && _list.size() == 1 && _removeList.size() == 1) {
_tapCo = TuioCursor(*tcur);
_tap = true;
}
_mx.unlock();
}
void TuioEar::addTuioBlob(TuioBlob *tblb) { }
@@ -111,52 +111,52 @@ void TuioEar::removeTuioBlob(TuioBlob *tblb) { }
void TuioEar::refresh(TuioTime frameTime) { } // about every 15ms
std::vector<TuioCursor> TuioEar::getInput() {
std::lock_guard<std::mutex> lock(_mx);
return _list;
std::lock_guard<std::mutex> lock(_mx);
return _list;
}
bool TuioEar::tap() {
std::lock_guard<std::mutex> lock(_mx);
if (_tap) {
_tap = false;
return !_tap;
}
else {
return _tap;
}
std::lock_guard<std::mutex> lock(_mx);
if (_tap) {
_tap = false;
return !_tap;
}
else {
return _tap;
}
}
TuioCursor TuioEar::getTap() {
std::lock_guard<std::mutex> lock(_mx);
return _tapCo;
std::lock_guard<std::mutex> lock(_mx);
return _tapCo;
}
// Removes all cursor ID from list that exists in _removeList
void TuioEar::clearInput() {
_mx.lock();
_list.erase(
std::remove_if(
_list.begin(),
_list.end(),
[this](const TuioCursor& cursor) {
return std::find_if(
_removeList.begin(),
_removeList.end(),
[&cursor](int id) {
return cursor.getSessionID() == id;
}
) != _removeList.end();
}),
_list.end()
);
_removeList.clear();
_mx.unlock();
_mx.lock();
_list.erase(
std::remove_if(
_list.begin(),
_list.end(),
[this](const TuioCursor& cursor) {
return std::find_if(
_removeList.begin(),
_removeList.end(),
[&cursor](int id) {
return cursor.getSessionID() == id;
}
) != _removeList.end();
}),
_list.end()
);
_removeList.clear();
_mx.unlock();
}
// Standard UDP IP connection to port 3333
TuioEar::TuioEar() {
_oscReceiver = new UdpReceiver(3333);
_tuioClient = new TuioClient(_oscReceiver);
_tuioClient->addTuioListener(this);
_tuioClient->connect();
_oscReceiver = new UdpReceiver(3333);
_tuioClient = new TuioClient(_oscReceiver);
_tuioClient->addTuioListener(this);
_tuioClient->connect();
}

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -41,114 +41,114 @@
using namespace TUIO;
namespace {
const std::string _loggerCat = "TouchModule";
const std::string _loggerCat = "TouchModule";
}
namespace openspace {
bool TouchModule::hasNewInput() {
// Get new input from listener
listOfContactPoints = ear.getInput();
ear.clearInput();
touch.touchActive(!listOfContactPoints.empty()); // Set touch property to active (to void mouse input, mainly for mtdev bridges)
// Get new input from listener
listOfContactPoints = ear.getInput();
ear.clearInput();
touch.touchActive(!listOfContactPoints.empty()); // Set touch property to active (to void mouse input, mainly for mtdev bridges)
// Erase old input id's that no longer exists
lastProcessed.erase(
std::remove_if(
lastProcessed.begin(),
lastProcessed.end(),
[this](const Point& point) {
return std::find_if(
listOfContactPoints.begin(),
listOfContactPoints.end(),
[&point](const TuioCursor& c) {
return point.first == c.getSessionID();
}
) == listOfContactPoints.end(); }),
lastProcessed.end());
// Erase old input id's that no longer exists
lastProcessed.erase(
std::remove_if(
lastProcessed.begin(),
lastProcessed.end(),
[this](const Point& point) {
return std::find_if(
listOfContactPoints.begin(),
listOfContactPoints.end(),
[&point](const TuioCursor& c) {
return point.first == c.getSessionID();
}
) == listOfContactPoints.end(); }),
lastProcessed.end());
// if tap occured, we have new input
if (listOfContactPoints.empty() && lastProcessed.empty() && ear.tap()) {
TuioCursor c = ear.getTap();
listOfContactPoints.push_back(c);
// if tap occured, we have new input
if (listOfContactPoints.empty() && lastProcessed.empty() && ear.tap()) {
TuioCursor c = ear.getTap();
listOfContactPoints.push_back(c);
lastProcessed.emplace_back(c.getSessionID(), c.getPath().back());
touch.tap();
return true;
}
// Return true if we got new input
if (listOfContactPoints.size() == lastProcessed.size() && !listOfContactPoints.empty()) {
bool newInput = true;
// go through list and check if the last registrered time is newer than the one in lastProcessed (last frame)
std::for_each(lastProcessed.begin(), lastProcessed.end(), [this, &newInput](Point& p) {
std::vector<TuioCursor>::iterator cursor = std::find_if(listOfContactPoints.begin(), listOfContactPoints.end(),
[&p](const TuioCursor& c) { return c.getSessionID() == p.first; });
double now = cursor->getPath().back().getTuioTime().getTotalMilliseconds();
if (!cursor->isMoving()) { // if current cursor isn't moving, we want to interpret that as new input for interaction purposes
newInput = true;
}
else if (p.second.getTuioTime().getTotalMilliseconds() == now) {
newInput = false;
}
});
return newInput;
}
else {
return false;
}
touch.tap();
return true;
}
// Return true if we got new input
if (listOfContactPoints.size() == lastProcessed.size() && !listOfContactPoints.empty()) {
bool newInput = true;
// go through list and check if the last registrered time is newer than the one in lastProcessed (last frame)
std::for_each(lastProcessed.begin(), lastProcessed.end(), [this, &newInput](Point& p) {
std::vector<TuioCursor>::iterator cursor = std::find_if(listOfContactPoints.begin(), listOfContactPoints.end(),
[&p](const TuioCursor& c) { return c.getSessionID() == p.first; });
double now = cursor->getPath().back().getTuioTime().getTotalMilliseconds();
if (!cursor->isMoving()) { // if current cursor isn't moving, we want to interpret that as new input for interaction purposes
newInput = true;
}
else if (p.second.getTuioTime().getTotalMilliseconds() == now) {
newInput = false;
}
});
return newInput;
}
else {
return false;
}
}
TouchModule::TouchModule()
: OpenSpaceModule("Touch")
: OpenSpaceModule("Touch")
{
addPropertySubOwner(touch);
addPropertySubOwner(markers);
addPropertySubOwner(touch);
addPropertySubOwner(markers);
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::InitializeGL,
[&]() {
LDEBUGC("TouchModule", "Initializing TouchMarker OpenGL");
markers.initialize();
}
);
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::InitializeGL,
[&]() {
LDEBUGC("TouchModule", "Initializing TouchMarker OpenGL");
markers.initialize();
}
);
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::DeinitializeGL,
[&]() {
LDEBUGC("TouchMarker", "Deinitialize TouchMarker OpenGL");
markers.deinitialize();
}
);
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::DeinitializeGL,
[&]() {
LDEBUGC("TouchMarker", "Deinitialize TouchMarker OpenGL");
markers.deinitialize();
}
);
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::PreSync,
[&]() {
touch.setCamera(OsEng.interactionHandler().camera());
touch.setFocusNode(OsEng.interactionHandler().focusNode());
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::PreSync,
[&]() {
touch.setCamera(OsEng.interactionHandler().camera());
touch.setFocusNode(OsEng.interactionHandler().focusNode());
if (hasNewInput() && OsEng.windowWrapper().isMaster()) {
touch.updateStateFromInput(listOfContactPoints, lastProcessed);
}
else if (listOfContactPoints.empty()) {
touch.resetAfterInput();
}
if (hasNewInput() && OsEng.windowWrapper().isMaster()) {
touch.updateStateFromInput(listOfContactPoints, lastProcessed);
}
else if (listOfContactPoints.empty()) {
touch.resetAfterInput();
}
// update lastProcessed
lastProcessed.clear();
for (const TuioCursor& c : listOfContactPoints) {
// update lastProcessed
lastProcessed.clear();
for (const TuioCursor& c : listOfContactPoints) {
lastProcessed.emplace_back(c.getSessionID(), c.getPath().back());
}
touch.unitTest(); // used to save data from solver, only calculated for one frame when user chooses in GUI
touch.step(OsEng.windowWrapper().deltaTime()); // calculate the new camera state for this frame
}
);
}
touch.unitTest(); // used to save data from solver, only calculated for one frame when user chooses in GUI
touch.step(OsEng.windowWrapper().deltaTime()); // calculate the new camera state for this frame
}
);
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::Render,
[&]() {
markers.render(listOfContactPoints); // render markers, customizable through the GUI
}
);
OsEng.registerModuleCallback(
OpenSpaceEngine::CallbackOption::Render,
[&]() {
markers.render(listOfContactPoints); // render markers, customizable through the GUI
}
);
}
} // namespace openspace

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -32,23 +32,23 @@
namespace openspace {
class TouchModule : public OpenSpaceModule {
using Point = std::pair<int, TUIO::TuioPoint>;
public:
TouchModule();
class TouchModule : public OpenSpaceModule {
using Point = std::pair<int, TUIO::TuioPoint>;
public:
TouchModule();
private:
/**
* Returns true if new touch input occured since the last frame
*/
bool hasNewInput();
private:
/**
* Returns true if new touch input occured since the last frame
*/
bool hasNewInput();
TuioEar ear;
TouchInteraction touch;
TouchMarker markers;
std::vector<TUIO::TuioCursor> listOfContactPoints;
std::vector<Point> lastProcessed; // contains an id and the TuioPoint that was processed last frame
};
TuioEar ear;
TouchInteraction touch;
TouchMarker markers;
std::vector<TUIO::TuioCursor> listOfContactPoints;
std::vector<Point> lastProcessed; // contains an id and the TuioPoint that was processed last frame
};
} // namespace openspace