Added new osgGA - GUI Adapter library submitted by Neil Salter. This will
replace the current GUI adapter code inside osgUtil.
This commit is contained in:
@@ -10,6 +10,7 @@ SRC_DIRS = \
|
||||
osg\
|
||||
osgUtil\
|
||||
osgDB\
|
||||
osgGA\
|
||||
osgGLUT\
|
||||
osgPlugins\
|
||||
osgText\
|
||||
|
||||
@@ -30,6 +30,24 @@ Package=<4>
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Core osgGA"=".\osgGA\osgGA.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osg
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgUtil
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Core osgGLUT"=".\osgGLUT\osgGLUT.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
@@ -45,6 +63,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgUtil
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
}}}
|
||||
@@ -99,6 +120,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -123,6 +147,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -168,6 +195,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -192,6 +222,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -216,6 +249,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -240,6 +276,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -267,6 +306,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -291,6 +333,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -315,6 +360,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -339,6 +387,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -363,6 +414,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -390,6 +444,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -429,6 +486,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
@@ -453,6 +513,9 @@ Package=<4>
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGLUT
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
|
||||
201
VisualStudio/osgGA/osgGA.dsp
Executable file
201
VisualStudio/osgGA/osgGA.dsp
Executable file
@@ -0,0 +1,201 @@
|
||||
# Microsoft Developer Studio Project File - Name="Core osgGA" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=Core osgGA - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "osgGA.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "osgGA.mak" CFG="Core osgGA - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Core osgGA - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "Core osgGA - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Core osgGA - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "../../lib"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "../../lib"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../include" /D "NDEBUG" /D "_MBCS" /D "_USRDLL" /D "OSGUTIL_LIBRARY" /D "WIN32" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 glu32.lib opengl32.lib /nologo /dll /pdb:none /machine:I386 /out:"../../bin/osgGA.dll" /libpath:"../../lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "Core osgGA - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "../../lib"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /vmg /vd0 /GR /GX /Zi /Od /I "../../include" /D "OSGUTIL_LIBRARY" /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /D "OSG_USE_MEMORY_MANAGER" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 glu32.lib opengl32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/osgGAd.dll" /pdbtype:sept /libpath:"../../lib"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Core osgGA - Win32 Release"
|
||||
# Name "Core osgGA - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\CameraManipulator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\DriveManipulator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\FlightManipulator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\GUIEventHandler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\GUIEventHandlerVisitor.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\KeySwitchCameraManipulator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\SetSceneViewVisitor.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\StateSetManipulator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\TrackballManipulator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osgGA\Version.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter ";h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\CameraManipulator
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\DriveManipulator
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\FlightManipulator
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\GUIActionAdapter
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\GUIEventAdapter
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\GUIEventHandler
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\GUIEventHandlerVisitor
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\KeySwitchCameraManipulator
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\SetSceneViewVisitor
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\StateSetManipulator
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\TrackballManipulator
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\Export
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\osgGA\Version
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
\c
|
||||
70
include/osgGA/CameraManipulator
Normal file
70
include/osgGA/CameraManipulator
Normal file
@@ -0,0 +1,70 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_CAMERAMANIPULATOR
|
||||
#define OSGGA_CAMERAMANIPULATOR 1
|
||||
|
||||
#include <osg/Camera>
|
||||
#include <osg/Node>
|
||||
|
||||
#include <osgGA/Export>
|
||||
#include <osgGA/GUIEventHandler>
|
||||
#include <osgGA/GUIEventAdapter>
|
||||
#include <osgGA/GUIActionAdapter>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
class OSGGA_EXPORT CameraManipulator : public GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
CameraManipulator();
|
||||
virtual ~CameraManipulator();
|
||||
|
||||
/** attach a camera to the manipulator to be used for specifying view.*/
|
||||
virtual void setCamera(osg::Camera*);
|
||||
|
||||
/** get the attached camera.*/
|
||||
virtual const osg::Camera * getCamera() const;
|
||||
|
||||
/** get the attached camera.*/
|
||||
virtual osg::Camera * getCamera();
|
||||
|
||||
/** Attach a node to the manipulator.
|
||||
Automatically detaches previously attached node.
|
||||
setNode(NULL) detaches previously nodes.
|
||||
Is ignored by manipulators which do not require a reference model.*/
|
||||
virtual void setNode(osg::Node*) {}
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual const osg::Node* getNode() const { return NULL; }
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual osg::Node* getNode() { return NULL; }
|
||||
|
||||
/** Move the camera to the default position.
|
||||
May be ignored by manipulators if home functionality is not appropriate.*/
|
||||
virtual void home(const GUIEventAdapter& ,GUIActionAdapter&) {}
|
||||
|
||||
/** Start/restart the manipulator.*/
|
||||
virtual void init(const GUIEventAdapter& ,GUIActionAdapter&) {}
|
||||
|
||||
/** Handle events, return true if handled, false otherwise.*/
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
/** Handle visitations */
|
||||
virtual void accept(GUIEventHandlerVisitor& v) { v.visit(*this); }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Reference pointer to a camera
|
||||
osg::ref_ptr<osg::Camera> _camera;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
75
include/osgGA/DriveManipulator
Normal file
75
include/osgGA/DriveManipulator
Normal file
@@ -0,0 +1,75 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_DRIVEMANIPULATOR
|
||||
#define OSGGA_DRIVEMANIPULATOR 1
|
||||
|
||||
#include <osgGA/CameraManipulator>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
class OSGGA_EXPORT DriveManipulator : public CameraManipulator
|
||||
{
|
||||
public:
|
||||
|
||||
DriveManipulator();
|
||||
virtual ~DriveManipulator();
|
||||
|
||||
/** Attach a node to the manipulator.
|
||||
Automatically detaches previously attached node.
|
||||
setNode(NULL) detaches previously nodes.
|
||||
Is ignored by manipulators which do not require a reference model.*/
|
||||
virtual void setNode(osg::Node*);
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual const osg::Node* getNode() const;
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual osg::Node* getNode();
|
||||
|
||||
/** Move the camera to the default position.
|
||||
May be ignored by manipulators if home functionality is not appropriate.*/
|
||||
virtual void home(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
/** Start/restart the manipulator.*/
|
||||
virtual void init(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
/** handle events, return true if handled, false otherwise.*/
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
private:
|
||||
|
||||
/** Reset the internal GUIEvent stack.*/
|
||||
void flushMouseEventStack();
|
||||
/** Add the current mouse GUIEvent to internal stack.*/
|
||||
void addMouseEvent(const GUIEventAdapter& ea);
|
||||
|
||||
/** For the give mouse movement calculate the movement of the camera.
|
||||
Return true is camera has moved and a redraw is required.*/
|
||||
bool calcMovement();
|
||||
|
||||
// Internal event stack comprising last three mouse events.
|
||||
osg::ref_ptr<const GUIEventAdapter> _ga_t1;
|
||||
osg::ref_ptr<const GUIEventAdapter> _ga_t0;
|
||||
|
||||
osg::ref_ptr<osg::Node> _node;
|
||||
|
||||
float _modelScale;
|
||||
float _velocity;
|
||||
float _height;
|
||||
float _buffer;
|
||||
|
||||
enum SpeedControlMode {
|
||||
USE_MOUSE_Y_FOR_SPEED,
|
||||
USE_MOUSE_BUTTONS_FOR_SPEED
|
||||
};
|
||||
|
||||
SpeedControlMode _speedMode;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
53
include/osgGA/Export
Normal file
53
include/osgGA/Export
Normal file
@@ -0,0 +1,53 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
// The following symbol has a underscore suffix for compatibility.
|
||||
#ifndef OSGGA_EXPORT_
|
||||
#define OSGGA_EXPORT_ 1
|
||||
|
||||
#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW32__))
|
||||
#pragma warning( disable : 4244 )
|
||||
#pragma warning( disable : 4251 )
|
||||
#pragma warning( disable : 4275 )
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
|
||||
# ifdef OSGGA_LIBRARY
|
||||
# define OSGGA_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define OSGGA_EXPORT __declspec(dllimport)
|
||||
#endif /* OSGUTIL_LIBRARY */
|
||||
#else
|
||||
#define OSGGA_EXPORT
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
||||
\namespace osgGA
|
||||
|
||||
The 'GA' in osgGA stands for 'GUI Abstraction'.
|
||||
|
||||
As the OpenSceneGraph is a cross-platform, window system-agnostic class library,
|
||||
it has no direct ties to any given windowing environment. Viewers, however, must at
|
||||
some level interact with a window system - where Window system may refer to a windowing
|
||||
API, e.g. GLUT, Qt, FLTK, MFC, ...
|
||||
|
||||
There is much commonality in the implementation of Viewers for varying windowing
|
||||
environments. E.g. most Viewers will update a Camera position in response to a mouse
|
||||
event, and may request that a timer be started as a result of a model being 'spun'.
|
||||
|
||||
The purpose of the osgGA namespace is to centralise the common areas of this
|
||||
functionality. With this centralised, the viewer writer needs only write a
|
||||
GUIEventAdapter, a GUIActionAdapter, and assemble a collection of GUIEventHandlers
|
||||
as appropriate for the viewer.
|
||||
|
||||
Events from the windowing environment are adpated, and then fed into the GUIEventHandlers.
|
||||
The GUIEventHandlers analyse and take action, and make requests of the windowing
|
||||
environemnt via the GUIActionAdapter. The viewer writer should honour these requests.
|
||||
|
||||
*/
|
||||
76
include/osgGA/FlightManipulator
Normal file
76
include/osgGA/FlightManipulator
Normal file
@@ -0,0 +1,76 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_FLIGHTMANIPULATOR
|
||||
#define OSGGA_FLIGHTMANIPULATOR 1
|
||||
|
||||
#include <osgGA/CameraManipulator>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
class OSGGA_EXPORT FlightManipulator : public CameraManipulator
|
||||
{
|
||||
public:
|
||||
|
||||
FlightManipulator();
|
||||
virtual ~FlightManipulator();
|
||||
|
||||
/** Attach a node to the manipulator.
|
||||
Automatically detaches previously attached node.
|
||||
setNode(NULL) detaches previously nodes.
|
||||
Is ignored by manipulators which do not require a reference model.*/
|
||||
virtual void setNode(osg::Node*);
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual const osg::Node* getNode() const;
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual osg::Node* getNode();
|
||||
|
||||
/** Move the camera to the default position.
|
||||
May be ignored by manipulators if home functionality is not appropriate.*/
|
||||
virtual void home(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
/** Start/restart the manipulator.*/
|
||||
virtual void init(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
/** handle events, return true if handled, false otherwise.*/
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
enum YawControlMode {
|
||||
YAW_AUTOMATICALLY_WHEN_BANKED,
|
||||
NO_AUTOMATIC_YAW
|
||||
};
|
||||
|
||||
/** Set the yaw control between no yaw and yawing when banked.*/
|
||||
void setYawControlMode(YawControlMode ycm) { _yawMode = ycm; }
|
||||
|
||||
private:
|
||||
|
||||
/** Reset the internal GUIEvent stack.*/
|
||||
void flushMouseEventStack();
|
||||
/** Add the current mouse GUIEvent to internal stack.*/
|
||||
void addMouseEvent(const GUIEventAdapter& ea);
|
||||
|
||||
/** For the give mouse movement calculate the movement of the camera.
|
||||
Return true is camera has moved and a redraw is required.*/
|
||||
bool calcMovement();
|
||||
|
||||
// Internal event stack comprising last three mouse events.
|
||||
osg::ref_ptr<const GUIEventAdapter> _ga_t1;
|
||||
osg::ref_ptr<const GUIEventAdapter> _ga_t0;
|
||||
|
||||
osg::ref_ptr<osg::Node> _node;
|
||||
|
||||
float _modelScale;
|
||||
float _velocity;
|
||||
|
||||
YawControlMode _yawMode;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
55
include/osgGA/GUIActionAdapter
Normal file
55
include/osgGA/GUIActionAdapter
Normal file
@@ -0,0 +1,55 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_GUIACTIONADAPTER
|
||||
#define OSGGA_GUIACTIONADAPTER 1
|
||||
|
||||
#include <osgGA/Export>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
|
||||
/** Pure virtual base class for adapting the GUI actions requested by CameraManipulators
|
||||
* into actions which are handled by the GUI toolkit of the users application.
|
||||
*
|
||||
* There are several was of using the ActionAdapter either inheriting it as
|
||||
* done with osgGLUT::Viewer class or passing a simple struct to the camera
|
||||
* manipulator then unpacking the results and working out what to do to respond
|
||||
* to the requests.
|
||||
*
|
||||
* Also there are several ways to run your app and handle the updating of
|
||||
* the window. osgGLUT::Viewer always has a idle callback registered which does a
|
||||
* redraw all the time. osgGLUT::Viewer can safely ignore both requestRedraw() and
|
||||
* requestContinousUpdate() as these are happening all the time anyway.
|
||||
*
|
||||
* Other apps will probably want to respond to the requestRedraw() and
|
||||
* requestContinousUpdate(bool) and again there is more than one way to handle it.
|
||||
* You can override requestRedraw() and implement to call your own window
|
||||
* redraw straight away. Or you can implement so that a flag is set and
|
||||
* then you then respond the flag being set in your own leisure.
|
||||
*
|
||||
* requestContinousUpdate(bool) is for enabling a throw or idle
|
||||
* callback to be requested by the camera manipulator. Again you can respond
|
||||
* to this immediately by registering a idle callback or a timed callback, or
|
||||
* you can delay setting the callback and do at you own leisure.
|
||||
*
|
||||
* requestWarpPointer(int,int) is requesting a respositioning of a mouse pointer
|
||||
* to a specified x,y location on the window. Used by some camera manipulators
|
||||
* to initialize the mouse pointer when mouse position relative to a controls
|
||||
* neutral mouse position is required, i.e when mimicking a aircrafts joystick.
|
||||
*/
|
||||
class GUIActionAdapter
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void requestRedraw() = 0;
|
||||
virtual void requestContinuousUpdate(bool needed=true) = 0;
|
||||
virtual void requestWarpPointer(int x,int y) = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
89
include/osgGA/GUIEventAdapter
Normal file
89
include/osgGA/GUIEventAdapter
Normal file
@@ -0,0 +1,89 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_GUIEVENTADAPTER
|
||||
#define OSGGA_GUIEVENTADAPTER 1
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osgGA/Export>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
|
||||
/** Pure virtual base class for adapting platform specific events into
|
||||
* generic keyboard and mouse events.
|
||||
*
|
||||
* Used as GUI toolkit independent input into the osgUtil::CameraManipualor's.
|
||||
* For an example of how GUIEventAdapter is specialised for a particular GUI
|
||||
* Toolkit see osgGLUT::GLUTEventAdapter.
|
||||
*/
|
||||
class GUIEventAdapter : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
GUIEventAdapter() {}
|
||||
|
||||
|
||||
enum MouseButtonMask {
|
||||
LEFT_MOUSE_BUTTON=1,
|
||||
MIDDLE_MOUSE_BUTTON=2,
|
||||
RIGHT_MOUSE_BUTTON=4
|
||||
};
|
||||
|
||||
enum EventType {
|
||||
PUSH,
|
||||
RELEASE,
|
||||
DRAG,
|
||||
MOVE,
|
||||
KEYBOARD,
|
||||
FRAME,
|
||||
RESIZE,
|
||||
NONE
|
||||
};
|
||||
|
||||
/** Get the EventType of the GUI event.*/
|
||||
virtual EventType getEventType() const = 0;
|
||||
|
||||
/** key pressed, return -1 if inappropriate for this event. */
|
||||
virtual int getKey() const = 0;
|
||||
|
||||
/** button pressed/released, return -1 if inappropriate for this event.*/
|
||||
virtual int getButton() const = 0;
|
||||
|
||||
/** window minimum x. */
|
||||
virtual int getXmin() const = 0;
|
||||
|
||||
/** window maximum x. */
|
||||
virtual int getXmax() const = 0;
|
||||
|
||||
/** window minimum y. */
|
||||
virtual int getYmin() const = 0;
|
||||
|
||||
/** window maximum y. */
|
||||
virtual int getYmax() const = 0;
|
||||
|
||||
/** current mouse x position.*/
|
||||
virtual int getX() const = 0;
|
||||
|
||||
/** current mouse y position.*/
|
||||
virtual int getY() const = 0;
|
||||
|
||||
/** current mouse button state */
|
||||
virtual unsigned int getButtonMask() const = 0;
|
||||
|
||||
/** time in seconds of event. */
|
||||
virtual float time() const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** Force users to create on heap, so that multiple referencing is safe.*/
|
||||
virtual ~GUIEventAdapter() {}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
123
include/osgGA/GUIEventHandler
Normal file
123
include/osgGA/GUIEventHandler
Normal file
@@ -0,0 +1,123 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_GUIEVENTHANDLER
|
||||
#define OSGGA_GUIEVENTHANDLER 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <osg/Referenced>
|
||||
|
||||
#include <osgGA/Export>
|
||||
#include <osgGA/GUIEventAdapter>
|
||||
#include <osgGA/GUIActionAdapter>
|
||||
#include <osgGA/GUIEventHandlerVisitor>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
class CompositeGUIEventHandler;
|
||||
|
||||
/**
|
||||
|
||||
GUIEventHandler provides a basic interface for any class which wants to handle
|
||||
a GUI Events.
|
||||
|
||||
The GUIEvent is supplied by a GUIEventAdapter. Feedback resulting from the
|
||||
handle method is supplied by a GUIActionAdapter, which allows the GUIEventHandler
|
||||
to ask the GUI to take some action in response to an incoming event.
|
||||
|
||||
For example, consider a Trackball Viewer class which takes mouse events and
|
||||
manipulates a scene camera in response. The Trackball Viewer is a GUIEventHandler,
|
||||
and receives the events via the handle method. If the user 'throws' the model,
|
||||
the Trackball Viewer class can detect this via the incoming events, and
|
||||
request that the GUI set up a timer callback to continually redraw the view.
|
||||
This request is made via the GUIActionAdapter class.
|
||||
|
||||
*/
|
||||
|
||||
class OSGGA_EXPORT GUIEventHandler : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
/** Handle events, return true if handled, false otherwise.*/
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us)=0;
|
||||
|
||||
/** Is this const GUIEventHandler a composite? */
|
||||
virtual const CompositeGUIEventHandler* getComposite() const { return 0; }
|
||||
|
||||
/** Is this non-const GUIEventHandler a composite? */
|
||||
virtual CompositeGUIEventHandler* getComposite() { return 0; }
|
||||
|
||||
/** Accept visits from GUIEventHandler visitors */
|
||||
virtual void accept(GUIEventHandlerVisitor&) = 0;
|
||||
//virtual void accept(GUIEventHandlerVisitor&) { }
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
CompositeGUIEventHandler allows GUIEventHandlers to be composed into hierarchies.
|
||||
*/
|
||||
|
||||
class OSGGA_EXPORT CompositeGUIEventHandler : public GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::vector< osg::ref_ptr<GUIEventHandler> > ChildList;
|
||||
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& aa);
|
||||
|
||||
virtual const CompositeGUIEventHandler* getComposite() const { return this; }
|
||||
|
||||
virtual CompositeGUIEventHandler* getComposite() { return this; }
|
||||
|
||||
virtual void accept(GUIEventHandlerVisitor& v) { v.visit(*this); }
|
||||
|
||||
|
||||
|
||||
/* Composite-specific methods below */
|
||||
|
||||
virtual bool addChild(GUIEventHandler *geh);
|
||||
|
||||
virtual bool removeChild(GUIEventHandler *geh);
|
||||
|
||||
const int getNumChildren() const { return _children.size(); }
|
||||
|
||||
GUIEventHandler *getChild( int i) { return _children[i].get(); }
|
||||
|
||||
const GUIEventHandler *getChild( int i ) const { return _children[i].get(); }
|
||||
|
||||
bool containsNode( const GUIEventHandler* node ) const
|
||||
{
|
||||
|
||||
for (ChildList::const_iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->get()==node) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ChildList::iterator findChild( const GUIEventHandler* node )
|
||||
{
|
||||
for (ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->get()==node) return itr;
|
||||
}
|
||||
return _children.end();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ChildList _children;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
55
include/osgGA/GUIEventHandlerVisitor
Normal file
55
include/osgGA/GUIEventHandlerVisitor
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef OSGGA_GUIEVENTHANDLERVISITOR
|
||||
#define OSGGA_GUIEVENTHANDLERVISITOR 1
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osgGA/Export>
|
||||
#include <osgGA/GUIEventAdapter>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
// Some forward declarations
|
||||
class GUIActionAdapter;
|
||||
class CompositeGUIEventHandler;
|
||||
class CameraManipulator;
|
||||
class StateSetManipulator;
|
||||
|
||||
/** Base class primarily for visiting GUIEventHandlers.
|
||||
|
||||
A Default Visitor, (Might want to make it an Extrinsic Visitor at some point).
|
||||
By default, it does nothing to the things it visits. Sub classes of this Visitor
|
||||
need only override visit operations for the types of object they're interested in.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class OSGGA_EXPORT GUIEventHandlerVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void visit(CompositeGUIEventHandler&);
|
||||
virtual void visit(CameraManipulator&) {};
|
||||
virtual void visit(StateSetManipulator&) {};
|
||||
|
||||
// Accessors
|
||||
|
||||
/** Get the GUI EventAdapter associated with this GUIEventHandlerVisitor */
|
||||
const GUIEventAdapter *getGUIEventAdapter() { return _gea.get(); }
|
||||
|
||||
/** Get the GUI Action Adapter associated with this GEH Visitor */
|
||||
GUIActionAdapter *getGUIActionAdapter() { return _gaa; }
|
||||
|
||||
protected:
|
||||
|
||||
GUIEventHandlerVisitor(GUIEventAdapter* in, GUIActionAdapter* out):_gea(in),_gaa(out) {}
|
||||
virtual ~GUIEventHandlerVisitor() {}
|
||||
|
||||
private:
|
||||
|
||||
osg::ref_ptr<GUIEventAdapter> _gea;
|
||||
GUIActionAdapter* _gaa; // Just a pointer. NOT owned by this object.
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
70
include/osgGA/KeySwitchCameraManipulator
Normal file
70
include/osgGA/KeySwitchCameraManipulator
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef OSGUTIL_KEYSWITCCAMERAMANIPULATORHER
|
||||
#define OSGUTIL_KEYSWITCHCAMERAMANIPULATORER 1
|
||||
|
||||
#include <osgGA/Export>
|
||||
#include <osgGA/CameraManipulator>
|
||||
#include <osgGA/GUIEventHandler>
|
||||
#include <osgGA/GUIEventHandlerVisitor>
|
||||
//#include <osgUtil/CallbackList>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
class GUIEventAdapter;
|
||||
class GUIActionAdapter;
|
||||
|
||||
class OSGGA_EXPORT KeySwitchCameraManipulator : public CameraManipulator
|
||||
{
|
||||
public:
|
||||
|
||||
// Local methods
|
||||
|
||||
void addCameraManipulator(int key, std::string name, CameraManipulator *cm);
|
||||
|
||||
//typedef void (* Callback)(KeySwitchCameraManipulator *);
|
||||
|
||||
// class Callback: public osgUtil::CallbackList<KeySwitchCameraManipulator>::Callback {
|
||||
// public:
|
||||
// virtual ~Callback() {};
|
||||
// virtual void operator()(KeySwitchCameraManipulator *) = 0;
|
||||
// };
|
||||
//
|
||||
// void addCallback(Callback*);
|
||||
//
|
||||
// void removeCallback(Callback*);
|
||||
|
||||
// Overrides from CameraManipulator...
|
||||
|
||||
virtual void setCamera(osg::Camera* c) { _current->setCamera(c); }
|
||||
|
||||
virtual const osg::Camera * getCamera() const { return _current->getCamera(); }
|
||||
|
||||
virtual osg::Camera * getCamera() { return _current->getCamera(); }
|
||||
|
||||
virtual void setNode(osg::Node* n) { _current->setNode(n); }
|
||||
|
||||
virtual const osg::Node* getNode() const { return _current->getNode(); }
|
||||
|
||||
virtual osg::Node* getNode() { return _current->getNode(); }
|
||||
|
||||
virtual void home(const GUIEventAdapter& ee,GUIActionAdapter& aa) { _current->home(ee,aa); }
|
||||
|
||||
virtual void init(const GUIEventAdapter& ee,GUIActionAdapter& aa) { _current->init(ee,aa); }
|
||||
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::pair<std::string, osg::ref_ptr<CameraManipulator> > NamedManipulator;
|
||||
typedef std::map<int, NamedManipulator> KeyManipMap;
|
||||
KeyManipMap _manips;
|
||||
|
||||
osg::ref_ptr<CameraManipulator> _current;
|
||||
|
||||
// Callbacks
|
||||
//CallbackList<KeySwitchCameraManipulator> _cameraManipChangeCallbacks;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
40
include/osgGA/SetSceneViewVisitor
Normal file
40
include/osgGA/SetSceneViewVisitor
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef OSGGA_SETSCENEVIEWGEHVISITOR
|
||||
#define OSGGA_SETSCENEVIEWGEHVISITOR 1
|
||||
|
||||
#include <osgGA/GUIEventHandlerVisitor>
|
||||
#include <osgUtil/SceneView>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
// Some forward declarations
|
||||
class GUIEventHandler;
|
||||
class CameraManipulator;
|
||||
|
||||
/** SetSceneViewGUIEventHandlerVisitor which visits various types of GUIEventHandler and
|
||||
sets them up appropriately, given a new scene view.
|
||||
. */
|
||||
|
||||
class OSGGA_EXPORT SetSceneViewVisitor: public GUIEventHandlerVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
SetSceneViewVisitor(GUIEventAdapter* in,
|
||||
GUIActionAdapter* out,
|
||||
osgUtil::SceneView* sv):
|
||||
GUIEventHandlerVisitor(in,out),
|
||||
_sceneView(sv) {}
|
||||
|
||||
virtual ~SetSceneViewVisitor() {}
|
||||
|
||||
virtual void visit(CameraManipulator& cm);
|
||||
virtual void visit(StateSetManipulator& cm);
|
||||
|
||||
private:
|
||||
|
||||
osg::ref_ptr<osgUtil::SceneView> _sceneView;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
51
include/osgGA/StateSetManipulator
Normal file
51
include/osgGA/StateSetManipulator
Normal file
@@ -0,0 +1,51 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_GEOSTATE_MANIPULATOR
|
||||
#define OSGGA_GEOSTATE_MANIPULATOR 1
|
||||
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include <osgGA/Export>
|
||||
#include <osgGA/GUIEventAdapter>
|
||||
#include <osgGA/GUIActionAdapter>
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
class OSGGA_EXPORT StateSetManipulator : public GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
StateSetManipulator();
|
||||
virtual ~StateSetManipulator();
|
||||
|
||||
/** attach a geostate to the manipulator to be used for specifying view.*/
|
||||
virtual void setStateSet(osg::StateSet*);
|
||||
|
||||
/** get the attached a geostate.*/
|
||||
virtual osg::StateSet * getStateSet();
|
||||
|
||||
/** get the attached a geostate.*/
|
||||
virtual const osg::StateSet * getStateSet() const;
|
||||
|
||||
/** Handle events, return true if handled, false otherwise.*/
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
/** Handle visitations */
|
||||
virtual void accept(GUIEventHandlerVisitor&);
|
||||
|
||||
protected:
|
||||
|
||||
// Reference pointer to a geostate
|
||||
osg::ref_ptr<osg::StateSet> _drawState;
|
||||
|
||||
bool _backface;
|
||||
bool _lighting;
|
||||
bool _texture;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
77
include/osgGA/TrackballManipulator
Normal file
77
include/osgGA/TrackballManipulator
Normal file
@@ -0,0 +1,77 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_TRACKBALLMANIPULATOR
|
||||
#define OSGGA_TRACKBALLMANIPULATOR 1
|
||||
|
||||
#include <osgGA/CameraManipulator>
|
||||
|
||||
namespace osgGA{
|
||||
|
||||
class OSGGA_EXPORT TrackballManipulator : public CameraManipulator
|
||||
{
|
||||
public:
|
||||
|
||||
TrackballManipulator();
|
||||
virtual ~TrackballManipulator();
|
||||
|
||||
/** Attach a node to the manipulator.
|
||||
Automatically detaches previously attached node.
|
||||
setNode(NULL) detaches previously nodes.
|
||||
Is ignored by manipulators which do not require a reference model.*/
|
||||
virtual void setNode(osg::Node*);
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual const osg::Node* getNode() const;
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual osg::Node* getNode();
|
||||
|
||||
/** Move the camera to the default position.
|
||||
May be ignored by manipulators if home functionality is not appropriate.*/
|
||||
virtual void home(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
/** Start/restart the manipulator.*/
|
||||
virtual void init(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
|
||||
/** handle events, return true if handled, false otherwise.*/
|
||||
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
|
||||
|
||||
private:
|
||||
|
||||
/** Reset the internal GUIEvent stack.*/
|
||||
void flushMouseEventStack();
|
||||
/** Add the current mouse GUIEvent to internal stack.*/
|
||||
void addMouseEvent(const GUIEventAdapter& ea);
|
||||
|
||||
/** For the give mouse movement calculate the movement of the camera.
|
||||
Return true is camera has moved and a redraw is required.*/
|
||||
bool calcMovement();
|
||||
|
||||
void trackball(osg::Vec3& axis,float& angle, float p1x, float p1y, float p2x, float p2y);
|
||||
float tb_project_to_sphere(float r, float x, float y);
|
||||
|
||||
|
||||
/** Check the speed at which the mouse is moving.
|
||||
If speed is below a threshold then return false, otherwise return true.*/
|
||||
bool isMouseMoving();
|
||||
|
||||
// Internal event stack comprising last three mouse events.
|
||||
osg::ref_ptr<const GUIEventAdapter> _ga_t1;
|
||||
osg::ref_ptr<const GUIEventAdapter> _ga_t0;
|
||||
|
||||
osg::ref_ptr<osg::Node> _node;
|
||||
|
||||
float _modelScale;
|
||||
float _minimumZoomScale;
|
||||
|
||||
bool _thrown;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
39
include/osgGA/Version
Normal file
39
include/osgGA/Version
Normal file
@@ -0,0 +1,39 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSGGA_VERSION
|
||||
#define OSGGA_VERSION 1
|
||||
|
||||
#include <osgGA/Export>
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
* getVersion_osgGA() returns the library version number.
|
||||
* Numbering convention : osg_src-0.8-31 will return 0.8.31 from getVersion_osgGA.
|
||||
*
|
||||
* This C function can be also used to check for the existence of the OpenSceneGraph
|
||||
* library using autoconf and its m4 macro AC_CHECK_LIB.
|
||||
*
|
||||
* Here is the code to add to your configure.in:
|
||||
\verbatim
|
||||
#
|
||||
# Check for the OpenSceneGraph (OSG) utility library
|
||||
#
|
||||
AC_CHECK_LIB(osg, osgGAGetVersion, ,
|
||||
[AC_MSG_ERROR(OpenSceneGraph utility library not found. See http://www.openscenegraph.org)],)
|
||||
\endverbatim
|
||||
*/
|
||||
extern OSGGA_EXPORT const char* osgGAGetVersion();
|
||||
|
||||
/**
|
||||
* getLibraryName_osgGA() returns the library name in human friendly form.
|
||||
*/
|
||||
extern OSGGA_EXPORT const char* osgGAGetLibraryName();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
37
src/osgGA/CameraManipulator.cpp
Normal file
37
src/osgGA/CameraManipulator.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <osg/GL>
|
||||
#include <osg/Matrix>
|
||||
#include <osgGA/CameraManipulator>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgGA;
|
||||
|
||||
CameraManipulator::CameraManipulator(): _camera(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CameraManipulator::~CameraManipulator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CameraManipulator::setCamera(Camera *camera)
|
||||
{
|
||||
_camera=camera;
|
||||
}
|
||||
|
||||
|
||||
const Camera *CameraManipulator::getCamera() const
|
||||
{
|
||||
return _camera.get();
|
||||
}
|
||||
|
||||
Camera *CameraManipulator::getCamera()
|
||||
{
|
||||
return _camera.get();
|
||||
}
|
||||
|
||||
bool CameraManipulator::handle(const GUIEventAdapter&,GUIActionAdapter&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
565
src/osgGA/DriveManipulator.cpp
Normal file
565
src/osgGA/DriveManipulator.cpp
Normal file
@@ -0,0 +1,565 @@
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#include <osgGA/DriveManipulator>
|
||||
#include <osgUtil/IntersectVisitor>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgGA;
|
||||
|
||||
DriveManipulator::DriveManipulator()
|
||||
{
|
||||
_modelScale = 0.01f;
|
||||
_velocity = 0.0f;
|
||||
//_speedMode = USE_MOUSE_Y_FOR_SPEED;
|
||||
_speedMode = USE_MOUSE_BUTTONS_FOR_SPEED;
|
||||
}
|
||||
|
||||
|
||||
DriveManipulator::~DriveManipulator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DriveManipulator::setNode(osg::Node* node)
|
||||
{
|
||||
_node = node;
|
||||
if (_node.get())
|
||||
{
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
_modelScale = boundingSphere._radius;
|
||||
_height = sqrtf(_modelScale)*0.03f;
|
||||
_buffer = sqrtf(_modelScale)*0.05f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const osg::Node* DriveManipulator::getNode() const
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
|
||||
osg::Node* DriveManipulator::getNode()
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
void DriveManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
|
||||
if(_node.get() && _camera.get())
|
||||
{
|
||||
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
|
||||
osg::Vec3 ep = boundingSphere._center;
|
||||
osg::Vec3 bp = ep;
|
||||
ep.z() -= _modelScale*0.0001f;
|
||||
bp.z() -= _modelScale;
|
||||
|
||||
// check to see if any obstruction in front.
|
||||
osgUtil::IntersectVisitor iv;
|
||||
|
||||
bool cameraSet = false;
|
||||
|
||||
osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment;
|
||||
segDown->set(ep,bp);
|
||||
iv.addLineSegment(segDown.get());
|
||||
|
||||
_node->accept(iv);
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get());
|
||||
if (!hitList.empty())
|
||||
{
|
||||
// notify(INFO) << "Hit terrain ok"<< std::endl;
|
||||
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
|
||||
osg::Vec3 np = hitList.front().getWorldIntersectNormal();
|
||||
|
||||
osg::Vec3 uv;
|
||||
if (np.z()>0.0f) uv = np;
|
||||
else uv = -np;
|
||||
|
||||
float lookDistance = _modelScale*0.1f;
|
||||
|
||||
ep = ip;
|
||||
ep.z() += _height;
|
||||
osg::Vec3 lv = uv^osg::Vec3(1.0f,0.0f,0.0f);
|
||||
osg::Vec3 cp = ep+lv*lookDistance;
|
||||
|
||||
_camera->setLookAt(ep,cp,uv);
|
||||
|
||||
cameraSet = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!cameraSet)
|
||||
{
|
||||
bp = ep;
|
||||
bp.z() += _modelScale;
|
||||
|
||||
osg::ref_ptr<osg::LineSegment> segUp = new osg::LineSegment;
|
||||
segUp->set(ep,bp);
|
||||
iv.addLineSegment(segUp.get());
|
||||
|
||||
_node->accept(iv);
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segUp.get());
|
||||
if (!hitList.empty())
|
||||
{
|
||||
// notify(INFO) << "Hit terrain ok"<< std::endl;
|
||||
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
|
||||
osg::Vec3 np = hitList.front().getWorldIntersectNormal();
|
||||
|
||||
osg::Vec3 uv;
|
||||
if (np.z()>0.0f) uv = np;
|
||||
else uv = -np;
|
||||
|
||||
float lookDistance = _modelScale*0.1f;
|
||||
|
||||
ep = ip;
|
||||
ep.z() += _height;
|
||||
osg::Vec3 lv = uv^osg::Vec3(1.0f,0.0f,0.0f);
|
||||
osg::Vec3 cp = ep+lv*lookDistance;
|
||||
|
||||
_camera->setLookAt(ep,cp,uv);
|
||||
|
||||
cameraSet = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!cameraSet)
|
||||
{
|
||||
// eye
|
||||
_camera->setLookAt(boundingSphere._center+osg::Vec3( 0.0,-2.0f * boundingSphere._radius,0.0f),
|
||||
// look
|
||||
boundingSphere._center,
|
||||
// up
|
||||
osg::Vec3(0.0f,0.0f,1.0f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_velocity = 0.0f;
|
||||
|
||||
us.requestRedraw();
|
||||
|
||||
us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2,(ea.getYmin()+ea.getYmax())/2);
|
||||
|
||||
flushMouseEventStack();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DriveManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
flushMouseEventStack();
|
||||
|
||||
us.requestContinuousUpdate(false);
|
||||
|
||||
_velocity = 0.0f;
|
||||
|
||||
osg::Vec3 ep = _camera->getEyePoint();
|
||||
osg::Vec3 sv = _camera->getSideVector();
|
||||
osg::Vec3 bp = ep;
|
||||
bp.z() -= _modelScale;
|
||||
|
||||
// check to see if any obstruction in front.
|
||||
osgUtil::IntersectVisitor iv;
|
||||
|
||||
bool cameraSet = false;
|
||||
|
||||
osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment;
|
||||
segDown->set(ep,bp);
|
||||
iv.addLineSegment(segDown.get());
|
||||
|
||||
_node->accept(iv);
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get());
|
||||
if (!hitList.empty())
|
||||
{
|
||||
// notify(INFO) << "Hit terrain ok"<< std::endl;
|
||||
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
|
||||
osg::Vec3 np = hitList.front().getWorldIntersectNormal();
|
||||
|
||||
osg::Vec3 uv;
|
||||
if (np.z()>0.0f) uv = np;
|
||||
else uv = -np;
|
||||
|
||||
float lookDistance = _modelScale*0.1f;
|
||||
|
||||
ep = ip+uv*_height;
|
||||
osg::Vec3 lv = uv^sv;
|
||||
osg::Vec3 lp = ep+lv*lookDistance;
|
||||
|
||||
_camera->setLookAt(ep,lp,uv);
|
||||
_camera->ensureOrthogonalUpVector();
|
||||
|
||||
cameraSet = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!cameraSet)
|
||||
{
|
||||
bp = ep;
|
||||
bp.z() += _modelScale;
|
||||
|
||||
osg::ref_ptr<osg::LineSegment> segUp = new osg::LineSegment;
|
||||
segUp->set(ep,bp);
|
||||
iv.addLineSegment(segUp.get());
|
||||
|
||||
_node->accept(iv);
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segUp.get());
|
||||
if (!hitList.empty())
|
||||
{
|
||||
// notify(INFO) << "Hit terrain ok"<< std::endl;
|
||||
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
|
||||
osg::Vec3 np = hitList.front().getWorldIntersectNormal();
|
||||
|
||||
osg::Vec3 uv;
|
||||
if (np.z()>0.0f) uv = np;
|
||||
else uv = -np;
|
||||
|
||||
float lookDistance = _modelScale*0.1f;
|
||||
|
||||
ep = ip+uv*_height;
|
||||
osg::Vec3 lv = uv^sv;
|
||||
osg::Vec3 lp = ep+lv*lookDistance;
|
||||
|
||||
_camera->setLookAt(ep,lp,uv);
|
||||
_camera->ensureOrthogonalUpVector();
|
||||
|
||||
cameraSet = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2,(ea.getYmin()+ea.getYmax())/2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool DriveManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
if(!_camera.get()) return false;
|
||||
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(GUIEventAdapter::PUSH):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::RELEASE):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::DRAG):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::MOVE):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::KEYBOARD):
|
||||
{
|
||||
if (ea.getKey()==' ')
|
||||
{
|
||||
flushMouseEventStack();
|
||||
home(ea,us);
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='q')
|
||||
{
|
||||
_speedMode = USE_MOUSE_Y_FOR_SPEED;
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='a')
|
||||
{
|
||||
_speedMode = USE_MOUSE_BUTTONS_FOR_SPEED;
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='+')
|
||||
{
|
||||
_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()*1.25f);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='-')
|
||||
{
|
||||
_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()/1.25f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::FRAME):
|
||||
{
|
||||
addMouseEvent(ea);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::RESIZE):
|
||||
{
|
||||
init(ea,us);
|
||||
us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DriveManipulator::flushMouseEventStack()
|
||||
{
|
||||
_ga_t1 = NULL;
|
||||
_ga_t0 = NULL;
|
||||
}
|
||||
|
||||
|
||||
void DriveManipulator::addMouseEvent(const GUIEventAdapter& ea)
|
||||
{
|
||||
_ga_t1 = _ga_t0;
|
||||
_ga_t0 = &ea;
|
||||
}
|
||||
|
||||
|
||||
bool DriveManipulator::calcMovement()
|
||||
{
|
||||
_camera->setFusionDistanceMode(osg::Camera::PROPORTIONAL_TO_SCREEN_DISTANCE);
|
||||
|
||||
// return if less then two events have been added.
|
||||
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
|
||||
|
||||
float dt = _ga_t0->time()-_ga_t1->time();
|
||||
|
||||
if (dt<0.0f)
|
||||
{
|
||||
notify(WARN) << "warning dt = "<<dt<< std::endl;
|
||||
dt = 0.0f;
|
||||
}
|
||||
|
||||
switch(_speedMode)
|
||||
{
|
||||
case(USE_MOUSE_Y_FOR_SPEED):
|
||||
{
|
||||
float my = (_ga_t0->getYmin()+_ga_t0->getYmax())/2.0f;
|
||||
float dy = _ga_t0->getY()-my;
|
||||
_velocity = -_modelScale*0.0002f*dy;
|
||||
break;
|
||||
}
|
||||
case(USE_MOUSE_BUTTONS_FOR_SPEED):
|
||||
{
|
||||
unsigned int buttonMask = _ga_t1->getButtonMask();
|
||||
if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
|
||||
{
|
||||
// pan model.
|
||||
|
||||
_velocity += dt*_modelScale*0.02f;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
|
||||
buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
|
||||
{
|
||||
|
||||
_velocity = 0.0f;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
|
||||
{
|
||||
|
||||
_velocity -= dt*_modelScale*0.02f;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rotate the camera.
|
||||
osg::Vec3 center = _camera->getEyePoint();
|
||||
osg::Vec3 uv = _camera->getUpVector();
|
||||
|
||||
float mx = (_ga_t0->getXmin()+_ga_t0->getXmax())/2.0f;
|
||||
|
||||
float dx = _ga_t0->getX()-mx;
|
||||
|
||||
float yaw = -inDegrees(dx*0.1f*dt);
|
||||
|
||||
osg::Matrix mat;
|
||||
mat.makeTranslate(-center.x(),-center.y(),-center.z());
|
||||
mat *= Matrix::rotate(yaw,uv.x(),uv.y(),uv.z());
|
||||
mat *= Matrix::translate(center.x(),center.y(),center.z());
|
||||
|
||||
center = _camera->getEyePoint();
|
||||
uv = _camera->getUpVector();
|
||||
|
||||
_camera->transformLookAt(mat);
|
||||
|
||||
// get the new forward (look) vector.
|
||||
osg::Vec3 sv = _camera->getSideVector();
|
||||
osg::Vec3 lv = _camera->getCenterPoint()-_camera->getEyePoint();
|
||||
float lookDistance = lv.length();
|
||||
lv.normalize();
|
||||
|
||||
// movement is big enough the move the eye point along the look vector.
|
||||
if (fabsf(_velocity*dt)>1e-8)
|
||||
{
|
||||
osg::Vec3 ep = _camera->getEyePoint();
|
||||
float distanceToMove = _velocity*dt;
|
||||
|
||||
float signedBuffer;
|
||||
if (distanceToMove>=0.0f) signedBuffer=_buffer;
|
||||
else signedBuffer=-_buffer;
|
||||
|
||||
// check to see if any obstruction in front.
|
||||
osgUtil::IntersectVisitor iv;
|
||||
osg::ref_ptr<osg::LineSegment> segForward = new osg::LineSegment;
|
||||
segForward->set(ep,ep+lv*(signedBuffer+distanceToMove));
|
||||
iv.addLineSegment(segForward.get());
|
||||
|
||||
_node->accept(iv);
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segForward.get());
|
||||
if (!hitList.empty())
|
||||
{
|
||||
// notify(INFO) << "Hit obstruction"<< std::endl;
|
||||
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
|
||||
distanceToMove = (ip-ep).length()-_buffer;
|
||||
_velocity = 0.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check to see if forward point is correct height above terrain.
|
||||
osg::Vec3 fp = ep+lv*distanceToMove;
|
||||
osg::Vec3 lfp = fp-uv*_height*5;
|
||||
|
||||
iv.reset();
|
||||
|
||||
osg::ref_ptr<osg::LineSegment> segNormal = new osg::LineSegment;
|
||||
segNormal->set(fp,lfp);
|
||||
iv.addLineSegment(segNormal.get());
|
||||
|
||||
_node->accept(iv);
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segNormal.get());
|
||||
if (!hitList.empty())
|
||||
{
|
||||
// notify(INFO) << "Hit terrain ok"<< std::endl;
|
||||
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
|
||||
osg::Vec3 np = hitList.front().getWorldIntersectNormal();
|
||||
|
||||
if (uv*np>0.0f) uv = np;
|
||||
else uv = -np;
|
||||
|
||||
ep = ip+uv*_height;
|
||||
lv = uv^sv;
|
||||
osg::Vec3 lp = ep+lv*lookDistance;
|
||||
|
||||
_camera->setLookAt(ep,lp,uv);
|
||||
_camera->ensureOrthogonalUpVector();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// no hit on the terrain found therefore resort to a fall under
|
||||
// under the influence of gravity.
|
||||
osg::Vec3 dp = lfp;
|
||||
dp.z() -= 2*_modelScale;
|
||||
|
||||
iv.reset();
|
||||
|
||||
osg::ref_ptr<osg::LineSegment> segFall = new osg::LineSegment;
|
||||
segFall->set(lfp,dp);
|
||||
iv.addLineSegment(segFall.get());
|
||||
|
||||
_node->accept(iv);
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segFall.get());
|
||||
if (!hitList.empty())
|
||||
{
|
||||
|
||||
notify(INFO) << "Hit terrain on decent ok"<< std::endl;
|
||||
osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
|
||||
osg::Vec3 np = hitList.front().getWorldIntersectNormal();
|
||||
|
||||
if (uv*np>0.0f) uv = np;
|
||||
else uv = -np;
|
||||
|
||||
ep = ip+uv*_height;
|
||||
lv = uv^sv;
|
||||
osg::Vec3 lp = ep+lv*lookDistance;
|
||||
|
||||
_camera->setLookAt(ep,lp,uv);
|
||||
_camera->ensureOrthogonalUpVector();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// no collision with terrain has been found therefore track horizontally.
|
||||
|
||||
lv *= (_velocity*dt);
|
||||
ep += lv;
|
||||
osg::Vec3 lp = _camera->getCenterPoint()+lv;
|
||||
|
||||
_camera->setLookAt(ep,lp,uv);
|
||||
_camera->ensureOrthogonalUpVector();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
245
src/osgGA/FlightManipulator.cpp
Normal file
245
src/osgGA/FlightManipulator.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
#include <osgGA/FlightManipulator>
|
||||
#include <osg/Types>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgGA;
|
||||
|
||||
FlightManipulator::FlightManipulator()
|
||||
{
|
||||
_modelScale = 0.01f;
|
||||
_velocity = 0.0f;
|
||||
_yawMode = YAW_AUTOMATICALLY_WHEN_BANKED;
|
||||
}
|
||||
|
||||
|
||||
FlightManipulator::~FlightManipulator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FlightManipulator::setNode(osg::Node* node)
|
||||
{
|
||||
_node = node;
|
||||
if (_node.get())
|
||||
{
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
_modelScale = boundingSphere._radius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const osg::Node* FlightManipulator::getNode() const
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
osg::Node* FlightManipulator::getNode()
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
void FlightManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
if(_node.get() && _camera.get())
|
||||
{
|
||||
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
|
||||
_camera->setLookAt(
|
||||
boundingSphere._center+osg::Vec3( 0.0,-3.0f * boundingSphere._radius,0.0f),
|
||||
boundingSphere._center,
|
||||
osg::Vec3(0.0f,0.0f,1.0f));
|
||||
|
||||
_velocity = 0.0f;
|
||||
|
||||
us.requestRedraw();
|
||||
|
||||
us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2,(ea.getYmin()+ea.getYmax())/2);
|
||||
|
||||
flushMouseEventStack();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FlightManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
flushMouseEventStack();
|
||||
|
||||
us.requestContinuousUpdate(false);
|
||||
|
||||
_velocity = 0.0f;
|
||||
|
||||
us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2,(ea.getYmin()+ea.getYmax())/2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool FlightManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
if(!_camera.get()) return false;
|
||||
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(GUIEventAdapter::PUSH):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::RELEASE):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::DRAG):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::MOVE):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::KEYBOARD):
|
||||
if (ea.getKey()==' ')
|
||||
{
|
||||
flushMouseEventStack();
|
||||
home(ea,us);
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='+')
|
||||
{
|
||||
_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()*1.25f);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='-')
|
||||
{
|
||||
_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()/1.25f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
case(GUIEventAdapter::FRAME):
|
||||
addMouseEvent(ea);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
|
||||
case(GUIEventAdapter::RESIZE):
|
||||
init(ea,us);
|
||||
us.requestRedraw();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FlightManipulator::flushMouseEventStack()
|
||||
{
|
||||
_ga_t1 = NULL;
|
||||
_ga_t0 = NULL;
|
||||
}
|
||||
|
||||
|
||||
void FlightManipulator::addMouseEvent(const GUIEventAdapter& ea)
|
||||
{
|
||||
_ga_t1 = _ga_t0;
|
||||
_ga_t0 = &ea;
|
||||
}
|
||||
|
||||
|
||||
bool FlightManipulator::calcMovement()
|
||||
{
|
||||
_camera->setFusionDistanceMode(osg::Camera::PROPORTIONAL_TO_SCREEN_DISTANCE);
|
||||
|
||||
// return if less then two events have been added.
|
||||
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
|
||||
|
||||
|
||||
float dt = _ga_t0->time()-_ga_t1->time();
|
||||
|
||||
if (dt<0.0f)
|
||||
{
|
||||
notify(WARN) << "warning dt = "<<dt<< std::endl;
|
||||
dt = 0.0f;
|
||||
}
|
||||
|
||||
unsigned int buttonMask = _ga_t1->getButtonMask();
|
||||
if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
|
||||
{
|
||||
// pan model.
|
||||
|
||||
_velocity += dt*_modelScale*0.05f;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
|
||||
buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
|
||||
{
|
||||
|
||||
_velocity = 0.0f;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
|
||||
{
|
||||
|
||||
_velocity -= dt*_modelScale*0.05f;
|
||||
|
||||
}
|
||||
|
||||
float mx = (_ga_t0->getXmin()+_ga_t0->getXmax())/2.0f;
|
||||
float my = (_ga_t0->getYmin()+_ga_t0->getYmax())/2.0f;
|
||||
|
||||
float dx = _ga_t0->getX()-mx;
|
||||
float dy = _ga_t0->getY()-my;
|
||||
|
||||
osg::Vec3 center = _camera->getEyePoint();
|
||||
osg::Vec3 sv = _camera->getSideVector();
|
||||
osg::Vec3 lv = _camera->getLookVector();
|
||||
|
||||
float pitch = inDegrees(dy*0.15f*dt);
|
||||
float roll = inDegrees(dx*0.1f*dt);
|
||||
|
||||
osg::Matrix mat;
|
||||
mat.makeTranslate(-center);
|
||||
mat *= Matrix::rotate(pitch,sv.x(),sv.y(),sv.z());
|
||||
mat *= Matrix::rotate(roll,lv.x(),lv.y(),lv.z());
|
||||
if (_yawMode==YAW_AUTOMATICALLY_WHEN_BANKED)
|
||||
{
|
||||
float bank = asinf(sv.z());
|
||||
float yaw = inRadians(bank)*dt;
|
||||
mat *= Matrix::rotate(yaw,0.0f,0.0f,1.0f);
|
||||
}
|
||||
|
||||
lv *= (_velocity*dt);
|
||||
|
||||
mat *= Matrix::translate(center+lv);
|
||||
|
||||
_camera->transformLookAt(mat);
|
||||
|
||||
return true;
|
||||
}
|
||||
43
src/osgGA/GUIEventHandler.cpp
Normal file
43
src/osgGA/GUIEventHandler.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
using osgGA::CompositeGUIEventHandler;
|
||||
|
||||
bool CompositeGUIEventHandler::handle(const GUIEventAdapter& ea,GUIActionAdapter& aa)
|
||||
{
|
||||
bool result=false;
|
||||
|
||||
for (ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
result |= (*itr)->handle(ea,aa);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool CompositeGUIEventHandler::addChild(GUIEventHandler *child)
|
||||
{
|
||||
if (child && !containsNode(child))
|
||||
{
|
||||
// note ref_ptr<> automatically handles incrementing child's reference count.
|
||||
_children.push_back(child);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
bool CompositeGUIEventHandler::removeChild(GUIEventHandler *child)
|
||||
{
|
||||
ChildList::iterator itr = findChild(child);
|
||||
if (itr!=_children.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing child's reference count.
|
||||
_children.erase(itr);
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
}
|
||||
9
src/osgGA/GUIEventHandlerVisitor.cpp
Normal file
9
src/osgGA/GUIEventHandlerVisitor.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <osgGA/GUIEventHandlerVisitor>
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
void osgGA::GUIEventHandlerVisitor::visit(osgGA::CompositeGUIEventHandler& cgeh)
|
||||
{
|
||||
for(int i=0; i<cgeh.getNumChildren(); i++){
|
||||
cgeh.getChild(i)->accept(*this);
|
||||
}
|
||||
}
|
||||
45
src/osgGA/KeySwitchCameraManipulator.cpp
Normal file
45
src/osgGA/KeySwitchCameraManipulator.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <osgGA/KeySwitchCameraManipulator>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osgGA;
|
||||
|
||||
void KeySwitchCameraManipulator::addCameraManipulator(int key, std::string name, CameraManipulator *cm)
|
||||
{
|
||||
if(!cm) return;
|
||||
|
||||
_manips[key]=std::make_pair(name,osg::ref_ptr<CameraManipulator>(cm));
|
||||
if(!_current.valid()){
|
||||
_current=cm;
|
||||
}
|
||||
}
|
||||
|
||||
bool KeySwitchCameraManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& aa)
|
||||
{
|
||||
if(ea.getEventType()==GUIEventAdapter::KEYBOARD){
|
||||
|
||||
KeyManipMap::iterator it=_manips.find(ea.getKey());
|
||||
if(it != _manips.end()){
|
||||
osg::notify(osg::INFO)<<"Switching to manipulator: "<<(*it).second.first<<endl;
|
||||
cout<<"***Switching to manipulator: "<<(*it).second.first<<endl;
|
||||
it->second.second->setNode(_current->getNode());
|
||||
it->second.second->setCamera(_current->getCamera());
|
||||
it->second.second->init(ea,aa);
|
||||
_current = it->second.second;
|
||||
|
||||
//_cameraManipChangeCallbacks.notify(this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return _current->handle(ea,aa);
|
||||
}
|
||||
|
||||
// void KeySwitchCameraManipulator::addCallback(Callback* c)
|
||||
// {
|
||||
// _cameraManipChangeCallbacks.addCallback(c);
|
||||
// }
|
||||
//
|
||||
// void KeySwitchCameraManipulator::removeCallback(Callback* c)
|
||||
// {
|
||||
// _cameraManipChangeCallbacks.removeCallback(c);
|
||||
// }
|
||||
24
src/osgGA/Makefile
Normal file
24
src/osgGA/Makefile
Normal file
@@ -0,0 +1,24 @@
|
||||
TOPDIR = ../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
|
||||
CXXFILES = \
|
||||
CameraManipulator.cpp\
|
||||
DriveManipulator.cpp\
|
||||
FlightManipulator.cpp\
|
||||
GUIEventHandler.cpp\
|
||||
GUIEventHandlerVisitor.cpp\
|
||||
KeySwitchCameraManipulator.cpp\
|
||||
SetSceneViewVisitor.cpp\
|
||||
StateSetManipulator.cpp\
|
||||
TrackballManipulator.cpp\
|
||||
Version.cpp\
|
||||
|
||||
DEF += -DOSGGA_LIBRARY
|
||||
|
||||
LIBS += -losgUtil -losg $(GL_LIBS) $(OTHER_LIBS)
|
||||
|
||||
TARGET_BASENAME = osgGA
|
||||
LIB = $(LIB_PREFIX)$(TARGET_BASENAME).$(LIB_EXT)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
16
src/osgGA/SetSceneViewVisitor.cpp
Normal file
16
src/osgGA/SetSceneViewVisitor.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <osgGA/SetSceneViewVisitor>
|
||||
#include <osgGA/CameraManipulator>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
|
||||
void osgGA::SetSceneViewVisitor::visit(osgGA::CameraManipulator& cm)
|
||||
{
|
||||
cm.setNode(_sceneView->getSceneData());
|
||||
cm.setCamera(_sceneView->getCamera());
|
||||
cm.init(*getGUIEventAdapter(),*getGUIActionAdapter());
|
||||
cm.home(*getGUIEventAdapter(),*getGUIActionAdapter());
|
||||
}
|
||||
|
||||
void osgGA::SetSceneViewVisitor::visit(osgGA::StateSetManipulator& ssm)
|
||||
{
|
||||
ssm.setStateSet(_sceneView->getGlobalStateSet());
|
||||
}
|
||||
73
src/osgGA/StateSetManipulator.cpp
Normal file
73
src/osgGA/StateSetManipulator.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <osgGA/StateSetManipulator>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgGA;
|
||||
|
||||
StateSetManipulator::StateSetManipulator(): _drawState(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
StateSetManipulator::~StateSetManipulator()
|
||||
{
|
||||
}
|
||||
|
||||
void StateSetManipulator::setStateSet(StateSet *drawState)
|
||||
{
|
||||
_drawState=drawState;
|
||||
if(!_drawState.valid()) return;
|
||||
_backface = (_drawState->getMode(GL_CULL_FACE)==osg::StateAttribute::ON);
|
||||
_lighting =(_drawState->getMode(GL_LIGHTING)==osg::StateAttribute::ON);
|
||||
_texture =(_drawState->getMode(GL_TEXTURE_2D)==osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
StateSet *StateSetManipulator::getStateSet()
|
||||
{
|
||||
return _drawState.get();
|
||||
}
|
||||
|
||||
const StateSet *StateSetManipulator::getStateSet() const
|
||||
{
|
||||
return _drawState.get();
|
||||
}
|
||||
|
||||
bool StateSetManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& aa)
|
||||
{
|
||||
if(!_drawState.valid()) return false;
|
||||
|
||||
if(ea.getEventType()==GUIEventAdapter::KEYBOARD){
|
||||
|
||||
switch( ea.getKey() ){
|
||||
|
||||
case 'b' :
|
||||
_backface = !_backface;
|
||||
if( _backface ) _drawState->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
|
||||
else _drawState->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE_OFF);
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 'l' :
|
||||
_lighting = !_lighting ;
|
||||
if( _lighting ) _drawState->setMode(GL_LIGHTING,osg::StateAttribute::ON);
|
||||
else _drawState->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_OFF);
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 't' :
|
||||
_texture = !_texture;
|
||||
if (_texture) _drawState->setMode(GL_TEXTURE_2D,osg::StateAttribute::INHERIT);
|
||||
else _drawState->setMode(GL_TEXTURE_2D,osg::StateAttribute::OVERRIDE_OFF);
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void StateSetManipulator::accept(GUIEventHandlerVisitor& gehv)
|
||||
{
|
||||
gehv.visit(*this);
|
||||
}
|
||||
397
src/osgGA/TrackballManipulator.cpp
Normal file
397
src/osgGA/TrackballManipulator.cpp
Normal file
@@ -0,0 +1,397 @@
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osg/Types>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgGA;
|
||||
|
||||
TrackballManipulator::TrackballManipulator()
|
||||
{
|
||||
_modelScale = 0.01f;
|
||||
_minimumZoomScale = 0.05f;
|
||||
_thrown = false;
|
||||
}
|
||||
|
||||
|
||||
TrackballManipulator::~TrackballManipulator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TrackballManipulator::setNode(osg::Node* node)
|
||||
{
|
||||
_node = node;
|
||||
if (_node.get())
|
||||
{
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
_modelScale = boundingSphere._radius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const osg::Node* TrackballManipulator::getNode() const
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
|
||||
osg::Node* TrackballManipulator::getNode()
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
|
||||
/*ea*/
|
||||
void TrackballManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
|
||||
{
|
||||
if(_node.get() && _camera.get())
|
||||
{
|
||||
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
|
||||
_camera->setView(boundingSphere._center+osg::Vec3( 0.0,-3.0f * boundingSphere._radius,0.0f),
|
||||
boundingSphere._center,
|
||||
osg::Vec3(0.0f,0.0f,1.0f));
|
||||
|
||||
us.requestRedraw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TrackballManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
|
||||
{
|
||||
flushMouseEventStack();
|
||||
}
|
||||
|
||||
|
||||
bool TrackballManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
if(!_camera.get()) return false;
|
||||
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(GUIEventAdapter::PUSH):
|
||||
{
|
||||
flushMouseEventStack();
|
||||
addMouseEvent(ea);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
_thrown = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::RELEASE):
|
||||
{
|
||||
if (ea.getButtonMask()==0)
|
||||
{
|
||||
|
||||
if (isMouseMoving())
|
||||
{
|
||||
if (calcMovement())
|
||||
{
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate(true);
|
||||
_thrown = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flushMouseEventStack();
|
||||
addMouseEvent(ea);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
_thrown = false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
flushMouseEventStack();
|
||||
addMouseEvent(ea);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
_thrown = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::DRAG):
|
||||
{
|
||||
addMouseEvent(ea);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
_thrown = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::MOVE):
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
case(GUIEventAdapter::KEYBOARD):
|
||||
if (ea.getKey()==' ')
|
||||
{
|
||||
flushMouseEventStack();
|
||||
_thrown = false;
|
||||
home(ea,us);
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
return true;
|
||||
} else if (ea.getKey()=='+')
|
||||
{
|
||||
_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()*1.25f);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='-')
|
||||
{
|
||||
_camera->setFusionDistanceRatio(_camera->getFusionDistanceRatio()/1.25f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case(GUIEventAdapter::FRAME):
|
||||
_camera->setFusionDistanceMode(osg::Camera::PROPORTIONAL_TO_LOOK_DISTANCE);
|
||||
if (_thrown)
|
||||
{
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TrackballManipulator::isMouseMoving()
|
||||
{
|
||||
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
|
||||
|
||||
static const float velocity = 100.0f;
|
||||
|
||||
float dx = _ga_t0->getX()-_ga_t1->getX();
|
||||
float dy = _ga_t0->getY()-_ga_t1->getY();
|
||||
float len = sqrtf(dx*dx+dy*dy);
|
||||
float dt = _ga_t0->time()-_ga_t1->time();
|
||||
|
||||
return (len>dt*velocity);
|
||||
}
|
||||
|
||||
|
||||
void TrackballManipulator::flushMouseEventStack()
|
||||
{
|
||||
_ga_t1 = NULL;
|
||||
_ga_t0 = NULL;
|
||||
}
|
||||
|
||||
|
||||
void TrackballManipulator::addMouseEvent(const GUIEventAdapter& ea)
|
||||
{
|
||||
_ga_t1 = _ga_t0;
|
||||
_ga_t0 = &ea;
|
||||
}
|
||||
|
||||
|
||||
bool TrackballManipulator::calcMovement()
|
||||
{
|
||||
|
||||
// return if less then two events have been added.
|
||||
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
|
||||
|
||||
float dx = _ga_t0->getX()-_ga_t1->getX();
|
||||
float dy = _ga_t0->getY()-_ga_t1->getY();
|
||||
|
||||
|
||||
// return if there is no movement.
|
||||
if (dx==0 && dy==0) return false;
|
||||
|
||||
float focalLength = (_camera->getCenterPoint()-_camera->getEyePoint()).length();
|
||||
unsigned int buttonMask = _ga_t1->getButtonMask();
|
||||
if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
|
||||
{
|
||||
|
||||
// rotate camera.
|
||||
|
||||
osg::Vec3 center = _camera->getCenterPoint();
|
||||
osg::Vec3 axis;
|
||||
float angle;
|
||||
|
||||
float mx0 = (_ga_t0->getXmin()+_ga_t0->getXmax())/2.0f;
|
||||
float rx0 = (_ga_t0->getXmax()-_ga_t0->getXmin())/2.0f;
|
||||
|
||||
float my0 = (_ga_t0->getYmin()+_ga_t0->getYmax())/2.0f;
|
||||
float ry0 = (_ga_t0->getYmax()-_ga_t0->getYmin())/2.0f;
|
||||
|
||||
float mx1 = (_ga_t0->getXmin()+_ga_t1->getXmax())/2.0f;
|
||||
float rx1 = (_ga_t0->getXmax()-_ga_t1->getXmin())/2.0f;
|
||||
|
||||
float my1 = (_ga_t1->getYmin()+_ga_t1->getYmax())/2.0f;
|
||||
float ry1 = (_ga_t1->getYmax()-_ga_t1->getYmin())/2.0f;
|
||||
|
||||
float px0 = (_ga_t0->getX()-mx0)/rx0;
|
||||
float py0 = (my0-_ga_t0->getY())/ry0;
|
||||
|
||||
float px1 = (_ga_t1->getX()-mx1)/rx1;
|
||||
float py1 = (my1-_ga_t1->getY())/ry1;
|
||||
|
||||
trackball(axis,angle,px1,py1,px0,py0);
|
||||
|
||||
osg::Matrix mat;
|
||||
mat.makeTranslate(-center.x(),-center.y(),-center.z());
|
||||
mat *= Matrix::rotate(angle,axis.x(),axis.y(),axis.z());
|
||||
mat *= Matrix::translate(center.x(),center.y(),center.z());
|
||||
|
||||
_camera->transformLookAt(mat);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
|
||||
buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
|
||||
{
|
||||
|
||||
// pan model.
|
||||
|
||||
|
||||
float scale = 0.0015f*focalLength;
|
||||
|
||||
osg::Vec3 uv = _camera->getUpVector();
|
||||
osg::Vec3 sv = _camera->getSideVector();
|
||||
osg::Vec3 dv = uv*(dy*scale)-sv*(dx*scale);
|
||||
|
||||
osg::Matrix mat;
|
||||
mat.makeTranslate(dv.x(),dv.y(),dv.z());
|
||||
|
||||
_camera->transformLookAt(mat);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
|
||||
{
|
||||
|
||||
// zoom model.
|
||||
|
||||
float fd = focalLength;
|
||||
float scale = 1.0f-dy*0.001f;
|
||||
if (fd*scale>_modelScale*_minimumZoomScale)
|
||||
{
|
||||
// zoom camera in.
|
||||
osg::Vec3 center = _camera->getCenterPoint();
|
||||
|
||||
osg::Matrix mat;
|
||||
mat.makeTranslate(-center.x(),-center.y(),-center.z());
|
||||
mat *= Matrix::scale(scale,scale,scale);
|
||||
mat *= Matrix::translate(center.x(),center.y(),center.z());
|
||||
|
||||
_camera->transformLookAt(mat);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// notify(DEBUG_INFO) << "Pushing forward"<<std::endl;
|
||||
// push the camera forward.
|
||||
float scale = 0.0015f*fd;
|
||||
osg::Vec3 dv = _camera->getLookVector()*(dy*scale);
|
||||
|
||||
osg::Matrix mat;
|
||||
mat.makeTranslate(dv.x(),dv.y(),dv.z());
|
||||
|
||||
_camera->transformLookAt(mat);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This size should really be based on the distance from the center of
|
||||
* rotation to the point on the object underneath the mouse. That
|
||||
* point would then track the mouse as closely as possible. This is a
|
||||
* simple example, though, so that is left as an Exercise for the
|
||||
* Programmer.
|
||||
*/
|
||||
const float TRACKBALLSIZE = 0.8f;
|
||||
|
||||
/*
|
||||
* Ok, simulate a track-ball. Project the points onto the virtual
|
||||
* trackball, then figure out the axis of rotation, which is the cross
|
||||
* product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
|
||||
* Note: This is a deformed trackball-- is a trackball in the center,
|
||||
* but is deformed into a hyperbolic sheet of rotation away from the
|
||||
* center. This particular function was chosen after trying out
|
||||
* several variations.
|
||||
*
|
||||
* It is assumed that the arguments to this routine are in the range
|
||||
* (-1.0 ... 1.0)
|
||||
*/
|
||||
void TrackballManipulator::trackball(osg::Vec3& axis,float& angle, float p1x, float p1y, float p2x, float p2y)
|
||||
{
|
||||
/*
|
||||
* First, figure out z-coordinates for projection of P1 and P2 to
|
||||
* deformed sphere
|
||||
*/
|
||||
|
||||
osg::Vec3 uv = _camera->getUpVector();
|
||||
osg::Vec3 sv = _camera->getSideVector();
|
||||
osg::Vec3 lv = _camera->getLookVector();
|
||||
|
||||
osg::Vec3 p1 = sv*p1x+uv*p1y-lv*tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y);
|
||||
osg::Vec3 p2 = sv*p2x+uv*p2y-lv*tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y);
|
||||
|
||||
/*
|
||||
* Now, we want the cross product of P1 and P2
|
||||
*/
|
||||
|
||||
// Robert,
|
||||
//
|
||||
// This was the quick 'n' dirty fix to get the trackball doing the right
|
||||
// thing after fixing the Quat rotations to be right-handed. You may want
|
||||
// to do something more elegant.
|
||||
// axis = p1^p2;
|
||||
axis = p2^p1;
|
||||
axis.normalize();
|
||||
|
||||
/*
|
||||
* Figure out how much to rotate around that axis.
|
||||
*/
|
||||
float t = (p2-p1).length() / (2.0*TRACKBALLSIZE);
|
||||
|
||||
/*
|
||||
* Avoid problems with out-of-control values...
|
||||
*/
|
||||
if (t > 1.0) t = 1.0;
|
||||
if (t < -1.0) t = -1.0;
|
||||
angle = inRadians(asin(t));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
|
||||
* if we are away from the center of the sphere.
|
||||
*/
|
||||
float TrackballManipulator::tb_project_to_sphere(float r, float x, float y)
|
||||
{
|
||||
float d, t, z;
|
||||
|
||||
d = sqrt(x*x + y*y);
|
||||
/* Inside sphere */
|
||||
if (d < r * 0.70710678118654752440)
|
||||
{
|
||||
z = sqrt(r*r - d*d);
|
||||
} /* On hyperbola */
|
||||
else
|
||||
{
|
||||
t = r / 1.41421356237309504880;
|
||||
z = t*t / d;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
12
src/osgGA/Version.cpp
Normal file
12
src/osgGA/Version.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <osgGA/Version>
|
||||
|
||||
const char* osgGAGetVersion()
|
||||
{
|
||||
return "0.8.45";
|
||||
}
|
||||
|
||||
|
||||
const char* osgGAGetLibraryName()
|
||||
{
|
||||
return "Open Scene Graph Gui Adapter Library";
|
||||
}
|
||||
@@ -257,6 +257,12 @@ void SceneView::cull()
|
||||
cullStage(projectionRight.get(),modelviewRight.get(),_cullVisitorRight.get(),_rendergraphRight.get(),_renderStageRight.get());
|
||||
|
||||
|
||||
// if (_camera.valid())
|
||||
// {
|
||||
// // clamp the camera to the near/far computed in cull traversal.
|
||||
// _camera->setNearFar(_cullVisitorRight->getCalculatedNearPlane(),_cullVisitorRight->getCalculatedFarPlane());
|
||||
// }
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -278,8 +284,15 @@ void SceneView::cull()
|
||||
|
||||
_cullVisitor->setTraversalMask(_cullMask);
|
||||
cullStage(projection.get(),modelview.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
|
||||
|
||||
// if (_camera.valid())
|
||||
// {
|
||||
// // clamp the camera to the near/far computed in cull traversal.
|
||||
// _camera->setNearFar(_cullVisitor->getCalculatedNearPlane(),_cullVisitor->getCalculatedFarPlane());
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil::CullVisitor* cullVisitor, osgUtil::RenderGraph* rendergraph, osgUtil::RenderStage* renderStage)
|
||||
|
||||
Reference in New Issue
Block a user