comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:011caca7515a
1 /*
2 XYPad - a haptic xy-pad that uses the jHapticGUI library
3
4 Copyright (C) 2015 Queen Mary University of London (http://depic.eecs.qmul.ac.uk/)
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "XYScene.h"
20
21 #include <HL/hl.h>
22 #include <HDU/hduError.h>
23
24 #include <GL/gl.h>
25 #include <GL/glu.h>
26 #include <GL/glut.h>
27
28 #include <iostream>
29
30 jhapticgui::XYScene::XYScene(void(*messageCallback) (const Message & m)) : HapticScene(messageCallback) {}
31
32 jhapticgui::XYScene::~XYScene() {}
33
34 bool jhapticgui::XYScene::initHaptics(void){
35 /* init haptic device */
36 HHD hHD = hdInitDevice(HD_DEFAULT_DEVICE);
37 if (HD_DEVICE_ERROR(hdGetError())) {
38 /* if unsuccessful return false */
39 return false;
40 }
41
42 /* create haptic context */
43 HHLRC hHLRC = hlCreateContext(hHD);
44 hlMakeCurrent(hHLRC);
45
46 /* Reserve an id for the shape */
47 shapeID = hlGenShapes(1);
48
49
50 /* initialize the haptic space */
51 hlMatrixMode(HL_TOUCHWORKSPACE);
52 hlLoadIdentity();
53 hlOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
54
55 /* install event callbacks for touch and motion */
56 hlAddEventCallback(HL_EVENT_TOUCH, HL_OBJECT_ANY, HL_CLIENT_THREAD, checkContact, this);
57 hlAddEventCallback(HL_EVENT_UNTOUCH, HL_OBJECT_ANY, HL_CLIENT_THREAD, checkContact, this);
58 hlAddEventCallback(HL_EVENT_MOTION, HL_OBJECT_ANY, HL_CLIENT_THREAD, checkMotion, this);
59
60 /* initialization successful */
61 return true;
62 }
63
64 void jhapticgui::XYScene::initGL(void){
65 glClearColor(0.0, 0.0, 0.0, 0.0);
66 glMatrixMode(GL_PROJECTION);
67 glLoadIdentity();
68 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
69
70 glDepthFunc(GL_LEQUAL);
71 glEnable(GL_DEPTH_TEST);
72 }
73
74
75 unsigned int jhapticgui::XYScene::processMessage(const Message & m){
76 /* there is only one type of message coming from the java *
77 * but the check is performed nevertheless for clarity */
78 if (!strcmp(m.command, "change")) {
79
80 /* the command selects the shape to display here all is done *
81 * is just a variable update. The variable new value will be *
82 * read in the next cycle of drawScene */
83 if (!strcmp(m.args, "circle")){
84 shape = Shape::CIRCLE;
85 }
86 else if(!strcmp(m.args, "square")){
87 shape = Shape::SQUARE;
88 }
89 }
90
91 /* message updates not used, just return any value */
92 return 0;
93 }
94
95 void jhapticgui::XYScene::beginFrame(void){
96 hlBeginFrame();
97 }
98
99 void jhapticgui::XYScene::endFrame(void){
100 hlEndFrame();
101 }
102
103 void jhapticgui::XYScene::drawCursor(void){
104 /* no cursor drawn */
105 }
106
107 void jhapticgui::XYScene::drawScene(unsigned int messageUpdate, unsigned int callbacksUpdate){
108
109 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
110 glColor3f(1.0, 200.0/255.0, 0.0);
111
112 hlBeginShape(HL_SHAPE_DEPTH_BUFFER, shapeID);
113
114 /* use shape variable to determine which shape to draw */
115 if (shape == Shape::SQUARE){
116 glBegin(GL_POLYGON);
117 glVertex3f(-RADIUS, -RADIUS, 0.0);
118 glVertex3f(RADIUS, -RADIUS, 0.0);
119 glVertex3f(RADIUS, RADIUS, 0.0);
120 glVertex3f(-RADIUS, RADIUS, 0.0);
121 glEnd();
122 }
123 else { // CIRCLE
124 glutSolidSphere(RADIUS, 64, 64);
125 }
126
127 hlEndShape();
128 }
129
130 unsigned int jhapticgui::XYScene::checkCallbacks(void){
131 /* openhaptics call to check all the events */
132 hlCheckEvents();
133 /* no callback update used, return any value */
134 return 0;
135 }
136
137 /* contact callback */
138 void jhapticgui::XYScene::checkContact(HLenum event, HLuint object, HLenum thread, HLcache *cache, void *userdata){
139 XYScene *pThis = static_cast<XYScene*>(userdata);
140
141 /* update a status variable and send a message to the java thread */
142 if (event == HL_EVENT_TOUCH){
143 pThis->isTouching = true;
144 pThis->send(Message("touch", "yes", object));
145 }
146 else{
147 pThis->isTouching = false;
148 pThis->send(Message("touch", "no", object));
149 }
150 }
151
152 /* motion callback */
153 void jhapticgui::XYScene::checkMotion(HLenum event, HLuint object, HLenum thread, HLcache *cache, void *userdata){
154 /* pointer to this scene */
155 XYScene *pThis = static_cast<XYScene*>(userdata);
156
157 /* get the proxy position */
158 HLdouble proxyPosition[3];
159 hlGetDoublev(HL_DEVICE_POSITION, proxyPosition);
160
161 /* only send position data if the haptic object is being touched */
162 if (pThis->isTouching){
163 /* the proxy position ranges from -RADIUS to +RADIUS *
164 * so the formula to get a normalized position (0 to 1)*
165 * is: ( proxyPos - (-RADIUS) / (RADIUS) - (-RADIUS) ),*
166 * let RADIUS be 0.5, the above formula is reduced to *
167 * proxyPos + RADIUS */
168 double x = proxyPosition[0] + RADIUS;
169 double y = proxyPosition[1] + RADIUS;
170
171 /* send position message */
172 char msgArgs[Message::MAX_ARGS_LEN];
173 sprintf_s(msgArgs, "%f %f", x, y);
174 pThis->send(Message("position", msgArgs, object));
175 }
176 }
177
178
179 const double jhapticgui::XYScene::RADIUS = 0.5;