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