OgreHapticsDevice.h

Go to the documentation of this file.
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