Mercurial > hg > haptic-xypad
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; |