00001 /* 00002 This source file is part of OgreHaptics 00003 (a library for wrapping haptics devices for use with the open-source 00004 graphics engine OGRE, http://www.ogre3d.org) 00005 00006 Copyright (c) 2006 - 2008 Jorrit de Vries 00007 Also see acknowledgements in Readme.html 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public License 00011 as published by the Free Software Foundation; either version 2.1 00012 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the 00021 Free Software Foundation, Inc., 00022 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 */ 00024 // -- Frame listener & events implementation based on Ogre::Root, original copyright follows -- 00025 // 00026 // This source file is part of OGRE 00027 // (Object-oriented Graphics Rendering Engine) 00028 // For the latest info, see http://www.ogre3d.org/ 00029 // 00030 // Copyright (c) 2000-2006 Torus Knot Software Ltd 00031 // Also see acknowledgements in Readme.html 00032 // 00033 // This program is free software; you can redistribute it and/or modify it under 00034 // the terms of the GNU Lesser General Public License as published by the Free Software 00035 // Foundation; either version 2 of the License, or (at your option) any later 00036 // version. 00037 // 00038 // This program is distributed in the hope that it will be useful, but WITHOUT 00039 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00040 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00041 // 00042 // You should have received a copy of the GNU Lesser General Public License along with 00043 // this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00044 // Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00045 // http://www.gnu.org/copyleft/lesser.txt. 00046 // 00047 // You may alternatively use this source under the terms of a specific version of 00048 // the OGRE Unrestricted License provided you have obtained such a license from 00049 // Torus Knot Software Ltd. 00050 #ifndef _OgreHapticsDevice_H__ 00051 #define _OgreHapticsDevice_H__ 00052 00053 #include "OgreHapticsPrerequisites.h" 00054 #include "OgreHapticsAtomic.h" 00055 #include "OgreHapticsCommon.h" 00056 #include "OgreHapticsConcurrentQueue.h" 00057 #include "OgreHapticsEvent.h" 00058 #include "OgreHapticsForceOutput.h" 00059 00060 namespace OgreHaptics { 00061 00066 enum DeviceButton 00067 { 00069 DB_NO_BUTTON = 0, 00071 DB_BUTTON1 = 0x01, 00073 DB_BUTTON2 = 0x02, 00075 DB_BUTTON3 = 0x04, 00077 DB_BUTTON4 = 0x08, 00084 DB_INKWELL = DB_BUTTON3, 00091 DB_SAFETY = DB_BUTTON4, 00092 }; 00093 00095 enum DeviceCalibrationState 00096 { 00098 DCS_NOT_INITIALISED, 00105 DCS_NEEDS_CALIBRATION, 00107 DCS_CALIBRATED 00108 }; 00109 00111 enum DeviceCalibrationType 00112 { 00120 DCT_UNKNOWN, 00125 DCT_AUTO, 00130 DCT_INKWELL, 00135 DCT_PULL_PUSH, 00140 DCT_RESET_POSITION 00141 }; 00142 00147 struct DeviceState 00148 { 00150 DeviceState() 00151 : buttons(0), 00152 force(Vector3::ZERO), 00153 torque(Vector3::ZERO), 00154 position(Vector3::ZERO), 00155 linearVelocity(Vector3::ZERO), 00156 angularVelocity(Vector3::ZERO), 00157 orientation(Quaternion::IDENTITY) 00158 {} 00160 DeviceState(const DeviceState& rhs) 00161 : buttons(rhs.buttons), 00162 force(rhs.force), 00163 torque(rhs.torque), 00164 position(rhs.position), 00165 linearVelocity(rhs.linearVelocity), 00166 angularVelocity(rhs.angularVelocity), 00167 orientation(rhs.orientation) 00168 {} 00169 00171 int buttons; 00173 Vector3 force; 00175 Vector3 torque; 00177 Vector3 position; 00179 Vector3 linearVelocity; 00181 Vector3 angularVelocity; 00183 Quaternion orientation; 00184 00186 DeviceState& operator = (const DeviceState& rhs) 00187 { 00188 buttons = rhs.buttons; 00189 force = rhs.force; 00190 torque = rhs.torque; 00191 position = rhs.position; 00192 linearVelocity = rhs.linearVelocity; 00193 angularVelocity = rhs.angularVelocity; 00194 orientation = rhs.orientation; 00195 return *this; 00196 } 00197 }; 00198 00200 class _OgreHapticsExport DeviceEvent : public EventArgs 00201 { 00202 public: 00204 DeviceEvent(EventType type, Device* devic, DeviceState state, 00205 DeviceButton btn, DeviceCalibrationState calState) 00206 : EventArgs(type), 00207 device(devic), 00208 cachedState(state), 00209 button(btn), 00210 calibrationState(calState) 00211 {} 00213 virtual ~DeviceEvent() {} 00214 00216 Device* device; 00227 DeviceState cachedState; 00229 DeviceButton button; 00231 DeviceCalibrationState calibrationState; 00232 }; 00233 00249 class _OgreHapticsExport DeviceListener 00250 { 00251 public: 00253 virtual ~DeviceListener() {} 00254 00256 virtual void buttonPressed(const DeviceEvent& evt) {} 00258 virtual void buttonReleased(const DeviceEvent& evt) {} 00260 virtual void calibrationStateChanged(const DeviceEvent& evt) {} 00261 }; 00262 00279 class _OgreHapticsExport Device 00280 { 00281 // Allow RenderSystem class full access 00282 friend class RenderSystem; 00283 public: 00285 struct RenderStats 00286 { 00287 float lastFPS; 00288 float avgFPS; 00289 float bestFPS; 00290 float worstFPS; 00292 double bestFrameTime; 00294 double worstFrameTime; 00295 }; 00296 00298 virtual ~Device(); 00299 00301 virtual void _notifyCreator(RenderSystem* renderSystem); 00303 virtual RenderSystem* _getCreator(void) const { return mCreator; } 00304 00306 const String& getName(void) const { return mName; } 00307 00314 const String& _getInitName(void) const { return mInitName; } 00322 int _getInitIndex(void) const { return mIndex; } 00323 00330 const String& getModel(void) const { return mModel; } 00338 int getSDKVersion(void) const { return mSDKVersion; } 00346 int getDriverVersion(void) const { return mDriverVersion; } 00347 00349 //virtual void getConfigOptions(void) = 0; 00351 //virtual void setConfigOption(const String& name, const String& value) = 0; 00352 00363 virtual void initialise(void) = 0; 00371 virtual void shutdown(void) = 0; 00373 bool isInitialised(void) const { return mIsInitialised; }; 00374 00379 DeviceCalibrationType getCalibrationType(void) const { return mCalibrationType; } 00400 bool needsCalibration(void) const; 00405 DeviceCalibrationState getCalibrationState(void) const; 00411 virtual void calibrate(void) = 0; 00412 00422 virtual void enable(void) = 0; 00428 void disable(void); 00433 bool isEnabled(void) const { return mIsEnabled; } 00434 00442 const RenderStats& getStatistics(void); 00450 void resetStatistics(void); 00451 00470 const Real* getDeviceWorkspaceDimensions(void) const; 00471 00496 void setTouchspaceExtents(const Vector3& leftLowerBack, 00497 const Vector3& rightUpperFront); 00509 void setTouchspaceExtents(Real left, Real bottom, Real back, 00510 Real right, Real top, Real front); 00516 const Real* getTouchspaceExtents(void) const { return mTouchspaceExtents; } 00517 00527 void setWorldTouchMatrix(const Matrix4& worldTouchMatrix); 00529 const Matrix4& getWorldTouchMatrix(void) const { return mWorldTouchMatrix; } 00531 const Matrix4& getTouchWorkspaceMatrix(void) const { return mTouchWorkspaceMatrix; } 00533 const Matrix4& getWorldTouchWorkspaceMatrix(void) const { return mWorldTouchWorkspaceMatrix; } 00554 const Vector3* getWorldWorkspaceCorners(void); 00573 void updateWorkspaceMapping(bool synchronise = true); 00574 00583 void capture(void); 00584 00594 void setDeviceListener(DeviceListener* listener) { mListener = listener; } 00595 00611 bool isButtonDown(DeviceButton button); 00612 00620 const Vector3& getPosition(void) const; 00628 const Quaternion& getOrientation(void) const; 00637 const Vector3& getForce(void) const; 00646 const Vector3& getTorque(void) const; 00655 const Vector3& getLinearVelocity(void) const; 00664 const Vector3& getAngularVelocity(void) const; 00665 00673 const Vector3& getWorldPosition(void) const; 00681 const Quaternion& getWorldOrientation(void) const; 00689 const Vector3& getWorldForce(void) const; 00698 const Vector3& getWorldTorque(void) const; 00706 const Vector3& getWorldLinearVelocity(void) const; 00715 const Vector3& getWorldAngularVelocity(void) const; 00716 00728 void update(void); 00729 00735 const Vector3& _getPosition(void) const; 00741 const Quaternion& _getOrientation(void) const; 00748 const Vector3& _getForce(void) const; 00755 const Vector3& _getTorque(void) const; 00762 const Vector3& _getLinearVelocity(void) const; 00769 const Vector3& _getAngularVelocity(void) const; 00770 00776 const Vector3& _getWorldPosition(void) const; 00782 const Quaternion& _getWorldOrientation(void) const; 00788 const Vector3& _getWorldForce(void) const; 00795 const Vector3& _getWorldTorque(void) const; 00801 const Vector3& _getWorldLinearVelocity(void) const; 00808 const Vector3& _getWorldAngularVelocity(void) const; 00809 00816 const Vector3& _getPreviousPosition(void) const; 00823 const Quaternion& _getPreviousOrientation(void) const; 00830 const Vector3& _getPreviousForce(void) const; 00837 const Vector3& _getPreviousTorque(void) const; 00844 const Vector3& _getPreviousLinearVelocity(void) const; 00851 const Vector3& _getPreviousAngularVelocity(void) const; 00852 00859 const Vector3& _getPreviousWorldPosition(void) const; 00866 const Quaternion& _getPreviousWorldOrientation(void) const; 00873 const Vector3& _getPreviousWorldForce(void) const; 00880 const Vector3& _getPreviousWorldTorque(void) const; 00887 const Vector3& _getPreviousWorldLinearVelocity(void) const; 00894 const Vector3& _getPreviousWorldAngularVelocity(void) const; 00895 00906 bool _isButtonDown(DeviceButton button); 00907 00962 virtual bool _setOption(const String& key, const void* value); 00963 01033 virtual bool _getOption(const String& key, void* value); 01034 01045 void _setFrameListener(FrameListener* listener); 01046 01051 void _addEffect(ForceEffect* effect); 01056 void _removeEffect(ForceEffect* effect, bool immediate = false); 01061 void _restartEffect(ForceEffect* effect); 01066 void _updateEffect(ForceEffect* effect); 01067 01079 virtual void _applyForces(const Vector3& force, const Vector3& torque) = 0; 01080 01091 virtual void _makeCurrent(void) = 0; 01092 protected: 01094 Device(const String& name, const DeviceInitInfo& initInfo, int index = -1); 01095 01097 String mName; 01099 String mInitName; 01101 String mModel; 01103 RenderSystem* mCreator; 01105 Timer* mTimer; 01107 int mIndex; 01109 int mSDKVersion; 01111 int mDriverVersion; 01113 bool mIsInitialised; 01115 bool mIsEnabled; 01117 bool mDeviceWorkspaceDimensionsDirty; 01119 bool mRecalcWorkspaceMapping; 01121 bool mSynchroniseWorkspaceMatrices; 01123 bool mRecalcWorldWorkspaceCorners; 01125 DeviceCalibrationType mCalibrationType; 01126 01129 Real mDeviceWorkspaceDimensions[6]; 01131 Real mTouchspaceExtents[6]; 01134 Matrix4 mWorldTouchMatrix; 01137 Matrix4 mhtWorldTouchMatrix; 01140 Matrix4 mTouchWorkspaceMatrix; 01143 Matrix4 mhtTouchWorkspaceMatrix; 01145 Matrix4 mInverseTouchWorkspaceMatrix; 01148 Matrix4 mhtInverseTouchWorkspaceMatrix; 01151 Matrix4 mWorldTouchWorkspaceMatrix; 01154 Matrix4 mhtWorldTouchWorkspaceMatrix; 01157 Matrix4 mInverseWorldTouchWorkspaceMatrix; 01160 Matrix4 mhtInverseWorldTouchWorkspaceMatrix; 01162 Vector3 mWorldWorkspaceCorners[8]; 01163 01165 AtomicScalar<DeviceCalibrationState> mCalibrationState; 01167 mutable RenderStats mStats; 01169 RenderStats mhtStats; 01171 unsigned int mhtFrameCount; 01173 double mhtFrameTime; 01175 double mhtLastTime; 01177 double mhtLastSecond; 01178 01180 DeviceState mDeviceState; 01183 DeviceState mhtDeviceState; 01186 DeviceState mhtPreviousDeviceState; 01190 DeviceState mWorldDeviceState; 01194 DeviceState mhtWorldDeviceState; 01198 DeviceState mhtPreviousWorldDeviceState; 01199 01201 enum EventTypes 01202 { 01204 ET_BUTTON_DOWN, 01206 ET_BUTTON_UP, 01208 ET_CALIBRATION_STATE_CHANGED 01209 }; 01213 ConcurrentQueue<EventArgs*> mEventQueue; 01215 ConcurrentQueue<EventArgs*>::HazardPtr* mEventQueueHazardPtr; 01217 ConcurrentQueue<EventArgs*>::HazardPtr* mhtEventQueueHazardPtr; 01219 DeviceListener* mListener; 01220 01222 enum FrameEventTimeType 01223 { 01224 FETT_ANY = 0, 01225 FETT_STARTED = 1, 01226 FETT_ENDED = 2, 01227 FETT_COUNT = 3 01228 }; 01230 double mEventTimes[FETT_COUNT][2]; 01231 01233 FrameListener* mFrameListener; 01237 AtomicScalar<int> mFrameListenerLock; 01238 01239 typedef std::set<ForceEffect*> ForceEffectList; 01241 ForceEffectList mEffectsToStart; 01243 ForceEffectList mEffectsToStop; 01246 ForceEffectList mEffectsToUpdate; 01248 ForceEffectList mhtFadingInEffects; 01251 ForceEffectList mhtSustainingEffects; 01253 ForceEffectList mhtFadingOutEffects; 01255 ForceOutput mhtOutput; 01256 01264 void _fireEvent(EventType type, const EventArgs& evt); 01266 void _fireFrameStarted(void); 01268 void _fireFrameEnded(void); 01274 virtual void clearEventTimes(void); 01276 double calculateEventTime(double currentTime, FrameEventTimeType type); 01278 void _fireFrameStarted(FrameEvent& evt); 01280 void _fireFrameEnded(FrameEvent& evt); 01281 01287 void updateTouchWorkspaceMapping(void); 01289 void updateWorldWorkspaceCorners(void); 01290 01292 virtual void disableImpl(void) = 0; 01300 void renderCallbackImpl(void); 01301 01303 void updateStats(double currentTime); 01305 void updateStates(void); 01307 virtual void obtainStateValues(double timeElapsed) = 0; 01308 /* 01309 Checks if the state, e.g. pressed or released, of a grip button has 01310 changed and adds event to queue in the case of change of button state. 01311 @remarks 01312 Used in the haptic thread. 01313 */ 01314 void checkButtonState(int oldButtons, int newButtons, DeviceButton button); 01322 void renderEffects(double currentTime); 01323 01325 void synchroniseMatricesCallbackImpl(void); 01327 void synchroniseEffectsCallbackImpl(void); 01328 01330 static SchedulerCallbackCode statisticsResetCallback(void* params); 01335 static SchedulerCallbackCode synchroniseStatisticsCallback(void* params); 01340 static SchedulerCallbackCode synchroniseStatesCallback(void* params); 01345 static SchedulerCallbackCode synchroniseMatricesCallback(void* params); 01350 static SchedulerCallbackCode updateCallback(void* params); 01355 static SchedulerCallbackCode removeEffectImmediateCallback(void* params); 01356 }; 01357 01358 } 01359 01360 #endif
Last modified Tue Jan 6 22:31:25 2009