Mercurial > hg > haptic-xypad
diff native/OpenHaptics/XYPad/XYScene.cpp @ 0:011caca7515a
first import
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Fri, 13 Feb 2015 14:44:20 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/native/OpenHaptics/XYPad/XYScene.cpp Fri Feb 13 14:44:20 2015 +0000 @@ -0,0 +1,179 @@ +/* +XYPad - a haptic xy-pad that uses the jHapticGUI library + +Copyright (C) 2015 Queen Mary University of London (http://depic.eecs.qmul.ac.uk/) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "XYScene.h" + +#include <HL/hl.h> +#include <HDU/hduError.h> + +#include <GL/gl.h> +#include <GL/glu.h> +#include <GL/glut.h> + +#include <iostream> + +jhapticgui::XYScene::XYScene(void(*messageCallback) (const Message & m)) : HapticScene(messageCallback) {} + +jhapticgui::XYScene::~XYScene() {} + +bool jhapticgui::XYScene::initHaptics(void){ + /* init haptic device */ + HHD hHD = hdInitDevice(HD_DEFAULT_DEVICE); + if (HD_DEVICE_ERROR(hdGetError())) { + /* if unsuccessful return false */ + return false; + } + + /* create haptic context */ + HHLRC hHLRC = hlCreateContext(hHD); + hlMakeCurrent(hHLRC); + + /* Reserve an id for the shape */ + shapeID = hlGenShapes(1); + + + /* initialize the haptic space */ + hlMatrixMode(HL_TOUCHWORKSPACE); + hlLoadIdentity(); + hlOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + + /* install event callbacks for touch and motion */ + hlAddEventCallback(HL_EVENT_TOUCH, HL_OBJECT_ANY, HL_CLIENT_THREAD, checkContact, this); + hlAddEventCallback(HL_EVENT_UNTOUCH, HL_OBJECT_ANY, HL_CLIENT_THREAD, checkContact, this); + hlAddEventCallback(HL_EVENT_MOTION, HL_OBJECT_ANY, HL_CLIENT_THREAD, checkMotion, this); + + /* initialization successful */ + return true; +} + +void jhapticgui::XYScene::initGL(void){ + glClearColor(0.0, 0.0, 0.0, 0.0); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); +} + + +unsigned int jhapticgui::XYScene::processMessage(const Message & m){ + /* there is only one type of message coming from the java * + * but the check is performed nevertheless for clarity */ + if (!strcmp(m.command, "change")) { + + /* the command selects the shape to display here all is done * + * is just a variable update. The variable new value will be * + * read in the next cycle of drawScene */ + if (!strcmp(m.args, "circle")){ + shape = Shape::CIRCLE; + } + else if(!strcmp(m.args, "square")){ + shape = Shape::SQUARE; + } + } + + /* message updates not used, just return any value */ + return 0; +} + +void jhapticgui::XYScene::beginFrame(void){ + hlBeginFrame(); +} + +void jhapticgui::XYScene::endFrame(void){ + hlEndFrame(); +} + +void jhapticgui::XYScene::drawCursor(void){ + /* no cursor drawn */ +} + +void jhapticgui::XYScene::drawScene(unsigned int messageUpdate, unsigned int callbacksUpdate){ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glColor3f(1.0, 200.0/255.0, 0.0); + + hlBeginShape(HL_SHAPE_DEPTH_BUFFER, shapeID); + + /* use shape variable to determine which shape to draw */ + if (shape == Shape::SQUARE){ + glBegin(GL_POLYGON); + glVertex3f(-RADIUS, -RADIUS, 0.0); + glVertex3f(RADIUS, -RADIUS, 0.0); + glVertex3f(RADIUS, RADIUS, 0.0); + glVertex3f(-RADIUS, RADIUS, 0.0); + glEnd(); + } + else { // CIRCLE + glutSolidSphere(RADIUS, 64, 64); + } + + hlEndShape(); +} + +unsigned int jhapticgui::XYScene::checkCallbacks(void){ + /* openhaptics call to check all the events */ + hlCheckEvents(); + /* no callback update used, return any value */ + return 0; +} + +/* contact callback */ +void jhapticgui::XYScene::checkContact(HLenum event, HLuint object, HLenum thread, HLcache *cache, void *userdata){ + XYScene *pThis = static_cast<XYScene*>(userdata); + + /* update a status variable and send a message to the java thread */ + if (event == HL_EVENT_TOUCH){ + pThis->isTouching = true; + pThis->send(Message("touch", "yes", object)); + } + else{ + pThis->isTouching = false; + pThis->send(Message("touch", "no", object)); + } +} + +/* motion callback */ +void jhapticgui::XYScene::checkMotion(HLenum event, HLuint object, HLenum thread, HLcache *cache, void *userdata){ + /* pointer to this scene */ + XYScene *pThis = static_cast<XYScene*>(userdata); + + /* get the proxy position */ + HLdouble proxyPosition[3]; + hlGetDoublev(HL_DEVICE_POSITION, proxyPosition); + + /* only send position data if the haptic object is being touched */ + if (pThis->isTouching){ + /* the proxy position ranges from -RADIUS to +RADIUS * + * so the formula to get a normalized position (0 to 1)* + * is: ( proxyPos - (-RADIUS) / (RADIUS) - (-RADIUS) ),* + * let RADIUS be 0.5, the above formula is reduced to * + * proxyPos + RADIUS */ + double x = proxyPosition[0] + RADIUS; + double y = proxyPosition[1] + RADIUS; + + /* send position message */ + char msgArgs[Message::MAX_ARGS_LEN]; + sprintf_s(msgArgs, "%f %f", x, y); + pThis->send(Message("position", msgArgs, object)); + } +} + + +const double jhapticgui::XYScene::RADIUS = 0.5; \ No newline at end of file