559 lines
21 KiB
C++
559 lines
21 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
|
*
|
|
* This library is open source and may be redistributed and/or modified under
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
*
|
|
* This library 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
|
|
* OpenSceneGraph Public License for more details.
|
|
*/
|
|
|
|
#ifndef OSGGA_EVENT
|
|
#define OSGGA_EVENT 1
|
|
|
|
#include <osg/Object>
|
|
#include <osg/Matrix>
|
|
#include <osg/GraphicsContext>
|
|
#include <osgGA/Export>
|
|
|
|
namespace osgGA{
|
|
|
|
|
|
/** Event class for storing Keyboard, mouse and window events.
|
|
*/
|
|
class OSGGA_EXPORT GUIEventAdapter : public osg::Object
|
|
{
|
|
public:
|
|
|
|
enum MouseButtonMask {
|
|
LEFT_MOUSE_BUTTON = 1<<0,
|
|
MIDDLE_MOUSE_BUTTON = 1<<1,
|
|
RIGHT_MOUSE_BUTTON = 1<<2
|
|
};
|
|
|
|
enum EventType {
|
|
NONE = 0,
|
|
PUSH = 1<<0,
|
|
RELEASE = 1<<1,
|
|
DOUBLECLICK = 1<<2,
|
|
DRAG = 1<<3,
|
|
MOVE = 1<<4,
|
|
KEYDOWN = 1<<5,
|
|
KEYUP = 1<<6,
|
|
FRAME = 1<<7,
|
|
RESIZE = 1<<8,
|
|
SCROLL = 1<<9,
|
|
PEN_PRESSURE = 1<<10,
|
|
PEN_ORIENTATION = 1<<11,
|
|
PEN_PROXIMITY_ENTER = 1<<12,
|
|
PEN_PROXIMITY_LEAVE = 1<<13,
|
|
CLOSE_WINDOW = 1<<14,
|
|
QUIT_APPLICATION = 1<<15,
|
|
USER = 1<<16
|
|
};
|
|
|
|
enum KeySymbol
|
|
{
|
|
KEY_Space = 0x20,
|
|
|
|
KEY_BackSpace = 0xFF08, /* back space, back char */
|
|
KEY_Tab = 0xFF09,
|
|
KEY_Linefeed = 0xFF0A, /* Linefeed, LF */
|
|
KEY_Clear = 0xFF0B,
|
|
KEY_Return = 0xFF0D, /* Return, enter */
|
|
KEY_Pause = 0xFF13, /* Pause, hold */
|
|
KEY_Scroll_Lock = 0xFF14,
|
|
KEY_Sys_Req = 0xFF15,
|
|
KEY_Escape = 0xFF1B,
|
|
KEY_Delete = 0xFFFF, /* Delete, rubout */
|
|
|
|
|
|
/* Cursor control & motion */
|
|
|
|
KEY_Home = 0xFF50,
|
|
KEY_Left = 0xFF51, /* Move left, left arrow */
|
|
KEY_Up = 0xFF52, /* Move up, up arrow */
|
|
KEY_Right = 0xFF53, /* Move right, right arrow */
|
|
KEY_Down = 0xFF54, /* Move down, down arrow */
|
|
KEY_Prior = 0xFF55, /* Prior, previous */
|
|
KEY_Page_Up = 0xFF55,
|
|
KEY_Next = 0xFF56, /* Next */
|
|
KEY_Page_Down = 0xFF56,
|
|
KEY_End = 0xFF57, /* EOL */
|
|
KEY_Begin = 0xFF58, /* BOL */
|
|
|
|
|
|
/* Misc Functions */
|
|
|
|
KEY_Select = 0xFF60, /* Select, mark */
|
|
KEY_Print = 0xFF61,
|
|
KEY_Execute = 0xFF62, /* Execute, run, do */
|
|
KEY_Insert = 0xFF63, /* Insert, insert here */
|
|
KEY_Undo = 0xFF65, /* Undo, oops */
|
|
KEY_Redo = 0xFF66, /* redo, again */
|
|
KEY_Menu = 0xFF67, /* On Windows, this is VK_APPS, the context-menu key */
|
|
KEY_Find = 0xFF68, /* Find, search */
|
|
KEY_Cancel = 0xFF69, /* Cancel, stop, abort, exit */
|
|
KEY_Help = 0xFF6A, /* Help */
|
|
KEY_Break = 0xFF6B,
|
|
KEY_Mode_switch = 0xFF7E, /* Character set switch */
|
|
KEY_Script_switch = 0xFF7E, /* Alias for mode_switch */
|
|
KEY_Num_Lock = 0xFF7F,
|
|
|
|
/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */
|
|
|
|
KEY_KP_Space = 0xFF80, /* space */
|
|
KEY_KP_Tab = 0xFF89,
|
|
KEY_KP_Enter = 0xFF8D, /* enter */
|
|
KEY_KP_F1 = 0xFF91, /* PF1, KP_A, ... */
|
|
KEY_KP_F2 = 0xFF92,
|
|
KEY_KP_F3 = 0xFF93,
|
|
KEY_KP_F4 = 0xFF94,
|
|
KEY_KP_Home = 0xFF95,
|
|
KEY_KP_Left = 0xFF96,
|
|
KEY_KP_Up = 0xFF97,
|
|
KEY_KP_Right = 0xFF98,
|
|
KEY_KP_Down = 0xFF99,
|
|
KEY_KP_Prior = 0xFF9A,
|
|
KEY_KP_Page_Up = 0xFF9A,
|
|
KEY_KP_Next = 0xFF9B,
|
|
KEY_KP_Page_Down = 0xFF9B,
|
|
KEY_KP_End = 0xFF9C,
|
|
KEY_KP_Begin = 0xFF9D,
|
|
KEY_KP_Insert = 0xFF9E,
|
|
KEY_KP_Delete = 0xFF9F,
|
|
KEY_KP_Equal = 0xFFBD, /* equals */
|
|
KEY_KP_Multiply = 0xFFAA,
|
|
KEY_KP_Add = 0xFFAB,
|
|
KEY_KP_Separator = 0xFFAC, /* separator, often comma */
|
|
KEY_KP_Subtract = 0xFFAD,
|
|
KEY_KP_Decimal = 0xFFAE,
|
|
KEY_KP_Divide = 0xFFAF,
|
|
|
|
KEY_KP_0 = 0xFFB0,
|
|
KEY_KP_1 = 0xFFB1,
|
|
KEY_KP_2 = 0xFFB2,
|
|
KEY_KP_3 = 0xFFB3,
|
|
KEY_KP_4 = 0xFFB4,
|
|
KEY_KP_5 = 0xFFB5,
|
|
KEY_KP_6 = 0xFFB6,
|
|
KEY_KP_7 = 0xFFB7,
|
|
KEY_KP_8 = 0xFFB8,
|
|
KEY_KP_9 = 0xFFB9,
|
|
|
|
/*
|
|
* Auxiliary Functions; note the duplicate definitions for left and right
|
|
* function keys; Sun keyboards and a few other manufactures have such
|
|
* function key groups on the left and/or right sides of the keyboard.
|
|
* We've not found a keyboard with more than 35 function keys total.
|
|
*/
|
|
|
|
KEY_F1 = 0xFFBE,
|
|
KEY_F2 = 0xFFBF,
|
|
KEY_F3 = 0xFFC0,
|
|
KEY_F4 = 0xFFC1,
|
|
KEY_F5 = 0xFFC2,
|
|
KEY_F6 = 0xFFC3,
|
|
KEY_F7 = 0xFFC4,
|
|
KEY_F8 = 0xFFC5,
|
|
KEY_F9 = 0xFFC6,
|
|
KEY_F10 = 0xFFC7,
|
|
KEY_F11 = 0xFFC8,
|
|
KEY_F12 = 0xFFC9,
|
|
KEY_F13 = 0xFFCA,
|
|
KEY_F14 = 0xFFCB,
|
|
KEY_F15 = 0xFFCC,
|
|
KEY_F16 = 0xFFCD,
|
|
KEY_F17 = 0xFFCE,
|
|
KEY_F18 = 0xFFCF,
|
|
KEY_F19 = 0xFFD0,
|
|
KEY_F20 = 0xFFD1,
|
|
KEY_F21 = 0xFFD2,
|
|
KEY_F22 = 0xFFD3,
|
|
KEY_F23 = 0xFFD4,
|
|
KEY_F24 = 0xFFD5,
|
|
KEY_F25 = 0xFFD6,
|
|
KEY_F26 = 0xFFD7,
|
|
KEY_F27 = 0xFFD8,
|
|
KEY_F28 = 0xFFD9,
|
|
KEY_F29 = 0xFFDA,
|
|
KEY_F30 = 0xFFDB,
|
|
KEY_F31 = 0xFFDC,
|
|
KEY_F32 = 0xFFDD,
|
|
KEY_F33 = 0xFFDE,
|
|
KEY_F34 = 0xFFDF,
|
|
KEY_F35 = 0xFFE0,
|
|
|
|
/* Modifiers */
|
|
|
|
KEY_Shift_L = 0xFFE1, /* Left shift */
|
|
KEY_Shift_R = 0xFFE2, /* Right shift */
|
|
KEY_Control_L = 0xFFE3, /* Left control */
|
|
KEY_Control_R = 0xFFE4, /* Right control */
|
|
KEY_Caps_Lock = 0xFFE5, /* Caps lock */
|
|
KEY_Shift_Lock = 0xFFE6, /* Shift lock */
|
|
|
|
KEY_Meta_L = 0xFFE7, /* Left meta */
|
|
KEY_Meta_R = 0xFFE8, /* Right meta */
|
|
KEY_Alt_L = 0xFFE9, /* Left alt */
|
|
KEY_Alt_R = 0xFFEA, /* Right alt */
|
|
KEY_Super_L = 0xFFEB, /* Left super */
|
|
KEY_Super_R = 0xFFEC, /* Right super */
|
|
KEY_Hyper_L = 0xFFED, /* Left hyper */
|
|
KEY_Hyper_R = 0xFFEE /* Right hyper */
|
|
};
|
|
|
|
|
|
enum ModKeyMask
|
|
{
|
|
MODKEY_LEFT_SHIFT = 0x0001,
|
|
MODKEY_RIGHT_SHIFT = 0x0002,
|
|
MODKEY_LEFT_CTRL = 0x0004,
|
|
MODKEY_RIGHT_CTRL = 0x0008,
|
|
MODKEY_LEFT_ALT = 0x0010,
|
|
MODKEY_RIGHT_ALT = 0x0020,
|
|
MODKEY_LEFT_META = 0x0040,
|
|
MODKEY_RIGHT_META = 0x0080,
|
|
MODKEY_LEFT_SUPER = 0x0100,
|
|
MODKEY_RIGHT_SUPER = 0x0200,
|
|
MODKEY_LEFT_HYPER = 0x0400,
|
|
MODKEY_RIGHT_HYPER = 0x0800,
|
|
MODKEY_NUM_LOCK = 0x1000,
|
|
MODKEY_CAPS_LOCK = 0x2000,
|
|
MODKEY_CTRL = (MODKEY_LEFT_CTRL|MODKEY_RIGHT_CTRL),
|
|
MODKEY_SHIFT = (MODKEY_LEFT_SHIFT|MODKEY_RIGHT_SHIFT),
|
|
MODKEY_ALT = (MODKEY_LEFT_ALT|MODKEY_RIGHT_ALT),
|
|
MODKEY_META = (MODKEY_LEFT_META|MODKEY_RIGHT_META),
|
|
MODKEY_SUPER = (MODKEY_LEFT_SUPER|MODKEY_RIGHT_SUPER),
|
|
MODKEY_HYPER = (MODKEY_LEFT_HYPER|MODKEY_RIGHT_HYPER)
|
|
};
|
|
|
|
enum MouseYOrientation
|
|
{
|
|
Y_INCREASING_UPWARDS,
|
|
Y_INCREASING_DOWNWARDS
|
|
};
|
|
|
|
enum ScrollingMotion
|
|
{
|
|
SCROLL_NONE,
|
|
SCROLL_LEFT,
|
|
SCROLL_RIGHT,
|
|
SCROLL_UP,
|
|
SCROLL_DOWN,
|
|
SCROLL_2D
|
|
};
|
|
|
|
enum TabletPointerType
|
|
{
|
|
UNKNOWN = 0,
|
|
PEN,
|
|
PUCK,
|
|
ERASER
|
|
};
|
|
|
|
enum TouchPhase
|
|
{
|
|
TOUCH_UNKNOWN,
|
|
TOUCH_BEGAN,
|
|
TOUCH_MOVED,
|
|
TOUCH_STATIONERY,
|
|
TOUCH_ENDED
|
|
};
|
|
|
|
class TouchData : public osg::Referenced {
|
|
public:
|
|
struct TouchPoint {
|
|
unsigned int id;
|
|
TouchPhase phase;
|
|
float x, y;
|
|
|
|
unsigned int tapCount;
|
|
TouchPoint() : id(0), phase(TOUCH_UNKNOWN), x(0.0f), y(0.0f), tapCount(0) {}
|
|
TouchPoint(unsigned int in_id, TouchPhase in_phase, float in_x, float in_y, unsigned int in_tap_count)
|
|
: id(in_id),
|
|
phase(in_phase),
|
|
x(in_x),
|
|
y(in_y),
|
|
tapCount(in_tap_count)
|
|
{
|
|
}
|
|
};
|
|
|
|
typedef std::vector<TouchPoint> TouchSet;
|
|
|
|
typedef TouchSet::iterator iterator;
|
|
typedef TouchSet::const_iterator const_iterator;
|
|
|
|
TouchData() : osg::Referenced() {}
|
|
|
|
unsigned int getNumTouchPoints() const { return _touches.size(); }
|
|
|
|
iterator begin() { return _touches.begin(); }
|
|
const_iterator begin() const { return _touches.begin(); }
|
|
|
|
iterator end() { return _touches.end(); }
|
|
const_iterator end() const { return _touches.end(); }
|
|
|
|
const TouchPoint get(unsigned int i) const { return _touches[i]; }
|
|
|
|
protected:
|
|
|
|
void addTouchPoint(unsigned int id, TouchPhase phase, float x, float y, unsigned int tap_count) {
|
|
_touches.push_back(TouchPoint(id, phase, x, y, tap_count));
|
|
}
|
|
|
|
TouchSet _touches;
|
|
|
|
friend class GUIEventAdapter;
|
|
};
|
|
|
|
public:
|
|
|
|
GUIEventAdapter();
|
|
|
|
GUIEventAdapter(const GUIEventAdapter& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
|
|
|
META_Object(osgGA, GUIEventAdapter);
|
|
|
|
|
|
/** Get the accumulated event state singleton.
|
|
* Typically all EventQueue will share this single GUIEventAdapter object for tracking
|
|
* the mouse position, keyboard and mouse masks. */
|
|
static osg::ref_ptr<GUIEventAdapter>& getAccumulatedEventState();
|
|
|
|
|
|
/** Set whether this event has been handled by an event handler or not.*/
|
|
void setHandled(bool handled) const { _handled = handled; }
|
|
|
|
/** Get whether this event has been handled by an event handler or not.*/
|
|
bool getHandled() const { return _handled; }
|
|
|
|
/** set the event type. */
|
|
void setEventType(EventType Type) { _eventType = Type; }
|
|
|
|
/** get the event type. */
|
|
virtual EventType getEventType() const { return _eventType; }
|
|
|
|
/** set time in seconds of event. */
|
|
void setTime(double time) { _time = time; }
|
|
|
|
/** get time in seconds of event. */
|
|
double getTime() const { return _time; }
|
|
|
|
/** deprecated function for getting time of event. */
|
|
double time() const { return _time; }
|
|
|
|
|
|
void setGraphicsContext(osg::GraphicsContext* context) { _context = context; }
|
|
const osg::GraphicsContext* getGraphicsContext() const { return _context.get(); }
|
|
|
|
|
|
/** set window rectangle. */
|
|
void setWindowRectangle(int x, int y, int width, int height, bool updateMouseRange = true);
|
|
|
|
/** get window x origin.*/
|
|
int getWindowX() const { return _windowX; }
|
|
|
|
/** get window y origin.*/
|
|
int getWindowY() const { return _windowY; }
|
|
|
|
/** get window width.*/
|
|
int getWindowWidth() const { return _windowWidth; }
|
|
|
|
/** get window height.*/
|
|
int getWindowHeight() const { return _windowHeight; }
|
|
|
|
|
|
/** set key pressed. */
|
|
inline void setKey(int key) { _key = key; }
|
|
|
|
/** get key pressed, return -1 if inappropriate for this GUIEventAdapter. */
|
|
virtual int getKey() const { return _key; }
|
|
|
|
/** set button pressed/released.*/
|
|
void setButton(int button) { _button = button; }
|
|
|
|
/** button pressed/released, return -1 if inappropriate for this GUIEventAdapter.*/
|
|
int getButton() const { return _button; }
|
|
|
|
|
|
/** set mouse input range. */
|
|
void setInputRange(float Xmin, float Ymin, float Xmax, float Ymax);
|
|
|
|
/** get mouse minimum x. */
|
|
float getXmin() const { return _Xmin; }
|
|
|
|
/** get mouse maximum x. */
|
|
float getXmax() const { return _Xmax; }
|
|
|
|
/** get mouse minimum y. */
|
|
float getYmin() const { return _Ymin; }
|
|
|
|
/** get mouse maximum y. */
|
|
float getYmax() const { return _Ymax; }
|
|
|
|
/** set current mouse x position.*/
|
|
void setX(float x) { _mx = x; }
|
|
|
|
/** get current mouse x position.*/
|
|
float getX() const { return _mx; }
|
|
|
|
/** set current mouse y position.*/
|
|
void setY(float y) { _my = y; }
|
|
|
|
/** get current mouse y position.*/
|
|
float getY() const { return _my; }
|
|
|
|
/**
|
|
* return the current mouse x value normalized to the range of -1 to 1.
|
|
* -1 would be the left hand side of the window.
|
|
* 0.0 would be the middle of the window.
|
|
* +1 would be the right hand side of the window.
|
|
*/
|
|
inline float getXnormalized() const { return 2.0f*(getX()-getXmin())/(getXmax()-getXmin())-1.0f; }
|
|
|
|
/**
|
|
* return the current mouse y value normalized to the range of -1 to 1.
|
|
* -1 would be the bottom of the window.
|
|
* 0.0 would be the middle of the window.
|
|
* +1 would be the top of the window.
|
|
*/
|
|
inline float getYnormalized() const
|
|
{
|
|
if (_mouseYOrientation==Y_INCREASING_UPWARDS) return 2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f;
|
|
else return -(2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f);
|
|
}
|
|
|
|
/// set mouse-Y orientation (mouse-Y increases upwards or downwards).
|
|
void setMouseYOrientation(MouseYOrientation myo) { _mouseYOrientation = myo; }
|
|
|
|
/// get mouse-Y orientation (mouse-Y increases upwards or downwards).
|
|
MouseYOrientation getMouseYOrientation() const { return _mouseYOrientation; }
|
|
|
|
/// set current mouse button state.
|
|
void setButtonMask(int mask) { _buttonMask = mask; }
|
|
|
|
/// get current mouse button state.
|
|
int getButtonMask() const { return _buttonMask; }
|
|
|
|
/// set modifier key mask.
|
|
void setModKeyMask(int mask) { _modKeyMask = mask; }
|
|
|
|
/// get modifier key mask.
|
|
int getModKeyMask() const { return _modKeyMask; }
|
|
|
|
/// set scrolling motion (for EventType::SCROLL).
|
|
void setScrollingMotion(ScrollingMotion motion) { _scrolling.motion = motion; }
|
|
|
|
/// get scrolling motion (for EventType::SCROLL).
|
|
ScrollingMotion getScrollingMotion() const { return _scrolling.motion; }
|
|
|
|
/// set the scrolling delta to x,y and the scrolling motion to SCROLL_2D.
|
|
void setScrollingMotionDelta(float x, float y) {
|
|
_scrolling.motion = SCROLL_2D;
|
|
_scrolling.deltaX = x;
|
|
_scrolling.deltaY = y;
|
|
}
|
|
|
|
/// get the scrolling x-delta.
|
|
float getScrollingDeltaX() const { return _scrolling.deltaX; }
|
|
|
|
/// get the scrolling y-delta.
|
|
float getScrollingDeltaY() const { return _scrolling.deltaY; }
|
|
|
|
|
|
/// set the tablet pen pressure (range 0..1).
|
|
void setPenPressure(float pressure) { _tabletPen.pressure = pressure; }
|
|
|
|
/// get the tablet pen pressure (range 0..1).
|
|
float getPenPressure() const { return _tabletPen.pressure; }
|
|
|
|
/// set the tablet pen tiltX in degrees.
|
|
void setPenTiltX(float tiltX) { _tabletPen.tiltX = tiltX; }
|
|
|
|
/// get the tablet pen tiltX in degrees.
|
|
float getPenTiltX() const { return _tabletPen.tiltX; }
|
|
|
|
/// set the tablet pen tiltY in degrees.
|
|
void setPenTiltY(float tiltY) { _tabletPen.tiltY = tiltY; }
|
|
|
|
/// get the tablet pen tiltY in degrees.
|
|
float getPenTiltY() const { return _tabletPen.tiltY; }
|
|
|
|
/// set the tablet pen rotation around the Z-axis in degrees.
|
|
void setPenRotation(float rotation) { _tabletPen.rotation = rotation; }
|
|
|
|
/// get the tablet pen rotation around the Z-axis in degrees.
|
|
float getPenRotation() const { return _tabletPen.rotation; }
|
|
|
|
/// set the tablet pointer type.
|
|
void setTabletPointerType(TabletPointerType pt) { _tabletPen.tabletPointerType = pt; }
|
|
|
|
/// get the tablet pointer type.
|
|
TabletPointerType getTabletPointerType() const { return _tabletPen.tabletPointerType; }
|
|
|
|
/// set the orientation from a tablet input device as a matrix.
|
|
const osg::Matrix getPenOrientation() const;
|
|
|
|
void addTouchPoint(unsigned int id, TouchPhase phase, float x, float y, unsigned int tapCount = 0);
|
|
|
|
TouchData* getTouchData() const { return _touchData.get(); }
|
|
bool isMultiTouchEvent() const { return (_touchData.valid()); }
|
|
|
|
protected:
|
|
|
|
/** Force users to create on heap, so that multiple referencing is safe.*/
|
|
virtual ~GUIEventAdapter();
|
|
|
|
mutable bool _handled;
|
|
EventType _eventType;
|
|
double _time;
|
|
|
|
osg::observer_ptr<osg::GraphicsContext> _context;
|
|
int _windowX;
|
|
int _windowY;
|
|
int _windowWidth;
|
|
int _windowHeight;
|
|
int _key;
|
|
int _button;
|
|
float _Xmin,_Xmax;
|
|
float _Ymin,_Ymax;
|
|
float _mx;
|
|
float _my;
|
|
int _buttonMask;
|
|
int _modKeyMask;
|
|
MouseYOrientation _mouseYOrientation;
|
|
|
|
struct Scrolling {
|
|
ScrollingMotion motion;
|
|
float deltaX;
|
|
float deltaY;
|
|
|
|
Scrolling() : motion(SCROLL_NONE), deltaX(0), deltaY(0) {}
|
|
Scrolling(const Scrolling& rhs) : motion(rhs.motion), deltaX(rhs.deltaX), deltaY(rhs.deltaY) {}
|
|
};
|
|
Scrolling _scrolling;
|
|
|
|
struct TabletPen {
|
|
float pressure;
|
|
float tiltX;
|
|
float tiltY;
|
|
float rotation;
|
|
TabletPointerType tabletPointerType;
|
|
|
|
TabletPen() : pressure(0), tiltX(0), tiltY(0), rotation(0), tabletPointerType(UNKNOWN) {}
|
|
TabletPen(const TabletPen& rhs) : pressure(rhs.pressure), tiltX(rhs.tiltX), tiltY(rhs.tiltY), rotation(rhs.rotation), tabletPointerType(rhs.tabletPointerType) {}
|
|
};
|
|
TabletPen _tabletPen;
|
|
|
|
osg::ref_ptr<TouchData> _touchData;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|