Mercurial > hg > haptic-xypad
view native/OpenHaptics/XYPad/XYScene.cpp @ 1:46671fc7d649 tip
fixed "window" message bug and brought the message outside the haptic device monitor
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Fri, 13 Mar 2015 13:02:16 +0000 |
parents | 011caca7515a |
children |
line wrap: on
line source
/* 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;