From Vivek Rajan, new osgManipulator library, with a few minor tweaks and rename for osgDragger to osgManipulator for build by Robert Osfield.

Vivek's email to osg-submissions:

"I'm happy to release the osgdragger nodekit to the OSG community. I
implemented the nodekit for my company, Fugro-Jason Inc., and they
have kindly agreed to open source it.

The nodekit contains a few draggers but it should be easy to build new
draggers on top of it. The design of the nodekit is based on a
SIGGRAPH 2002 course - "Design and Implementation of Direct
Manipulation in 3D". You can find the course notes at
http://www.pauliface.com/Sigg02/index.html. Reading pages 20 - 29 of
the course notes should give you a fair understanding of how the
nodekit works.

The source code also contains an example of how to use the draggers."
This commit is contained in:
Robert Osfield 2007-02-11 10:33:59 +00:00
parent f1a82f35b2
commit 19db0c1674
49 changed files with 6774 additions and 1 deletions

View File

@ -22,7 +22,8 @@ SRC_DIRS = \
osgParticle \
osgFX \
osgShadow \
osgSim
osgSim \
osgManipulator
ifeq ($(PRODUCER_INSTALLED),yes)
SRC_DIRS += osgProducer
@ -272,6 +273,7 @@ EXAMPLE_DIRS = \
osgvertexprogram \
osgvolume \
osgwindows \
osgmanipulator \
ifeq ($(COMPILE_INTROSPECTION),yes)

View File

@ -99,6 +99,27 @@ Package=<4>
###############################################################################
Project: "Core osgManipulator"=.\osgManipulator\osgManipulator.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
Begin Project Dependency
Project_Dep_Name Core osgGA
End Project Dependency
}}}
###############################################################################
Project: "Core osgShadow"=.\osgShadow\osgShadow.dsp - Package Owner=<4>
Package=<5>
@ -1302,6 +1323,36 @@ Package=<4>
###############################################################################
Project: "Example osgparticle"=.\examples\osgmanipulator\osgmanipulatordemo.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 osgDB
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgGA
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgManipulator
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgProducer
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgUtil
End Project Dependency
}}}
###############################################################################
Project: "Example osgmovie"=.\examples\osgmovie\osgmovie.dsp - Package Owner=<4>
Package=<5>

View File

@ -0,0 +1,101 @@
# Microsoft Developer Studio Project File - Name="Example osgmanipulator" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=Example osgmanipulator - 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 "osgmanipulatordemo.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 "osgmanipulatordemo.mak" CFG="Example osgmanipulator - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Example osgmanipulator - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Example osgmanipulator - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Example osgmanipulator - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../bin/$(PlatformName)"
# PROP Intermediate_Dir "$(PlatformName)/$(ConfigurationName)"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "_CRT_SECURE_NO_DEPRECATE" /YX /FD /Zm200 /c
# 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 /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 OpenThreadsWin32.lib Producer.lib /nologo /subsystem:console /debug /machine:I386 /opt:ref /opt:icf /out:"$(OutDir)/osgmanipulator.exe" /libpath:"../../../lib/$(PlatformName)" /libpath:"../../../../OpenThreads/lib/$(PlatformName)" /libpath:"../../../../Producer/lib/$(PlatformName)" /libpath:"../../../../3rdParty/lib/$(PlatformName)" /libpath:"../../../../3rdParty/lib"
!ELSEIF "$(CFG)" == "Example osgmanipulator - 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 "../../../bin/$(PlatformName)"
# PROP Intermediate_Dir "$(PlatformName)/$(ConfigurationName)"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "_CONSOLE" /D "_MBCS" /D "FL_DLL" /D "WIN32" /D "_DEBUG" /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /Zm200 /c
# 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 /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 OpenThreadsWin32d.lib Produced.lib glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"$(OutDir)/osgmanipulatord.exe" /pdbtype:sept /libpath:"../../../lib/$(PlatformName)" /libpath:"../../../../OpenThreads/lib/$(PlatformName)" /libpath:"../../../../Producer/lib/$(PlatformName)"/libpath:"../../../../3rdParty/lib/$(PlatformName)" /libpath:"../../../../3rdParty/lib"
# SUBTRACT LINK32 /incremental:no
!ENDIF
# Begin Target
# Name "Example osgmanipulator - Win32 Release"
# Name "Example osgmanipulator - Win32 Debug"
# Begin Source File
SOURCE=..\..\..\examples\osgmanipulator\osgmanipulator.cpp
# End Source File
# End Target
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=..\..\icons\osg_icon.rc
# End Source File
# End Group
# End Project

View File

@ -0,0 +1,329 @@
# Microsoft Developer Studio Project File - Name="Core osgManipulator" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Core osgManipulator - 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 "osgManipulator.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 "osgManipulator.mak" CFG="Core osgManipulator - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Core osgManipulator - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Core osgManipulator - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Core osgManipulator - Win32 Release Static" (based on "Win32 (x86) Static Library")
!MESSAGE "Core osgManipulator - Win32 Debug Static" (based on "Win32 (x86) Static 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 osgManipulator - 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 "../../bin/$(PlatformName)"
# PROP Intermediate_Dir "$(PlatformName)/$(ConfigurationName)"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# 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" /I "../../../OpenThreads/include" /I "../../../Producer/include" /I "../../../3rdParty/include" /D "NDEBUG" /D "_MBCS" /D "_USRDLL" /D "OSGMANIPULATOR_LIBRARY" /D "_WINDOWS" /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /YX /FD /Zm200 /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 /debug /machine:I386 /pdbtype:sept
# ADD LINK32 OpenThreadsWin32.lib opengl32.lib glu32.lib /nologo /dll /debug /machine:I386 /opt:ref /opt:icf /out:"$(OutDir)/osgManipulator.dll" /implib:"../../lib/$(PlatformName)/osgManipulator.lib" /libpath:"../../lib/$(PlatformName)" /libpath:"../../../OpenThreads/lib/$(PlatformName)" /libpath:"../../../Producer/lib/$(PlatformName)" /libpath:"../../../3rdParty/lib/$(PlatformName)" /libpath:"../../../3rdParty/lib"
!ELSEIF "$(CFG)" == "Core osgManipulator - 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 "../../bin/$(PlatformName)"
# PROP Intermediate_Dir "$(PlatformName)/$(ConfigurationName)"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# 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 /GR /GX /Zi /Od /I "../../include" /I "../../../OpenThreads/include" /I "../../../Producer/include" /I "../../../3rdParty/include" /D "_DEBUG" /D "OSGMANIPULATOR_LIBRARY" /D "_WINDOWS" /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /YX /FD /GZ /Zm200 /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 OpenThreadsWin32d.lib opengl32.lib glu32.lib /nologo /dll /debug /machine:I386 /out:"$(OutDir)/osgManipulatord.dll" /pdbtype:sept /implib:"../../lib/$(PlatformName)/osgManipulatord.lib" /libpath:"../../lib/$(PlatformName)" /libpath:"../../../OpenThreads/lib/$(PlatformName)" /libpath:"../../../Producer/lib/$(PlatformName)" /libpath:"../../../3rdParty/lib/$(PlatformName)" /libpath:"../../../3rdParty/lib"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "Core osgManipulator - Win32 Release Static"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "../../lib"
# PROP BASE Intermediate_Dir "Release_Static"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../lib/$(PlatformName)"
# PROP Intermediate_Dir "$(PlatformName)/$(ConfigurationName)_Static"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "OSG_LIBRARY_STATIC" /D "OT_LIBRARY_STATIC" /D "PR_LIBRARY_STATIC" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "../../include" /I "../../../OpenThreads/include" /I "../../../Producer/include" /I "../../../3rdParty/include" /D "NDEBUG" /D "_MBCS" /D "OSG_LIBRARY_STATIC" /D "OT_LIBRARY_STATIC" /D "PR_LIBRARY_STATIC" /D "_WINDOWS" /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /YX /FD /Zm200 /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
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nodefaultlib /nologo /out:"$(OutDir)/osgManipulator_s.lib"
!ELSEIF "$(CFG)" == "Core osgManipulator - Win32 Debug Static"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "../../lib"
# PROP BASE Intermediate_Dir "Debug_Static"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../lib/$(PlatformName)"
# PROP Intermediate_Dir "$(PlatformName)/$(ConfigurationName)_Static"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "OSG_LIBRARY_STATIC" /D "OT_LIBRARY_STATIC" /D "PR_LIBRARY_STATIC" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /vmg /GR /GX /Z7 /Od /I "../../include" /I "../../../OpenThreads/include" /I "../../../Producer/include" /I "../../../3rdParty/include" /D "_DEBUG" /D "OSG_LIBRARY_STATIC" /D "OT_LIBRARY_STATIC" /D "PR_LIBRARY_STATIC" /D "_WINDOWS" /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /YX /FD /GZ /Zm200 /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
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nodefaultlib /nologo /out:"$(OutDir)/osgManipulatord_s.lib"
# SUBTRACT LIB32 /pdb:none
!ENDIF
# Begin Target
# Name "Core osgManipulator - Win32 Release"
# Name "Core osgManipulator - Win32 Debug"
# Name "Core osgManipulator - Win32 Release Static"
# Name "Core osgManipulator - Win32 Debug Static"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\src\osgManipulator\AntiSquish.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Command.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\CommandManager.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Constraint.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Dragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Projector.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\RotateCylinderDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\RotateSphereDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Scale1DDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Scale2DDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\ScaleAxisDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Selection.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\TabBoxDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\TabPlaneDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\TabPlaneTrackballDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\TrackballDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Translate1DDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\Translate2DDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\TranslateAxisDragger.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgManipulator\TranslatePlaneDragger.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter ";h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\include\osgManipulator\AntiSquish
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Command
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\CommandManager
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Constraint
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Dragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Export
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Projector
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\RotateCylinderDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\RotateSphereDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Scale1DDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Scale2DDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\ScaleAxisDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Selection
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\TabBoxDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\TabPlaneDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\TabPlaneTrackballDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\TrackballDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Translate1DDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\Translate2DDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\TranslateAxisDragger
# End Source File
# Begin Source File
SOURCE=..\..\include\osgManipulator\TranslatePlaneDragger
# 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

View File

@ -0,0 +1,18 @@
TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgmanipulator.cpp\
LIBS += -losgProducer -lProducer -losgManipulator -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
INSTFILES = \
$(CXXFILES)\
GNUmakefile.inst=GNUmakefile
EXEC = osgmanipulator
INC += $(X_INC)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,13 @@
TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgmanipulator.cpp\
LIBS += -losgProducer -lProducer -losgManipulator -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
EXEC = osgmanipulator
INC += $(X_INC)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,394 @@
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osgProducer/Viewer>
#include <osg/CoordinateSystemNode>
#include <osgText/Text>
#include <osgManipulator/CommandManager>
#include <osgManipulator/TabBoxDragger>
#include <osgManipulator/TabPlaneDragger>
#include <osgManipulator/TabPlaneTrackballDragger>
#include <osgManipulator/TrackballDragger>
#include <osgManipulator/Translate1DDragger>
#include <osgManipulator/Translate2DDragger>
#include <osgManipulator/TranslateAxisDragger>
osgManipulator::Dragger* createDragger(const std::string& name)
{
osgManipulator::Dragger* dragger = 0;
if ("TabPlaneDragger" == name)
{
osgManipulator::TabPlaneDragger* d = new osgManipulator::TabPlaneDragger();
d->setupDefaultGeometry();
dragger = d;
}
else if ("TabPlaneTrackballDragger" == name)
{
osgManipulator::TabPlaneTrackballDragger* d = new osgManipulator::TabPlaneTrackballDragger();
d->setupDefaultGeometry();
dragger = d;
}
else if ("TrackballDragger" == name)
{
osgManipulator::TrackballDragger* d = new osgManipulator::TrackballDragger();
d->setupDefaultGeometry();
dragger = d;
}
else if ("Translate1DDragger" == name)
{
osgManipulator::Translate1DDragger* d = new osgManipulator::Translate1DDragger();
d->setupDefaultGeometry();
dragger = d;
}
else if ("Translate2DDragger" == name)
{
osgManipulator::Translate2DDragger* d = new osgManipulator::Translate2DDragger();
d->setupDefaultGeometry();
dragger = d;
}
else if ("TranslateAxisDragger" == name)
{
osgManipulator::TranslateAxisDragger* d = new osgManipulator::TranslateAxisDragger();
d->setupDefaultGeometry();
dragger = d;
}
else
{
osgManipulator::TabBoxDragger* d = new osgManipulator::TabBoxDragger();
d->setupDefaultGeometry();
dragger = d;
}
return dragger;
}
osg::Node* createHUD()
{
osg::Geode* geode = new osg::Geode();
std::string timesFont("fonts/arial.ttf");
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
osg::Vec3 position(50.0f,50.0f,0.0f);
text->setPosition(position);
text->setText("Use the Tab key to switch between the trackball and pick modes.");
text->setFont(timesFont);
osg::Camera* camera = new osg::Camera;
// set the projection matrix
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
// set the view matrix
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
// only clear the depth buffer
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
// draw subgraph after main camera view.
camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->addChild(geode);
return camera;
}
bool computePixelCoords(osgProducer::Viewer* viewer,float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y)
{
Producer::KeyboardMouse* km = viewer->getKeyboardMouse();
if (!km) return false;
if (cameraNum>=viewer->getNumberOfCameras()) return false;
Producer::Camera* camera=viewer->getCamera(cameraNum);
Producer::RenderSurface* rs = camera->getRenderSurface();
Producer::InputArea* inputArea = km->getInputArea();
if( inputArea != NULL )
{
// first locate which InputRectange is appropriate for specified RenderSurface.
unsigned int i;
for(i=0;i<inputArea->getNumRenderSurfaces();++i)
{
if (inputArea->getRenderSurface(i)==rs) break;
}
// the RenderSurface isn't in the InputArea list.. therefore cannot make mouse coords to it.
if (i==inputArea->getNumRenderSurfaces()) return false;
// we have a valid InputRectangle
Producer::RenderSurface::InputRectangle ir = inputArea->getRenderSurface(i)->getInputRectangle();
float rx = (x-ir.left())/ir.width();
float ry = (y-ir.bottom())/ir.height();
int wx, wy;
unsigned int w, h;
rs->getWindowRectangle( wx, wy, w, h );
pixel_x = ((float)w)* rx;
pixel_y = ((float)h)* ry;
}
else
{
float rx = (x+1.0f)*0.5f;
float ry = (y+1.0f)*0.5f;
int wx, wy;
unsigned int w, h;
rs->getWindowRectangle( wx, wy, w, h );
pixel_x = ((float)w)* rx;
pixel_y = ((float)h)* ry;
}
return true;
}
osg::Node* addDraggerToScene(osg::Node* scene, osgManipulator::CommandManager* cmdMgr, const std::string& name)
{
scene->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
osgManipulator::Selection* selection = new osgManipulator::Selection;
selection->addChild(scene);
osgManipulator::Dragger* dragger = createDragger(name);
osg::Group* root = new osg::Group;
root->addChild(dragger);
root->addChild(selection);
root->addChild(createHUD());
float scale = scene->getBound().radius() * 1.6;
dragger->setMatrix(osg::Matrix::scale(scale, scale, scale) *
osg::Matrix::translate(scene->getBound().center()));
cmdMgr->connect(*dragger, *selection);
return root;
}
class PickModeHandler : public osgGA::GUIEventHandler
{
public:
enum Modes
{
VIEW = 0,
PICK
};
PickModeHandler(osgProducer::Viewer *viewer) : osgGA::GUIEventHandler(),
_viewer(viewer), _mode(VIEW), _activeDragger(0)
{
}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa,
osg::Object*, osg::NodeVisitor*)
{
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Tab &&
ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN &&
_activeDragger == 0)
{
_mode = ! _mode;
}
if (VIEW == _mode) return false;
for(unsigned int i=0;i<_viewer->getNumberOfCameras();++i)
{
if ((ea.getEventType() == osgGA::GUIEventAdapter::PUSH) &&
_viewer->computeIntersections(ea.getX(), ea.getY(), i, hitList))
{
float pixel_x,pixel_y;
if (computePixelCoords(_viewer,ea.getX(),ea.getY(),i,pixel_x,pixel_y))
{
Producer::Camera* camera=_viewer->getCamera(i);
osgProducer::OsgSceneHandler* sh = dynamic_cast<osgProducer::OsgSceneHandler*>(camera->getSceneHandler());
osgUtil::SceneView* sv = sh ? sh->getSceneView() : 0;
if (! sv) continue;
for (osg::NodePath::iterator itr = hitList.front().getNodePath().begin();
itr != hitList.front().getNodePath().end();
++itr)
{
osgManipulator::Dragger* dragger = dynamic_cast<osgManipulator::Dragger*>(*itr);
if (dragger)
{
dragger->handle(int(pixel_x+0.5), int(pixel_y+0.5), *sv,
hitList, hitList.begin(),
ea, aa);
_activeDragger = dragger;
break;
}
}
}
}
switch (ea.getEventType())
{
case osgGA::GUIEventAdapter::DRAG:
case osgGA::GUIEventAdapter::RELEASE:
if (_activeDragger)
{
float pixel_x,pixel_y;
if (computePixelCoords(_viewer,ea.getX(),ea.getY(),i,pixel_x,pixel_y))
{
Producer::Camera* camera=_viewer->getCamera(i);
osgProducer::OsgSceneHandler* sh = dynamic_cast<osgProducer::OsgSceneHandler*>(camera->getSceneHandler());
osgUtil::SceneView* sv = sh ? sh->getSceneView() : 0;
if (_activeDragger && sv)
_activeDragger->handle(int(pixel_x+0.5), int(pixel_y+0.5), *sv,
hitList, hitList.begin(),
ea, aa);
}
}
break;
default:
break;
}
if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
{
_activeDragger = 0;
hitList.clear();
}
}
return true;
}
private:
osgProducer::Viewer* _viewer;
unsigned int _mode;
osgManipulator::Dragger* _activeDragger;
osgUtil::IntersectVisitor::HitList hitList;
};
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
// set up the usage document, in case we need to print out how to use this program.
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
arguments.getApplicationUsage()->addCommandLineOption("--image <filename>","Load an image and render it on a quad");
arguments.getApplicationUsage()->addCommandLineOption("--dem <filename>","Load an image/DEM and render it on a HeightField");
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line parameters");
arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display environmental variables available");
arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display keyboard & mouse bindings available");
arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display all command line, env vars and keyboard & mouse bindings.");
arguments.getApplicationUsage()->addCommandLineOption("--dragger <draggername>","Use the specified dragger for manipulation");
// construct the viewer.
osgProducer::Viewer viewer(arguments);
// set up the value with sensible default event handlers.
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
// get details on keyboard and mouse bindings used by the viewer.
viewer.getUsage(*arguments.getApplicationUsage());
// if user request help write it out to cout.
bool helpAll = arguments.read("--help-all");
unsigned int helpType = ((helpAll || arguments.read("-h") || arguments.read("--help"))? osg::ApplicationUsage::COMMAND_LINE_OPTION : 0 ) |
((helpAll || arguments.read("--help-env"))? osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE : 0 ) |
((helpAll || arguments.read("--help-keys"))? osg::ApplicationUsage::KEYBOARD_MOUSE_BINDING : 0 );
if (helpType)
{
arguments.getApplicationUsage()->write(std::cout, helpType);
return 1;
}
// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
if (arguments.argc()<=1)
{
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
return 1;
}
std::string dragger_name = "TabBoxDragger";
arguments.read("--dragger", dragger_name);
osg::Timer_t start_tick = osg::Timer::instance()->tick();
// read the scene from the list of file specified command line args.
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
// if no model has been successfully loaded report failure.
if (!loadedModel)
{
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
return 1;
}
// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();
// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
}
osg::Timer_t end_tick = osg::Timer::instance()->tick();
std::cout << "Time to load = "<<osg::Timer::instance()->delta_s(start_tick,end_tick)<<std::endl;
// optimize the scene graph, remove redundant nodes and state etc.
osgUtil::Optimizer optimizer;
optimizer.optimize(loadedModel.get());
osg::ref_ptr<osgManipulator::CommandManager> cmdMgr = new osgManipulator::CommandManager;
// pass the loaded scene graph to the viewer.
viewer.setSceneData(addDraggerToScene(loadedModel.get(), cmdMgr.get(), dragger_name));
viewer.getEventHandlerList().push_front(new PickModeHandler(&viewer));
// create the windows and run the threads.
viewer.realize();
while( !viewer.done() )
{
// wait for all cull and draw threads to complete.
viewer.sync();
// update the scene by traversing it with the the update visitor which will
// call all node update callbacks and animations.
viewer.update();
// fire off the cull and draw traversals of the scene.
viewer.frame();
}
// wait for all cull and draw threads to complete.
viewer.sync();
// run a clean up frame to delete all OpenGL objects.
viewer.cleanup_frame();
// wait for all the clean up frame to complete.
viewer.sync();
return 0;
}

View File

@ -0,0 +1,84 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgDragger - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef _OSG_ANTISQUISH_
#define _OSG_ANTISQUISH_ 1
#include <osgManipulator/Export>
#include <osg/Matrix>
#include <osg/CopyOp>
#include <osg/NodeVisitor>
#include <osg/NodeCallback>
#include <osg/MatrixTransform>
#include <osg/Quat>
#include <osg/Vec3>
namespace osgManipulator {
/**
* Class that performs the Anti Squish by making the scaling uniform along all axes.
*/
class OSGMANIPULATOR_EXPORT AntiSquish: public osg::MatrixTransform
{
public :
AntiSquish();
AntiSquish(const osg::Vec3& pivot);
AntiSquish(const osg::Vec3& pivot, const osg::Vec3& position);
AntiSquish(const AntiSquish& pat, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const { return new AntiSquish(); }
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new AntiSquish (*this,copyop); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const AntiSquish *>(obj)!=NULL; }
void setPivot(const osg::Vec3& pvt)
{
_pivot = pvt;
_usePivot = true;
_dirty = true;
}
const osg::Vec3& getPivot() { return _pivot; }
void setPosition(const osg::Vec3& pos)
{
_position = pos;
_usePosition = true;
_dirty = true;
}
const osg::Vec3& getPosition() { return _position; }
virtual ~AntiSquish();
osg::Matrix computeUnSquishedMatrix(const osg::Matrix&, bool& flag);
protected:
osg::NodeCallback* _asqCallback;
osg::Vec3 _pivot;
bool _usePivot;
osg::Vec3 _position;
bool _usePosition;
bool _dirty;
osg::Matrix _cachedLocalToWorld;
};
}
#endif

View File

@ -0,0 +1,352 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_COMMAND
#define OSGMANIPULATOR_COMMAND 1
#include <osgManipulator/Export>
#include <osgManipulator/Selection>
#include <osg/LineSegment>
#include <osg/Plane>
#include <osg/Vec2>
#include <vector>
namespace osgManipulator {
class Constraint;
/** Base class for motion commands that are generated by draggers. */
class OSGMANIPULATOR_EXPORT MotionCommand : public osg::Referenced
{
public:
/**
* Motion command are based on click-drag-release actions. So each
* command needs to indicate which stage of the motion the command
* represents.
*/
enum Stage
{
NONE,
/** Click or pick start. */
START,
/** Drag or pick move. */
MOVE,
/** Release or pick finish. */
FINISH
};
MotionCommand();
/** Execute the command. */
virtual bool execute() = 0;
/** Undo the command. The inverse of this command is executed. */
virtual bool unexecute() = 0;
/** Apply a constraint to the command. */
virtual void applyConstraint(const Constraint*) = 0;
/**
* Add Selection (receiver) to the command. The command will be
* executed on all the selections.
*/
void addSelection(Selection*);
/** Remove Selection (receiver) from the command. */
void removeSelection(Selection*);
/**
* Gets the matrix for transforming the Selection. This matrix is in the
* command's coordinate systems.
*/
virtual osg::Matrix getMotionMatrix() const = 0;
/**
* Sets the matrix for transforming the command's local coordinate
* system to the world/object coordinate system.
*/
void setLocalToWorldAndWorldToLocal(const osg::Matrix& localToWorld, const osg::Matrix& worldToLocal)
{
_localToWorld = localToWorld;
_worldToLocal = worldToLocal;
}
/**
* Gets the matrix for transforming the command's local coordinate
* system to the world/object coordinate system.
*/
inline const osg::Matrix& getLocalToWorld() const { return _localToWorld; }
/**
* Gets the matrix for transforming the command's world/object
* coordinate system to the command's local coordinate system.
*/
inline const osg::Matrix& getWorldToLocal() const { return _worldToLocal; }
void setStage(const Stage s) { _stage = s; }
Stage getStage() const { return _stage; }
protected:
virtual ~MotionCommand();
typedef std::vector< osg::ref_ptr<Selection> > SelectionList;
SelectionList& getSelectionList() { return _selectionList; }
const SelectionList& getSelectionList() const { return _selectionList; }
private:
osg::Matrix _localToWorld;
osg::Matrix _worldToLocal;
Stage _stage;
SelectionList _selectionList;
};
/**
* Command for translating in a line.
*/
class OSGMANIPULATOR_EXPORT TranslateInLineCommand : public MotionCommand
{
public:
TranslateInLineCommand();
TranslateInLineCommand(const osg::Vec3& s, const osg::Vec3& e);
virtual bool execute();
virtual bool unexecute();
virtual void applyConstraint(const Constraint*);
inline void setLine(const osg::Vec3& s, const osg::Vec3& e) { _line->start() = s; _line->end() = e; }
inline const osg::Vec3& getLineStart() const { return _line->start(); }
inline const osg::Vec3& getLineEnd() const { return _line->end(); }
inline void setTranslation(const osg::Vec3& t) { _translation = t; }
inline const osg::Vec3& getTranslation() const { return _translation; }
virtual osg::Matrix getMotionMatrix() const
{
return osg::Matrix::translate(_translation);
}
protected:
virtual ~TranslateInLineCommand();
private:
osg::ref_ptr<osg::LineSegment> _line;
osg::Vec3 _translation;
};
/**
* Command for translating in a plane.
*/
class OSGMANIPULATOR_EXPORT TranslateInPlaneCommand : public MotionCommand
{
public:
TranslateInPlaneCommand();
TranslateInPlaneCommand(const osg::Plane& plane);
virtual bool execute();
virtual bool unexecute();
virtual void applyConstraint(const Constraint*);
inline void setPlane(const osg::Plane& plane) { _plane = plane; }
inline const osg::Plane& getPlane() const { return _plane; }
inline void setTranslation(const osg::Vec3& t) { _translation = t; }
inline const osg::Vec3& getTranslation() const { return _translation; }
/** ReferencePoint is used only for snapping. */
inline void setReferencePoint(const osg::Vec3& rp) { _referencePoint = rp; }
inline const osg::Vec3& getReferencePoint() const { return _referencePoint; }
virtual osg::Matrix getMotionMatrix() const
{
return osg::Matrix::translate(_translation);
}
protected:
virtual ~TranslateInPlaneCommand();
private:
osg::Plane _plane;
osg::Vec3 _translation;
osg::Vec3 _referencePoint;
};
/**
* Command for 1D scaling.
*/
class OSGMANIPULATOR_EXPORT Scale1DCommand : public MotionCommand
{
public:
Scale1DCommand();
virtual bool execute();
virtual bool unexecute();
virtual void applyConstraint(const Constraint*);
inline void setScale(float s) { _scale = s; }
inline float getScale() const { return _scale; }
inline void setScaleCenter(float center) { _scaleCenter = center; }
inline float getScaleCenter() const { return _scaleCenter; }
/** ReferencePoint is used only for snapping. */
inline void setReferencePoint(float rp) { _referencePoint = rp; }
inline float getReferencePoint() const { return _referencePoint; }
inline void setMinScale(float min) { _minScale = min; }
inline float getMinScale() const { return _minScale; }
virtual osg::Matrix getMotionMatrix() const
{
return (osg::Matrix::translate(-_scaleCenter,0.0,0.0)
* osg::Matrix::scale(_scale,1.0,1.0)
* osg::Matrix::translate(_scaleCenter,0.0,0.0));
}
protected:
virtual ~Scale1DCommand();
private:
float _scale;
float _scaleCenter;
float _referencePoint;
float _minScale;
};
/**
* Command for 2D scaling.
*/
class OSGMANIPULATOR_EXPORT Scale2DCommand : public MotionCommand
{
public:
Scale2DCommand();
virtual bool execute();
virtual bool unexecute();
virtual void applyConstraint(const Constraint*);
inline void setScale(const osg::Vec2& s) { _scale = s; }
inline const osg::Vec2& getScale() const { return _scale; }
inline void setScaleCenter(const osg::Vec2& center) { _scaleCenter = center; }
inline const osg::Vec2& getScaleCenter() const { return _scaleCenter; }
/** ReferencePoint is used only for snapping. */
inline void setReferencePoint(const osg::Vec2& rp) { _referencePoint = rp; }
inline const osg::Vec2& getReferencePoint() const { return _referencePoint; }
inline void setMinScale(const osg::Vec2& min) { _minScale = min; }
inline const osg::Vec2& getMinScale() const { return _minScale; }
virtual osg::Matrix getMotionMatrix() const
{
return (osg::Matrix::translate(-_scaleCenter[0],0.0,-_scaleCenter[1])
* osg::Matrix::scale(_scale[0],1.0,_scale[1])
* osg::Matrix::translate(_scaleCenter[0],0.0,_scaleCenter[1]));
}
protected:
virtual ~Scale2DCommand();
private:
osg::Vec2 _scale;
osg::Vec2 _scaleCenter;
osg::Vec2 _referencePoint;
osg::Vec2 _minScale;
};
/**
* Command for uniform 3D scaling.
*/
class OSGMANIPULATOR_EXPORT ScaleUniformCommand : public MotionCommand
{
public:
ScaleUniformCommand();
virtual bool execute();
virtual bool unexecute();
virtual void applyConstraint(const Constraint*);
inline void setScale(float s) { _scale = s; }
inline float getScale() const { return _scale; }
inline void setScaleCenter(const osg::Vec3& center) { _scaleCenter = center; }
inline const osg::Vec3& getScaleCenter() const { return _scaleCenter; }
virtual osg::Matrix getMotionMatrix() const
{
return (osg::Matrix::translate(-_scaleCenter)
* osg::Matrix::scale(_scale,_scale,_scale)
* osg::Matrix::translate(_scaleCenter));
}
protected:
virtual ~ScaleUniformCommand();
private:
float _scale;
osg::Vec3 _scaleCenter;
};
/**
* Command for rotation in 3D.
*/
class OSGMANIPULATOR_EXPORT Rotate3DCommand : public MotionCommand
{
public:
Rotate3DCommand();
virtual bool execute();
virtual bool unexecute();
virtual void applyConstraint(const Constraint*);
inline void setRotation(const osg::Quat& rotation) { _rotation = rotation; }
inline const osg::Quat& getRotation() const { return _rotation; }
virtual osg::Matrix getMotionMatrix() const
{
return osg::Matrix::rotate(_rotation);
}
protected:
virtual ~Rotate3DCommand();
private:
osg::Quat _rotation;
};
}
#endif

View File

@ -0,0 +1,64 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_COMMANDMANAGER
#define OSGMANIPULATOR_COMMANDMANAGER 1
#include <osgManipulator/Dragger>
#include <osgManipulator/Selection>
#include <osgManipulator/Constraint>
namespace osgManipulator {
/**
* Command manager receives commands from draggers and dispatches them to selections.
*/
class OSGMANIPULATOR_EXPORT CommandManager : public osg::Referenced
{
public:
CommandManager();
/**
* Connect a dragger to a selection. The selection will begin listening
* to commands generated by the dragger. This can be called multiple
* times to connect many selections to a dragger.
*/
virtual bool connect(Dragger& dragger, Selection& selection);
virtual bool connect(Dragger& dragger, Constraint& constrain);
/** Disconnect the selections from a dragger. */
virtual bool disconnect(Dragger& dragger);
/** Dispatches a command. Usually called from a dragger. */
virtual void dispatch(MotionCommand& command);
/** Add all selections connected to the dragger to the command. */
void addSelectionsToCommand(MotionCommand& command, Dragger& dragger);
protected:
virtual ~CommandManager();
typedef std::multimap< osg::ref_ptr<Dragger>, osg::ref_ptr<Selection> > DraggerSelectionMap;
DraggerSelectionMap _draggerSelectionMap;
typedef std::multimap< osg::ref_ptr<Dragger>, osg::ref_ptr<Constraint> > DraggerConstraintMap;
DraggerConstraintMap _draggerConstraintMap;
};
}
#endif

View File

@ -0,0 +1,95 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_CONSTRAINT
#define OSGMANIPULATOR_CONSTRAINT 1
#include <osgManipulator/Export>
#include <osg/Node>
#include <osg/Matrix>
namespace osgManipulator {
class MotionCommand;
class TranslateInLineCommand;
class TranslateInPlaneCommand;
class Scale1DCommand;
class Scale2DCommand;
class ScaleUniformCommand;
class OSGMANIPULATOR_EXPORT Constraint : public osg::Referenced
{
public:
virtual bool constrain(MotionCommand&) const { return false; }
virtual bool constrain(TranslateInLineCommand& command) const { return constrain((MotionCommand&)command); }
virtual bool constrain(TranslateInPlaneCommand& command) const { return constrain((MotionCommand&)command); }
virtual bool constrain(Scale1DCommand& command) const { return constrain((MotionCommand&)command); }
virtual bool constrain(Scale2DCommand& command) const { return constrain((MotionCommand&)command); }
virtual bool constrain(ScaleUniformCommand& command) const { return constrain((MotionCommand&)command); }
protected:
Constraint(osg::Node& refNode) : _refNode(&refNode) {}
virtual ~Constraint() {}
osg::Node& getReferenceNode() { return *_refNode; }
const osg::Node& getReferenceNode() const { return *_refNode; }
const osg::Matrix& getLocalToWorld() const { return _localToWorld; }
const osg::Matrix& getWorldToLocal() const { return _worldToLocal; }
void computeLocalToWorldAndWorldToLocal() const;
private:
osg::ref_ptr<osg::Node> _refNode;
mutable osg::Matrix _localToWorld;
mutable osg::Matrix _worldToLocal;
};
/**
* Constraint to snap motion commands to a sugar cube grid.
*/
class OSGMANIPULATOR_EXPORT GridConstraint : public Constraint
{
public:
GridConstraint(osg::Node& refNode, const osg::Vec3d& origin, const osg::Vec3d& spacing);
void setOrigin(const osg::Vec3d origin) { _origin = origin; }
void setSpacing(const osg::Vec3d spacing) { _spacing = spacing; }
virtual bool constrain(TranslateInLineCommand& command) const;
virtual bool constrain(TranslateInPlaneCommand& command) const;
virtual bool constrain(Scale1DCommand& command) const;
virtual bool constrain(Scale2DCommand& command) const;
virtual bool constrain(ScaleUniformCommand& command) const;
protected:
virtual ~GridConstraint() {}
private:
osg::Vec3d _origin;
osg::Vec3d _spacing;
mutable osg::Matrix _startMatrix;
mutable osg::Matrix _matrix;
};
}
#endif

View File

@ -0,0 +1,134 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_DRAGGER
#define OSGMANIPULATOR_DRAGGER 1
#include <osgManipulator/Selection>
#include <osg/BoundingSphere>
#include <osgUtil/SceneView>
#include <osgUtil/IntersectVisitor>
#include <osgGA/GUIEventAdapter>
#include <osgGA/GUIActionAdapter>
namespace osgManipulator
{
class CommandManager;
class CompositeDragger;
/**
* Base class for draggers. Concrete draggers implement the pick event handler
* and generate motion commands (translate, rotate, ...) and sends these
* command to the CommandManager. The CommandManager dispatches the commands
* to all the Selections that are connected to the Dragger that generates the
* commands.
*/
class OSGMANIPULATOR_EXPORT Dragger : public Selection
{
public:
/** Set/Get the CommandManager. Draggers use CommandManager to dispatch commands. */
virtual void setCommandManager(CommandManager* cm) { _commandManager = cm; }
CommandManager* getCommandManager() { return _commandManager; }
const CommandManager* getCommandManager() const { return _commandManager; }
/**
* Set/Get parent dragger. For simple draggers parent points to itself.
* For composite draggers parent points to the parent dragger that uses
* this dragger.
*/
virtual void setParentDragger(Dragger* parent) { _parentDragger = parent; }
Dragger* getParentDragger() { return _parentDragger; }
const Dragger* getParentDragger() const { return _parentDragger; }
/** Returns 0 if this Dragger is not a CompositeDragger. */
virtual const CompositeDragger* getComposite() const { return 0; }
/** Returns 0 if this Dragger is not a CompositeDragger. */
virtual CompositeDragger* getComposite() { return 0; }
virtual bool handle(int, int, const osgUtil::SceneView&,
const osgUtil::IntersectVisitor::HitList&,
const osgUtil::IntersectVisitor::HitList::iterator&,
const osgGA::GUIEventAdapter&, osgGA::GUIActionAdapter&) { return false; }
protected:
Dragger();
virtual ~Dragger();
CommandManager* _commandManager;
Dragger* _parentDragger;
};
/**
* CompositeDragger allows to create complex draggers that are composed of a
* hierarchy of Draggers.
*/
class OSGMANIPULATOR_EXPORT CompositeDragger : public Dragger
{
public:
typedef std::vector< osg::ref_ptr<Dragger> > DraggerList;
virtual const CompositeDragger* getComposite() const { return this; }
virtual CompositeDragger* getComposite() { return this; }
virtual void setCommandManager(CommandManager* cm);
virtual void setParentDragger(Dragger* parent);
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
// Composite-specific methods below
virtual bool addDragger(Dragger* dragger);
virtual bool removeDragger(Dragger* dragger);
unsigned int getNumDraggers() const { return _draggerList.size(); }
Dragger* getDragger(unsigned int i) { return _draggerList[i].get(); }
const Dragger* getDragger(unsigned int i) const { return _draggerList[i].get(); }
bool containsDragger(const Dragger* dragger) const;
DraggerList::iterator findDragger(const Dragger* dragger);
protected:
CompositeDragger() {}
virtual ~CompositeDragger() {}
DraggerList _draggerList;
};
/**
* Culls the drawable all the time. Used by draggers to have invisible geometry
* around lines and points so that they can be picked. For example, a dragger
* could have a line with an invisible cylinder around it to enable picking on
* that line.
*/
void setDrawableToAlwaysCull(osg::Drawable& drawable);
/**
* Convenience function for setting the material color on a node.
*/
void setMaterialColor(const osg::Vec4& color, osg::Node& node);
}
#endif

View File

@ -0,0 +1,28 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_EXPORT_
#define OSGMANIPULATOR_EXPORT_ 1
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
# ifdef OSGMANIPULATOR_LIBRARY
# define OSGMANIPULATOR_EXPORT __declspec(dllexport)
# else
# define OSGMANIPULATOR_EXPORT __declspec(dllimport)
# endif /* OSGMANIPULATOR_LIBRARY */
#else
# define OSGMANIPULATOR_EXPORT
#endif
#endif

View File

@ -0,0 +1,298 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_PROJECTOR
#define OSGMANIPULATOR_PROJECTOR 1
#include <osgManipulator/Export>
#include <osg/LineSegment>
#include <osgUtil/SceneView>
namespace osgManipulator {
/**
* Base class for Projectors. Projectors maps 2D cursor motions to 3D motions.
*/
class OSGMANIPULATOR_EXPORT Projector : public osg::Referenced
{
public:
Projector();
/**
* Calculates the object/world coordinates (projectedPoint) of a window
* coordinate (pointToProject) when projected onto some shape or
* geometry (implemented in derived classes). SceneView in used for i
* projecting window coordinates into object coordinates and vice versa.
* Returns true on successful projection.
*/
virtual bool project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const = 0;
/**
* Sets the matrix for transforming the projector's local coordinate
* system to the world/object coordinate system.
*/
void setLocalToWorld(const osg::Matrix& localToWorld)
{
_localToWorld = localToWorld;
_worldToLocalDirty = true;
}
/**
* Gets the matrix for transforming the projector's local coordinate
* system to the world/object coordinate system.
*/
inline const osg::Matrix& getLocalToWorld() const { return _localToWorld; }
/**
* Gets the matrix for transforming the world/object coordinate
* system to the command's local coordinate system.
*/
inline const osg::Matrix& getWorldToLocal() const
{
if (_worldToLocalDirty)
{
_worldToLocal.invert(_localToWorld);
_worldToLocalDirty = false;
}
return _worldToLocal;
}
protected:
virtual ~Projector();
osg::Matrix _localToWorld;
mutable osg::Matrix _worldToLocal;
mutable bool _worldToLocalDirty;
};
/**
* LineProjector projects points onto the closest point on the given line.
*/
class OSGMANIPULATOR_EXPORT LineProjector : public Projector
{
public:
LineProjector();
LineProjector(const osg::Vec3& s, const osg::Vec3& e);
inline void setLine(const osg::Vec3& s, const osg::Vec3& e) { _line->start() = s; _line->end() = e; }
inline const osg::Vec3& getLineStart() const { return _line->start(); }
inline osg::Vec3& getLineStart() { return _line->start(); }
inline const osg::Vec3& getLineEnd() const { return _line->end(); }
inline osg::Vec3& getLineEnd() { return _line->end(); }
/**
* Calculates the object coordinates (projectedPoint) of a window
* coordinate (pointToProject) when projected onto the given line.
* Returns true on successful projection.
*/
virtual bool project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const;
protected:
virtual ~LineProjector();
osg::ref_ptr<osg::LineSegment> _line;
};
/**
* PlaneProjector projects points onto the given line.
*/
class OSGMANIPULATOR_EXPORT PlaneProjector : public Projector
{
public:
PlaneProjector();
PlaneProjector(const osg::Plane& plane);
inline void setPlane(const osg::Plane& plane) { _plane = plane; }
inline const osg::Plane& getPlane() const { return _plane; }
/**
* Calculates the object coordinates (projectedPoint) of a window
* coordinate (pointToProject) when projected onto the given plane.
* Returns true on successful projection.
*/
virtual bool project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const;
protected:
virtual ~PlaneProjector();
osg::Plane _plane;
};
/**
* SphereProjector projects points onto the given sphere.
*/
class OSGMANIPULATOR_EXPORT SphereProjector : public Projector
{
public:
SphereProjector();
SphereProjector(osg::Sphere& sphere);
inline void setSphere(osg::Sphere& sphere) { _sphere = &sphere; }
inline const osg::Sphere& getSphere() const { return *_sphere; }
/**
* Calculates the object coordinates (projectedPoint) of a window
* coordinate (pointToProject) when projected onto the given sphere.
* Returns true on successful projection.
*/
virtual bool project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const;
/**
* Returns true is the point is in front of the cylinder given the eye
* direction.
*/
bool isPointInFront(const osg::Vec3& point, const osgUtil::SceneView& sv, const osg::Matrix& localToWorld) const;
void setFront(bool front) { _front = front; }
protected:
virtual ~SphereProjector();
osg::ref_ptr<osg::Sphere> _sphere;
bool _front;
};
/**
* SpherePlaneProjector projects points onto a sphere, failing which it project
* onto a plane oriented to the viewing direction.
*/
class OSGMANIPULATOR_EXPORT SpherePlaneProjector : public SphereProjector
{
public:
SpherePlaneProjector();
SpherePlaneProjector(osg::Sphere& sphere);
/**
* Calculates the object coordinates (projectedPoint) of a window
* coordinate (pointToProject) when projected onto the given sphere.
* Returns true on successful projection.
*/
virtual bool project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const;
/**
* Returns true if the previous projection was on the sphere and false
* if the projection was on the plane.
*/
bool isProjectionOnSphere() const { return _onSphere; }
osg::Quat getRotation(const osg::Vec3& p1, bool p1OnSphere,
const osg::Vec3& p2, bool p2OnSphere,
float radialFactor = 0.0f) const;
protected:
virtual ~SpherePlaneProjector();
mutable osg::Plane _plane;
mutable bool _onSphere;
};
/**
* CylinderProjector projects points onto the given cylinder.
*/
class OSGMANIPULATOR_EXPORT CylinderProjector : public Projector
{
public:
CylinderProjector();
CylinderProjector(osg::Cylinder& cylinder);
inline void setCylinder(osg::Cylinder& cylinder)
{
_cylinder = &cylinder;
_cylinderAxis = osg::Vec3(0.0,0.0,1.0) * osg::Matrix(cylinder.getRotation());
_cylinderAxis.normalize();
}
inline const osg::Cylinder& getCylinder() const { return *_cylinder; }
/**
* Calculates the object coordinates (projectedPoint) of a window
* coordinate (pointToProject) when projected onto the given plane.
* Returns true on successful projection.
*/
virtual bool project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const;
/**
* Returns true is the point is in front of the cylinder given the eye
* direction.
*/
bool isPointInFront(const osg::Vec3& point, const osgUtil::SceneView& sv, const osg::Matrix& localToWorld) const;
void setFront(bool front) { _front = front; }
protected:
virtual ~CylinderProjector();
osg::ref_ptr<osg::Cylinder> _cylinder;
osg::Vec3 _cylinderAxis;
bool _front;
};
/**
* CylinderPlaneProjector projects points onto the given cylinder.
*/
class OSGMANIPULATOR_EXPORT CylinderPlaneProjector : public CylinderProjector
{
public:
CylinderPlaneProjector();
CylinderPlaneProjector(osg::Cylinder& cylinder);
/**
* Calculates the object coordinates (projectedPoint) of a window
* coordinate (pointToProject) when projected onto the given plane.
* Returns true on successful projection.
*/
virtual bool project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const;
/**
* Returns true if the previous projection was on the cylinder and
* false if the projection was on the plane.
*/
bool isProjectionOnCylinder() const { return _onCylinder; }
osg::Quat getRotation(const osg::Vec3& p1, bool p1OnCyl, const osg::Vec3& p2, bool p2OnCyl) const;
protected:
virtual ~CylinderPlaneProjector();
mutable osg::Plane _plane;
mutable bool _onCylinder;
mutable osg::Vec3 _planeLineStart, _planeLineEnd;
};
}
#endif

View File

@ -0,0 +1,74 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_ROTATECYLINDERDRAGGER
#define OSGMANIPULATOR_ROTATECYLINDERDRAGGER 1
#include <osgManipulator/Dragger>
#include <osgManipulator/Projector>
namespace osgManipulator {
/**
* Dragger for performing 3D rotation on a cylinder.
*/
class OSGMANIPULATOR_EXPORT RotateCylinderDragger : public Dragger
{
public:
RotateCylinderDragger();
/**
* Handle pick events on dragger and generate TranslateInLine commands.
*/
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
/** Set/Get color for dragger. */
inline void setColor(const osg::Vec4& color) { _color = color; setMaterialColor(_color,*this); }
inline const osg::Vec4 getColor() const { return _color; }
/**
* Set/Get pick color for dragger. Pick color is color of the dragger
* when picked. It gives a visual feedback to show that the dragger has
* been picked.
*/
inline void setPickColor(const osg::Vec4& color) { _pickColor = color; }
inline const osg::Vec4 getPickColor() const { return _pickColor; }
protected:
virtual ~RotateCylinderDragger();
osg::ref_ptr<CylinderPlaneProjector> _projector;
osg::Vec3 _prevWorldProjPt;
bool _prevPtOnCylinder;
osg::Matrix _startLocalToWorld, _startWorldToLocal;
osg::Quat _prevRotation;
osg::Vec4 _color;
osg::Vec4 _pickColor;
};
}
#endif

View File

@ -0,0 +1,73 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_ROTATESPHEREDRAGGER
#define OSGMANIPULATOR_ROTATESPHEREDRAGGER 1
#include <osgManipulator/Dragger>
#include <osgManipulator/Projector>
namespace osgManipulator {
/**
* Dragger for performing 3D rotation on a sphere.
*/
class OSGMANIPULATOR_EXPORT RotateSphereDragger : public Dragger
{
public:
RotateSphereDragger();
/**
* Handle pick events on dragger and generate TranslateInLine commands.
*/
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
/** Set/Get color for dragger. */
inline void setColor(const osg::Vec4& color) { _color = color; setMaterialColor(_color,*this); }
inline const osg::Vec4 getColor() const { return _color; }
/**
* Set/Get pick color for dragger. Pick color is color of the dragger
* when picked. It gives a visual feedback to show that the dragger has
* been picked.
*/
inline void setPickColor(const osg::Vec4& color) { _pickColor = color; }
inline const osg::Vec4 getPickColor() const { return _pickColor; }
protected:
virtual ~RotateSphereDragger();
osg::ref_ptr<SpherePlaneProjector> _projector;
osg::Vec3 _prevWorldProjPt;
bool _prevPtOnSphere;
osg::Matrix _startLocalToWorld, _startWorldToLocal;
osg::Quat _prevRotation;
osg::Vec4 _color;
osg::Vec4 _pickColor;
};
}
#endif

View File

@ -0,0 +1,98 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_SCALE1DDRAGGER
#define OSGMANIPULATOR_SCALE1DDRAGGER 1
#include <osgManipulator/Dragger>
#include <osgManipulator/Projector>
namespace osgManipulator {
/**
* Dragger for performing 1D scaling.
*/
class OSGMANIPULATOR_EXPORT Scale1DDragger : public Dragger
{
public:
enum ScaleMode
{
SCALE_WITH_ORIGIN_AS_PIVOT = 0,
SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT
};
Scale1DDragger(ScaleMode scaleMode=SCALE_WITH_ORIGIN_AS_PIVOT);
/**
* Handle pick events on dragger and generate TranslateInLine commands.
*/
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
/** Set/Get min scale for dragger. */
inline void setMinScale(float min) { _minScale = min; }
inline float getMinScale() const { return _minScale; }
/** Set/Get color for dragger. */
inline void setColor(const osg::Vec4& color) { _color = color; setMaterialColor(_color,*this); }
inline const osg::Vec4 getColor() const { return _color; }
/**
* Set/Get pick color for dragger. Pick color is color of the dragger
* when picked. It gives a visual feedback to show that the dragger has
* been picked.
*/
inline void setPickColor(const osg::Vec4& color) { _pickColor = color; }
inline const osg::Vec4 getPickColor() const { return _pickColor; }
/** Set/Get left and right handle nodes for dragger. */
inline void setLeftHandleNode (osg::Node& node) { _leftHandleNode = &node; }
inline void setRightHandleNode(osg::Node& node) { _rightHandleNode = &node; }
inline osg::Node* getLeftHandleNode() { return _leftHandleNode.get(); }
inline osg::Node* getRightHandleNode() { return _rightHandleNode.get(); }
/** Set left/right handle position. */
inline void setLeftHandlePosition(float pos) { _projector->getLineStart() = osg::Vec3(pos,0.0,0.0); }
inline float getLeftHandlePosition() const { return _projector->getLineStart()[0]; }
inline void setRightHandlePosition(float pos) { _projector->getLineEnd() = osg::Vec3(pos,0.0,0.0); }
inline float getRightHandlePosition() { return _projector->getLineEnd()[0]; }
protected:
virtual ~Scale1DDragger();
osg::ref_ptr< LineProjector > _projector;
osg::Vec3 _startProjectedPoint;
float _scaleCenter;
float _minScale;
osg::ref_ptr< osg::Node > _leftHandleNode;
osg::ref_ptr< osg::Node > _rightHandleNode;
osg::Vec4 _color;
osg::Vec4 _pickColor;
ScaleMode _scaleMode;
};
}
#endif

View File

@ -0,0 +1,114 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_SCALE2DDRAGGER
#define OSGMANIPULATOR_SCALE2DDRAGGER 1
#include <osgManipulator/Dragger>
#include <osgManipulator/Projector>
namespace osgManipulator {
/**
* Dragger for performing 2D scaling.
*/
class OSGMANIPULATOR_EXPORT Scale2DDragger : public Dragger
{
public:
enum ScaleMode
{
SCALE_WITH_ORIGIN_AS_PIVOT = 0,
SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT
};
Scale2DDragger(ScaleMode scaleMode=SCALE_WITH_ORIGIN_AS_PIVOT);
/**
* Handle pick events on dragger and generate TranslateInLine commands.
*/
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
/** Set/Get min scale for dragger. */
inline void setMinScale(const osg::Vec2& min) { _minScale = min; }
inline const osg::Vec2& getMinScale() const { return _minScale; }
/** Set/Get color for dragger. */
inline void setColor(const osg::Vec4& color) { _color = color; setMaterialColor(_color,*this); }
inline const osg::Vec4 getColor() const { return _color; }
/**
* Set/Get pick color for dragger. Pick color is color of the dragger
* when picked. It gives a visual feedback to show that the dragger has
* been picked.
*/
inline void setPickColor(const osg::Vec4& color) { _pickColor = color; }
inline const osg::Vec4 getPickColor() const { return _pickColor; }
/** Set/Get the handle nodes for dragger. */
inline void setTopLeftHandleNode (osg::Node& node) { _topLeftHandleNode = &node; }
inline osg::Node* getTopLeftHandleNode() { return _topLeftHandleNode.get(); }
inline void setBottomLeftHandleNode (osg::Node& node) { _bottomLeftHandleNode = &node; }
inline osg::Node* getBottomLeftHandleNode() { return _bottomLeftHandleNode.get(); }
inline void setTopRightHandleNode(osg::Node& node) { _topRightHandleNode = &node; }
inline osg::Node* getTopRightHandleNode() { return _topRightHandleNode.get(); }
inline void setBottomRightHandleNode(osg::Node& node) { _bottomRightHandleNode = &node; }
inline osg::Node* getBottomRightHandleNode() { return _bottomRightHandleNode.get(); }
/** Set/Get the handle nodes postion for dragger. */
inline void setTopLeftHandlePosition(const osg::Vec2& pos) { _topLeftHandlePosition = pos; }
const osg::Vec2& getTopLeftHandlePosition() { return _topLeftHandlePosition; }
inline void setBottomLeftHandlePosition(const osg::Vec2& pos) { _bottomLeftHandlePosition = pos; }
const osg::Vec2& getBottomLeftHandlePosition() { return _bottomLeftHandlePosition; }
inline void setTopRightHandlePosition(const osg::Vec2& pos) { _topRightHandlePosition = pos; }
const osg::Vec2& getTopRightHandlePosition() { return _topRightHandlePosition; }
inline void setBottomRightHandlePosition(const osg::Vec2& pos){ _bottomRightHandlePosition = pos; }
const osg::Vec2& getBottomRightHandlePosition() { return _bottomRightHandlePosition; }
protected:
virtual ~Scale2DDragger();
osg::ref_ptr< PlaneProjector > _projector;
osg::Vec3 _startProjectedPoint;
osg::Vec2 _scaleCenter;
osg::Vec2 _referencePoint;
osg::Vec2 _minScale;
osg::ref_ptr< osg::Node > _topLeftHandleNode;
osg::ref_ptr< osg::Node > _bottomLeftHandleNode;
osg::ref_ptr< osg::Node > _topRightHandleNode;
osg::ref_ptr< osg::Node > _bottomRightHandleNode;
osg::Vec2 _topLeftHandlePosition;
osg::Vec2 _bottomLeftHandlePosition;
osg::Vec2 _topRightHandlePosition;
osg::Vec2 _bottomRightHandlePosition;
osg::Vec4 _color;
osg::Vec4 _pickColor;
ScaleMode _scaleMode;
};
}
#endif

View File

@ -0,0 +1,46 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_SCALEAXISDRAGGER
#define OSGMANIPULATOR_SCALEAXISDRAGGER 1
#include <osgManipulator/Scale1DDragger>
namespace osgManipulator {
/**
* Dragger for performing scaling on all 3 axes.
*/
class OSGMANIPULATOR_EXPORT ScaleAxisDragger : public CompositeDragger
{
public:
ScaleAxisDragger();
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
protected:
virtual ~ScaleAxisDragger();
osg::ref_ptr< Scale1DDragger > _xDragger;
osg::ref_ptr< Scale1DDragger > _yDragger;
osg::ref_ptr< Scale1DDragger > _zDragger;
};
}
#endif

View File

@ -0,0 +1,68 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_SELECTION
#define OSGMANIPULATOR_SELECTION 1
#include <osgManipulator/Export>
#include <osg/MatrixTransform>
namespace osgManipulator {
class MotionCommand;
class TranslateInLineCommand;
class TranslateInPlaneCommand;
class Scale1DCommand;
class Scale2DCommand;
class ScaleUniformCommand;
class Rotate3DCommand;
/** Computes the nodepath from the given node all the way upto the root. */
extern OSGMANIPULATOR_EXPORT void computeNodePathToRoot(osg::Node& node, osg::NodePath& np);
/**
* Selection listens to motion commands generated by draggers.
*/
class OSGMANIPULATOR_EXPORT Selection : public osg::MatrixTransform
{
public:
Selection();
/**
* Receive motion commands and set the MatrixTransform accordingly to
* transform selections. Returns true on success.
*/
virtual bool receive(const MotionCommand&);
virtual bool receive(const TranslateInLineCommand& command) { return receive((MotionCommand&)command); }
virtual bool receive(const TranslateInPlaneCommand& command) { return receive((MotionCommand&)command); }
virtual bool receive(const Scale1DCommand& command) { return receive((MotionCommand&)command); }
virtual bool receive(const Scale2DCommand& command) { return receive((MotionCommand&)command); }
virtual bool receive(const ScaleUniformCommand& command) { return receive((MotionCommand&)command); }
virtual bool receive(const Rotate3DCommand& command) { return receive((MotionCommand&)command); }
protected:
virtual ~Selection();
osg::Matrix _startMotionMatrix;
osg::Matrix _localToWorld;
osg::Matrix _worldToLocal;
};
}
#endif

View File

@ -0,0 +1,47 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TABBOXDRAGGER
#define OSGMANIPULATOR_TABBOXDRAGGER 1
#include <osgManipulator/TabPlaneDragger>
namespace osgManipulator {
/**
* TabBoxDragger consists of 6 TabPlaneDraggers to form a box dragger that
* performs translation and scaling.
*/
class OSGMANIPULATOR_EXPORT TabBoxDragger : public CompositeDragger
{
public:
TabBoxDragger();
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
void setPlaneColor(const osg::Vec4& color);
protected:
virtual ~TabBoxDragger();
std::vector< osg::ref_ptr< TabPlaneDragger > > _planeDraggers;
};
}
#endif

View File

@ -0,0 +1,59 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TABPLANEDRAGGER
#define OSGMANIPULATOR_TABPLANEDRAGGER 1
#include <osgManipulator/TranslatePlaneDragger>
#include <osgManipulator/Scale2DDragger>
#include <osgManipulator/Scale1DDragger>
namespace osgManipulator {
/**
* Tab plane dragger consists of a plane with tabs on it's corners and edges
* for scaling. And the plane is used as a 2D translate dragger.
*/
class OSGMANIPULATOR_EXPORT TabPlaneDragger : public CompositeDragger
{
public:
TabPlaneDragger();
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hit,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry(bool twoSidedHandle = true);
void setPlaneColor(const osg::Vec4& color) { _translateDragger->setColor(color); }
protected:
virtual ~TabPlaneDragger();
osg::ref_ptr< TranslatePlaneDragger > _translateDragger;
osg::ref_ptr< Scale2DDragger > _cornerScaleDragger;
osg::ref_ptr< Scale1DDragger > _horzEdgeScaleDragger;
osg::ref_ptr< Scale1DDragger > _vertEdgeScaleDragger;
float _handleScaleFactor;
};
}
#endif

View File

@ -0,0 +1,48 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TABPLANETRACKBALLDRAGGER
#define OSGMANIPULATOR_TABPLANETRACKBALLDRAGGER 1
#include <osgManipulator/TrackballDragger>
#include <osgManipulator/TabPlaneDragger>
namespace osgManipulator {
/**
* Dragger for performing rotation in all axes.
*/
class OSGMANIPULATOR_EXPORT TabPlaneTrackballDragger : public CompositeDragger
{
public:
TabPlaneTrackballDragger();
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
void setPlaneColor(const osg::Vec4& color) { _tabPlaneDragger->setPlaneColor(color); }
protected:
virtual ~TabPlaneTrackballDragger();
osg::ref_ptr<TrackballDragger> _trackballDragger;
osg::ref_ptr<TabPlaneDragger> _tabPlaneDragger;
};
}
#endif

View File

@ -0,0 +1,48 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TRACKBALLDRAGGER
#define OSGMANIPULATOR_TRACKBALLDRAGGER 1
#include <osgManipulator/RotateCylinderDragger>
#include <osgManipulator/RotateSphereDragger>
namespace osgManipulator {
/**
* Dragger for performing rotation in all axes.
*/
class OSGMANIPULATOR_EXPORT TrackballDragger : public CompositeDragger
{
public:
TrackballDragger(bool useAutoTransform=false);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
protected:
virtual ~TrackballDragger();
osg::ref_ptr<RotateCylinderDragger> _xDragger;
osg::ref_ptr<RotateCylinderDragger> _yDragger;
osg::ref_ptr<RotateCylinderDragger> _zDragger;
osg::ref_ptr<RotateSphereDragger> _xyzDragger;
};
}
#endif

View File

@ -0,0 +1,71 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TRANSLATE1DDRAGGER
#define OSGMANIPULATOR_TRANSLATE1DDRAGGER 1
#include <osgManipulator/Dragger>
#include <osgManipulator/Projector>
namespace osgManipulator {
/**
* Dragger for performing 1D translation.
*/
class OSGMANIPULATOR_EXPORT Translate1DDragger : public Dragger
{
public:
Translate1DDragger();
Translate1DDragger(const osg::Vec3& s, const osg::Vec3& e);
/** Handle pick events on dragger and generate TranslateInLine commands. */
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hit,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
/** Set/Get color for dragger. */
inline void setColor(const osg::Vec4& color) { _color = color; setMaterialColor(_color,*this); }
inline const osg::Vec4 getColor() const { return _color; }
/** Set/Get pick color for dragger. Pick color is color of the dragger when picked.
It gives a visual feedback to show that the dragger has been picked. */
inline void setPickColor(const osg::Vec4& color) { _pickColor = color; }
inline const osg::Vec4 getPickColor() const { return _pickColor; }
inline void setCheckForNodeInNodePath(bool onOff) { _checkForNodeInNodePath = onOff; }
protected:
virtual ~Translate1DDragger();
osg::ref_ptr< LineProjector > _projector;
osg::Vec3 _startProjectedPoint;
osg::Vec4 _color;
osg::Vec4 _pickColor;
bool _checkForNodeInNodePath;
};
}
#endif

View File

@ -0,0 +1,69 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TRANSLATE2DDRAGGER
#define OSGMANIPULATOR_TRANSLATE2DDRAGGER 1
#include <osgManipulator/Dragger>
#include <osgManipulator/Projector>
#include <osg/PolygonOffset>
namespace osgManipulator {
/**
* Dragger for performing 2D translation.
*/
class OSGMANIPULATOR_EXPORT Translate2DDragger : public Dragger
{
public:
Translate2DDragger();
Translate2DDragger(const osg::Plane& plane);
/** Handle pick events on dragger and generate TranslateInLine commands. */
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hit,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
/** Set/Get color for dragger. */
inline void setColor(const osg::Vec4& color) { _color = color; setMaterialColor(_color,*this); }
inline const osg::Vec4 getColor() const { return _color; }
/** Set/Get pick color for dragger. Pick color is color of the dragger when picked.
It gives a visual feedback to show that the dragger has been picked. */
inline void setPickColor(const osg::Vec4& color) { _pickColor = color; }
inline const osg::Vec4 getPickColor() const { return _pickColor; }
protected:
virtual ~Translate2DDragger();
osg::ref_ptr< PlaneProjector > _projector;
osg::Vec3 _startProjectedPoint;
osg::Vec4 _color;
osg::Vec4 _pickColor;
osg::ref_ptr<osg::PolygonOffset> _polygonOffset;
};
}
#endif

View File

@ -0,0 +1,46 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TRANSLATEAXISDRAGGER
#define OSGMANIPULATOR_TRANSLATEAXISDRAGGER 1
#include <osgManipulator/Translate1DDragger>
namespace osgManipulator {
/**
* Dragger for performing translation in all three axes.
*/
class OSGMANIPULATOR_EXPORT TranslateAxisDragger : public CompositeDragger
{
public:
TranslateAxisDragger();
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
protected:
virtual ~TranslateAxisDragger();
osg::ref_ptr< Translate1DDragger > _xDragger;
osg::ref_ptr< Translate1DDragger > _yDragger;
osg::ref_ptr< Translate1DDragger > _zDragger;
};
}
#endif

View File

@ -0,0 +1,58 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#ifndef OSGMANIPULATOR_TRANSLATEPLANEDRAGGER
#define OSGMANIPULATOR_TRANSLATEPLANEDRAGGER 1
#include <osgManipulator/Translate2DDragger>
#include <osgManipulator/Translate1DDragger>
namespace osgManipulator {
/**
* Tab plane dragger consists of a plane with tabs on it's corners and edges
* for scaling. And the plane is used as a 2D translate dragger.
*/
class OSGMANIPULATOR_EXPORT TranslatePlaneDragger : public CompositeDragger
{
public:
TranslatePlaneDragger();
virtual bool handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hitList,
const osgUtil::IntersectVisitor::HitList::iterator& hit,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
/** Setup default geometry for dragger. */
void setupDefaultGeometry();
inline void setColor(const osg::Vec4& color) { if (_translate2DDragger.valid()) _translate2DDragger->setColor(color); }
Translate1DDragger* getTranslate1DDragger() { return _translate1DDragger.get(); }
Translate2DDragger* getTranslate2DDragger() { return _translate2DDragger.get(); }
protected:
virtual ~TranslatePlaneDragger();
osg::ref_ptr< Translate2DDragger > _translate2DDragger;
osg::ref_ptr< Translate1DDragger > _translate1DDragger;
bool _usingTranslate1DDragger;
};
}
#endif

View File

@ -0,0 +1,192 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/AntiSquish>
using namespace osgManipulator;
namespace
{
class AntiSquishCallback: public osg::NodeCallback
{
public:
AntiSquishCallback(AntiSquish* asq) : osg::NodeCallback(), _antiSquish(asq) {}
virtual ~AntiSquishCallback() {};
virtual void operator() (osg::Node*, osg::NodeVisitor* nv)
{
// Get the node path.
osg::NodePath np = nv->getNodePath();
// Remove the last node which is the anti squish node itself.
np.pop_back();
// Get the accumulated modeling matrix.
osg::Matrix localToWorld = computeLocalToWorld(np);
// compute the unsquished matrix.
bool flag = false;
osg::Matrix _unsquishedMatrix = _antiSquish->computeUnSquishedMatrix(localToWorld, flag);
if (flag)
_antiSquish->setMatrix(_unsquishedMatrix);
}
protected:
AntiSquish* _antiSquish;
};
}
AntiSquish::AntiSquish() : _usePivot(true), _usePosition(false)
{
_asqCallback = new AntiSquishCallback(this);
setUpdateCallback(_asqCallback);
}
AntiSquish::AntiSquish(const osg::Vec3& pivot) : _pivot(pivot), _usePivot(true), _usePosition(false)
{
_asqCallback = new AntiSquishCallback(this);
setUpdateCallback(_asqCallback);
}
AntiSquish::AntiSquish(const osg::Vec3& pivot, const osg::Vec3& pos)
: _pivot(pivot), _usePivot(true), _position(pos), _usePosition(true)
{
_asqCallback = new AntiSquishCallback(this);
setUpdateCallback(_asqCallback);
}
AntiSquish::AntiSquish(const AntiSquish& pat,const osg::CopyOp& copyop) :
MatrixTransform(pat,copyop),
_asqCallback(pat._asqCallback),
_pivot(pat._pivot),
_usePivot(pat._usePivot),
_position(pat._position),
_usePosition(pat._usePosition),
_cachedLocalToWorld(pat._cachedLocalToWorld)
{
}
AntiSquish::~AntiSquish()
{
}
osg::Matrix AntiSquish::computeUnSquishedMatrix(const osg::Matrix& LTW, bool& flag)
{
osg::Vec3d t, s;
osg::Quat r, so;
if (LTW == _cachedLocalToWorld && _dirty == false)
{
flag = false;
return osg::Matrix::identity();
}
_cachedLocalToWorld = LTW;
LTW.decompose(t, r, s, so);
// Let's take an average of the scale.
double av = (s[0] + s[1] + s[2])/3.0;
s[0] = av; s[1] = av; s[2]=av;
if (av == 0)
{
flag = false;
return osg::Matrix::identity();
}
osg::Matrix unsquished;
//
// Final Matrix: [-Pivot][SO]^[S][SO][R][T][Pivot][LOCALTOWORLD]^[position]
// OR [SO]^[S][SO][R][T][LOCALTOWORLD]^
//
if (_usePivot)
{
osg::Matrix tmpPivot;
tmpPivot.setTrans(-_pivot);
unsquished.postMult(tmpPivot);
osg::Matrix tmps, invtmps;
so.get(tmps);
invtmps = osg::Matrix::inverse(tmps);
if (invtmps.isNaN())
{
flag = false;
return osg::Matrix::identity();
}
//SO^
unsquished.postMult(invtmps);
//S
unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2]));
//SO
unsquished.postMult(tmps);
tmpPivot.makeIdentity();
osg::Matrix tmpr;
r.get(tmpr);
//R
unsquished.postMult(tmpr);
//T
unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2]));
osg::Matrix invltw;
invltw = osg::Matrix::inverse(LTW);
if (invltw.isNaN())
{
flag =false;
return osg::Matrix::identity();
}
// LTW^
unsquished.postMult( invltw );
// Position
tmpPivot.makeIdentity();
if (_usePosition)
tmpPivot.setTrans(_position);
else
tmpPivot.setTrans(_pivot);
unsquished.postMult(tmpPivot);
}
else
{
osg::Matrix tmps, invtmps;
so.get(tmps);
invtmps = osg::Matrix::inverse(tmps);
unsquished.postMult(invtmps);
unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2]));
unsquished.postMult(tmps);
osg::Matrix tmpr;
r.get(tmpr);
unsquished.postMult(tmpr);
unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2]));
unsquished.postMult( osg::Matrix::inverse(LTW) );
}
if (unsquished.isNaN())
{
flag = false;
return osg::Matrix::identity();
}
flag = true;
_dirty = false;
return unsquished;
}

View File

@ -0,0 +1,321 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Command>
#include <osgManipulator/Selection>
#include <osgManipulator/Constraint>
#include <algorithm>
using namespace osgManipulator;
///////////////////////////////////////////////////////////////////////////////
//
// Motion Command base class.
//
MotionCommand::MotionCommand() : _stage(NONE)
{
}
MotionCommand::~MotionCommand()
{
}
void MotionCommand::addSelection(Selection* selection)
{
_selectionList.push_back(selection);
}
void MotionCommand::removeSelection(Selection* selection)
{
_selectionList.erase(std::remove(_selectionList.begin(), _selectionList.end(), selection),
_selectionList.end());
}
///////////////////////////////////////////////////////////////////////////////
//
// Translate in line command.
//
TranslateInLineCommand::TranslateInLineCommand()
{
_line = new osg::LineSegment;
}
TranslateInLineCommand::TranslateInLineCommand(const osg::Vec3& s, const osg::Vec3& e)
{
_line = new osg::LineSegment(s,e);
}
TranslateInLineCommand::~TranslateInLineCommand()
{
}
bool TranslateInLineCommand::execute()
{
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*this);
}
return true;
}
bool TranslateInLineCommand::unexecute()
{
osg::ref_ptr<TranslateInLineCommand> inverse = new TranslateInLineCommand();
*inverse = *this;
inverse->setTranslation(-_translation);
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*inverse);
}
return true;
}
void TranslateInLineCommand::applyConstraint(const Constraint* constraint)
{
if (constraint) constraint->constrain(*this);
}
///////////////////////////////////////////////////////////////////////////////
//
// Translate in plane command.
//
TranslateInPlaneCommand::TranslateInPlaneCommand()
{
}
TranslateInPlaneCommand::TranslateInPlaneCommand(const osg::Plane& plane) : _plane(plane)
{
}
TranslateInPlaneCommand::~TranslateInPlaneCommand()
{
}
bool TranslateInPlaneCommand::execute()
{
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*this);
}
return true;
}
bool TranslateInPlaneCommand::unexecute()
{
osg::ref_ptr<TranslateInPlaneCommand> inverse = new TranslateInPlaneCommand();
*inverse = *this;
inverse->setTranslation(-_translation);
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*inverse);
}
return true;
}
void TranslateInPlaneCommand::applyConstraint(const Constraint* constraint)
{
if (constraint) constraint->constrain(*this);
}
///////////////////////////////////////////////////////////////////////////////
//
// Scale 1D command.
//
Scale1DCommand::Scale1DCommand() : _scale(1.0f)
{
}
Scale1DCommand::~Scale1DCommand()
{
}
bool Scale1DCommand::execute()
{
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*this);
}
return true;
}
bool Scale1DCommand::unexecute()
{
osg::ref_ptr<Scale1DCommand> inverse = new Scale1DCommand();
*inverse = *this;
if (_scale) inverse->setScale(1.0/_scale);
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*inverse);
}
return true;
}
void Scale1DCommand::applyConstraint(const Constraint* constraint)
{
if (constraint) constraint->constrain(*this);
}
///////////////////////////////////////////////////////////////////////////////
//
// Scale 2D command.
//
Scale2DCommand::Scale2DCommand() : _scale(1.0,1.0)
{
}
Scale2DCommand::~Scale2DCommand()
{
}
bool Scale2DCommand::execute()
{
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*this);
}
return true;
}
bool Scale2DCommand::unexecute()
{
osg::ref_ptr<Scale2DCommand> inverse = new Scale2DCommand();
*inverse = *this;
if (_scale[0] && _scale[1])
inverse->setScale(osg::Vec2(1.0/_scale[0],1.0/_scale[1]));
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*inverse);
}
return true;
}
void Scale2DCommand::applyConstraint(const Constraint* constraint)
{
if (constraint) constraint->constrain(*this);
}
///////////////////////////////////////////////////////////////////////////////
//
// Scale uniform command.
//
ScaleUniformCommand::ScaleUniformCommand() : _scale(1.0f)
{
}
ScaleUniformCommand::~ScaleUniformCommand()
{
}
bool ScaleUniformCommand::execute()
{
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*this);
}
return true;
}
bool ScaleUniformCommand::unexecute()
{
osg::ref_ptr<ScaleUniformCommand> inverse = new ScaleUniformCommand();
*inverse = *this;
if (_scale) inverse->setScale(1.0/_scale);
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*inverse);
}
return true;
}
void ScaleUniformCommand::applyConstraint(const Constraint* constraint)
{
if (constraint) constraint->constrain(*this);
}
///////////////////////////////////////////////////////////////////////////////
//
// Rotate 3D command.
//
Rotate3DCommand::Rotate3DCommand()
{
}
Rotate3DCommand::~Rotate3DCommand()
{
}
bool Rotate3DCommand::execute()
{
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*this);
}
return true;
}
bool Rotate3DCommand::unexecute()
{
osg::ref_ptr<Rotate3DCommand> inverse = new Rotate3DCommand();
*inverse = *this;
inverse->setRotation(_rotation.inverse());
for (SelectionList::iterator iter = getSelectionList().begin();
iter != getSelectionList().end();
++iter)
{
(*iter)->receive(*inverse);
}
return true;
}
void Rotate3DCommand::applyConstraint(const Constraint* constraint)
{
if (constraint) constraint->constrain(*this);
}

View File

@ -0,0 +1,124 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/CommandManager>
#include <osgManipulator/Command>
using namespace osgManipulator;
CommandManager::CommandManager()
{
}
CommandManager::~CommandManager()
{
}
bool CommandManager::connect(Dragger& dragger, Selection& selection)
{
dragger.setCommandManager(this);
// Check to see if the selection is already associated with the dragger.
if (_draggerSelectionMap.count(&dragger) > 0)
{
std::pair<DraggerSelectionMap::iterator,DraggerSelectionMap::iterator> s;
s = _draggerSelectionMap.equal_range(&dragger);
for (DraggerSelectionMap::iterator iter = s.first; iter != s.second; ++iter)
{
if (iter->second == &selection)
return false;
}
}
// Associate selection with dragger
_draggerSelectionMap.insert(DraggerSelectionMap::value_type(&dragger,&selection));
return true;
}
bool CommandManager::connect(Dragger& dragger, Constraint& constraint)
{
dragger.setCommandManager(this);
// Check to see if the selection is already associated with the dragger.
if (_draggerConstraintMap.count(&dragger) > 0)
{
std::pair<DraggerConstraintMap::iterator,DraggerConstraintMap::iterator> s;
s = _draggerConstraintMap.equal_range(&dragger);
for (DraggerConstraintMap::iterator iter = s.first; iter != s.second; ++iter)
{
if (iter->second == &constraint)
return false;
}
}
// Associate selection with dragger
_draggerConstraintMap.insert(DraggerConstraintMap::value_type(&dragger,&constraint));
return true;
}
bool CommandManager::disconnect(Dragger& dragger)
{
_draggerSelectionMap.erase(&dragger);
_draggerConstraintMap.erase(&dragger);
return true;
}
void CommandManager::dispatch(MotionCommand& command)
{
command.execute();
}
void CommandManager::addSelectionsToCommand(MotionCommand& command, Dragger& dragger)
{
// Apply constraints to the command.
if (_draggerConstraintMap.count(&dragger) > 0)
{
// Get all the selections assoicated with this dragger.
std::pair<DraggerConstraintMap::iterator,DraggerConstraintMap::iterator> s;
s = _draggerConstraintMap.equal_range(&dragger);
for (DraggerConstraintMap::iterator iter = s.first; iter != s.second; ++iter)
{
// Add the selection to the command.
if (iter->second.valid())
{
command.applyConstraint(iter->second.get());
}
}
}
// Add the dragger to the selection list first.
command.addSelection(&dragger);
// Add the remaining selections.
if (_draggerSelectionMap.count(&dragger) > 0)
{
// Get all the selections assoicated with this dragger.
std::pair<DraggerSelectionMap::iterator,DraggerSelectionMap::iterator> s;
s = _draggerSelectionMap.equal_range(&dragger);
for (DraggerSelectionMap::iterator iter = s.first; iter != s.second; ++iter)
{
// Add the selection to the command.
if (iter->second.valid())
{
command.addSelection(iter->second.get());
}
}
}
}

View File

@ -0,0 +1,165 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Constraint>
#include <osgManipulator/Command>
#include <osg/Vec2d>
#include <math.h>
using namespace osgManipulator;
namespace
{
double round_to_nearest_int(double x) { return floor(x+0.5); }
osg::Vec3d snap_point_to_grid(const osg::Vec3d& point, const osg::Vec3d& origin, const osg::Vec3d& spacing)
{
osg::Vec3d scale;
scale[0] = spacing[0] ? round_to_nearest_int((point[0] - origin[0]) / spacing[0]) : 1.0;
scale[1] = spacing[1] ? round_to_nearest_int((point[1] - origin[1]) / spacing[1]) : 1.0;
scale[2] = spacing[2] ? round_to_nearest_int((point[2] - origin[2]) / spacing[2]) : 1.0;
osg::Vec3d snappedPoint = origin;
snappedPoint += osg::Vec3(scale[0]*spacing[0],scale[1]*spacing[1],scale[2]*spacing[2]);
return snappedPoint;
}
}
void Constraint::computeLocalToWorldAndWorldToLocal() const
{
osg::NodePath pathToRoot;
computeNodePathToRoot(const_cast<osg::Node&>(getReferenceNode()),pathToRoot);
_localToWorld = osg::computeLocalToWorld(pathToRoot);
_worldToLocal = osg::computeWorldToLocal(pathToRoot);
}
GridConstraint::GridConstraint(osg::Node& refNode, const osg::Vec3d& origin, const osg::Vec3d& spacing)
: Constraint(refNode), _origin(origin), _spacing(spacing)
{
}
bool GridConstraint::constrain(TranslateInLineCommand& command) const
{
if (command.getStage() == osgManipulator::MotionCommand::START)
computeLocalToWorldAndWorldToLocal();
else if (command.getStage() == osgManipulator::MotionCommand::FINISH)
return true;
osg::Vec3 translatedPoint = command.getLineStart() + command.getTranslation();
osg::Vec3d localTranslatedPoint = (osg::Vec3d(translatedPoint)
* command.getLocalToWorld() * getWorldToLocal());
osg::Vec3d newLocalTranslatedPoint = snap_point_to_grid(localTranslatedPoint,
_origin,
_spacing);
command.setTranslation(newLocalTranslatedPoint * getLocalToWorld() * command.getWorldToLocal() - command.getLineStart());
return true;
}
bool GridConstraint::constrain(TranslateInPlaneCommand& command) const
{
if (command.getStage() == osgManipulator::MotionCommand::START)
computeLocalToWorldAndWorldToLocal();
else if (command.getStage() == osgManipulator::MotionCommand::FINISH)
return true;
osg::Matrix commandToConstraint = command.getLocalToWorld() * getWorldToLocal();
osg::Matrix constraintToCommand = getLocalToWorld() * command.getWorldToLocal();
// Snap the reference point to grid.
osg::Vec3d localRefPoint = command.getReferencePoint() * commandToConstraint;
osg::Vec3d snappedLocalRefPoint = snap_point_to_grid(localRefPoint, _origin, _spacing);
osg::Vec3d snappedCmdRefPoint = snappedLocalRefPoint * constraintToCommand;
// Snap the translated point to grid.
osg::Vec3 translatedPoint = snappedCmdRefPoint + command.getTranslation();
osg::Vec3d localTranslatedPoint = osg::Vec3d(translatedPoint) * commandToConstraint;
osg::Vec3d newLocalTranslatedPoint = snap_point_to_grid(localTranslatedPoint, _origin, _spacing);
// Set the snapped translation.
command.setTranslation(newLocalTranslatedPoint * constraintToCommand - snappedCmdRefPoint);
return true;
}
bool GridConstraint::constrain(Scale1DCommand& command) const
{
if (command.getStage() == osgManipulator::MotionCommand::START)
computeLocalToWorldAndWorldToLocal();
else if (command.getStage() == osgManipulator::MotionCommand::FINISH)
return true;
double scaledPoint = (command.getReferencePoint() - command.getScaleCenter()) * command.getScale() + command.getScaleCenter();
osg::Matrix constraintToCommand = getLocalToWorld() * command.getWorldToLocal();
osg::Vec3d commandOrigin = _origin * constraintToCommand;
osg::Vec3d commandSpacing = (_origin + _spacing) * constraintToCommand - commandOrigin;
double spacingFactor = commandSpacing[0] ? round_to_nearest_int((scaledPoint-commandOrigin[0])/commandSpacing[0]) : 1.0;
double snappedScaledPoint = commandOrigin[0] + commandSpacing[0] * spacingFactor;
double denom = (command.getReferencePoint() - command.getScaleCenter());
double snappedScale = (denom) ? (snappedScaledPoint - command.getScaleCenter()) / denom : 1.0;
if (snappedScale < command.getMinScale()) snappedScale = command.getMinScale();
command.setScale(snappedScale);
return true;
}
bool GridConstraint::constrain(Scale2DCommand& command) const
{
if (command.getStage() == osgManipulator::MotionCommand::START)
computeLocalToWorldAndWorldToLocal();
else if (command.getStage() == osgManipulator::MotionCommand::FINISH)
return true;
osg::Vec2d scaledPoint = command.getReferencePoint() - command.getScaleCenter();
scaledPoint[0] *= command.getScale()[0];
scaledPoint[1] *= command.getScale()[1];
scaledPoint += command.getScaleCenter();
osg::Matrix constraintToCommand = getLocalToWorld() * command.getWorldToLocal();
osg::Vec3d commandOrigin = _origin * constraintToCommand;
osg::Vec3d commandSpacing = (_origin + _spacing) * constraintToCommand - commandOrigin;
osg::Vec2d spacingFactor;
spacingFactor[0] = commandSpacing[0] ? round_to_nearest_int((scaledPoint[0] - commandOrigin[0])/commandSpacing[0]) : 1.0;
spacingFactor[1] = commandSpacing[2] ? round_to_nearest_int((scaledPoint[1] - commandOrigin[2])/commandSpacing[2]) : 1.0;
osg::Vec2d snappedScaledPoint = (osg::Vec2d(commandOrigin[0],commandOrigin[2])
+ osg::Vec2d(commandSpacing[0]*spacingFactor[0],
commandSpacing[2]*spacingFactor[1]));
osg::Vec2d denom = command.getReferencePoint() - command.getScaleCenter();
osg::Vec2 snappedScale;
snappedScale[0] = denom[0] ? (snappedScaledPoint[0] - command.getScaleCenter()[0]) / denom[0] : 1.0;
snappedScale[1] = denom[1] ? (snappedScaledPoint[1] - command.getScaleCenter()[1]) / denom[1] : 1.0;
if (snappedScale[0] < command.getMinScale()[0]) snappedScale[0] = command.getMinScale()[0];
if (snappedScale[1] < command.getMinScale()[1]) snappedScale[1] = command.getMinScale()[1];
command.setScale(snappedScale);
return true;
}
bool GridConstraint::constrain(ScaleUniformCommand&) const
{
// Can you correctly snap a ScaleUniformCommand using a Grid constraint that has
// different spacings in the three axis??
return false;
}

View File

@ -0,0 +1,127 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Dragger>
#include <osg/Material>
using namespace osgManipulator;
Dragger::Dragger() : _commandManager(0)
{
_parentDragger = this;
}
Dragger::~Dragger()
{
}
bool CompositeDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hl, const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
for (DraggerList::iterator itr=_draggerList.begin(); itr!=_draggerList.end(); ++itr)
{
if ((*itr)->handle(pixel_x, pixel_y, sv, hl, hitIter, ea, aa))
return true;
}
return false;
}
bool CompositeDragger::containsDragger( const Dragger* dragger ) const
{
for (DraggerList::const_iterator itr = _draggerList.begin(); itr != _draggerList.end(); ++itr)
{
if (itr->get() == dragger) return true;
}
return false;
}
CompositeDragger::DraggerList::iterator CompositeDragger::findDragger( const Dragger* dragger )
{
for (DraggerList::iterator itr = _draggerList.begin(); itr != _draggerList.end(); ++itr)
{
if (itr->get() == dragger) return itr;
}
return _draggerList.end();
}
bool CompositeDragger::addDragger(Dragger *dragger)
{
if (dragger && !containsDragger(dragger))
{
_draggerList.push_back(dragger);
return true;
}
else return false;
}
bool CompositeDragger::removeDragger(Dragger *dragger)
{
DraggerList::iterator itr = findDragger(dragger);
if (itr != _draggerList.end())
{
_draggerList.erase(itr);
return true;
}
else return false;
}
void CompositeDragger::setCommandManager(CommandManager* cm)
{
for (DraggerList::iterator itr = _draggerList.begin(); itr != _draggerList.end(); ++itr)
{
(*itr)->setCommandManager(cm);
}
Dragger::setCommandManager(cm);
}
void CompositeDragger::setParentDragger(Dragger* dragger)
{
for (DraggerList::iterator itr = _draggerList.begin(); itr != _draggerList.end(); ++itr)
{
(*itr)->setParentDragger(dragger);
}
Dragger::setParentDragger(dragger);
}
class ForceCullCallback : public osg::Drawable::CullCallback
{
public:
virtual bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const
{
return true;
}
};
void osgManipulator::setDrawableToAlwaysCull(osg::Drawable& drawable)
{
ForceCullCallback* cullCB = new ForceCullCallback;
drawable.setCullCallback (cullCB);
}
void osgManipulator::setMaterialColor(const osg::Vec4& color, osg::Node& node)
{
osg::Material* mat = dynamic_cast<osg::Material*>(node.getOrCreateStateSet()->getAttribute(osg::StateAttribute::MATERIAL));
if (! mat)
{
mat = new osg::Material;
node.getOrCreateStateSet()->setAttribute(mat);
}
mat->setDiffuse(osg::Material::FRONT_AND_BACK, color);
}

View File

@ -0,0 +1,37 @@
TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES = \
AntiSquish.cpp \
Command.cpp \
CommandManager.cpp \
Constraint.cpp \
Dragger.cpp \
Projector.cpp \
RotateCylinderDragger.cpp \
RotateSphereDragger.cpp \
Scale1DDragger.cpp \
Scale2DDragger.cpp \
ScaleAxisDragger.cpp \
Selection.cpp \
TabBoxDragger.cpp \
TabPlaneDragger.cpp \
TabPlaneTrackballDragger.cpp \
TrackballDragger.cpp \
Translate1DDragger.cpp \
Translate2DDragger.cpp \
TranslateAxisDragger.cpp \
TranslatePlaneDragger.cpp
DEF += -DOSGMANIPULATOR_LIBRARY
INC +=
LIBS += -losgGA -losgUtil -losg $(GL_LIBS) $(OTHER_LIBS)
TARGET_BASENAME = osgManipulator
LIB = $(LIB_PREFIX)$(TARGET_BASENAME).$(LIB_EXT)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,711 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Projector>
using namespace osgManipulator;
namespace
{
bool computeClosestPoints(const osg::LineSegment& l1, const osg::LineSegment& l2,
osg::Vec3& p1, osg::Vec3& p2)
{
// Computes the closest points (p1 and p2 on line l1 and l2 respectively) between the two lines
// An explanation of the algorithm can be found at
// http://www.geometryalgorithms.com/Archive/algorithm_0106/algorithm_0106.htm
osg::Vec3 u = l1.end() - l1.start(); u.normalize();
osg::Vec3 v = l2.end() - l2.start(); v.normalize();
osg::Vec3 w0 = l1.start() - l2.start();
float a = u * u;
float b = u * v;
float c = v * v;
float d = u * w0;
float e = v * w0;
float denominator = a*c - b*b;
// Test if lines are parallel
if (denominator == 0.0) return false;
float sc = (b*e - c*d)/denominator;
float tc = (a*e - b*d)/denominator;
p1 = l1.start() + u * sc;
p2 = l2.start() + v * tc;
return true;
}
bool computeClosestPointOnLine(const osg::Vec3& lineStart, const osg::Vec3& lineEnd,
const osg::Vec3& fromPoint, osg::Vec3& closestPoint)
{
osg::Vec3 v = lineEnd - lineStart;
osg::Vec3 w = fromPoint - lineStart;
float c1 = w * v;
float c2 = v * v;
float almostZero = 0.000001;
if (c2 < almostZero) return false;
float b = c1 / c2;
closestPoint = lineStart + v * b;
return true;
}
bool getPlaneLineIntersection(const osg::Vec4& plane,
const osg::Vec3& lineStart, const osg::Vec3& lineEnd,
osg::Vec3& isect)
{
const double deltaX = lineEnd.x() - lineStart.x();
const double deltaY = lineEnd.y() - lineStart.y();
const double deltaZ = lineEnd.z() - lineStart.z();
const double denominator = (plane[0]*deltaX + plane[1]*deltaY + plane[2]*deltaZ);
if (! denominator) return false;
const double C = (plane[0]*lineStart.x() + plane[1]*lineStart.y() + plane[2]*lineStart.z() + plane[3]) / denominator;
isect.x() = lineStart.x() - deltaX * C;
isect.y() = lineStart.y() - deltaY * C;
isect.z() = lineStart.z() - deltaZ * C;
return true;
}
bool getSphereLineIntersection(const osg::Sphere& sphere,
const osg::Vec3& lineStart, const osg::Vec3& lineEnd,
osg::Vec3& frontISect, osg::Vec3& backISect)
{
osg::Vec3 lineDirection = lineEnd - lineStart;
lineDirection.normalize();
osg::Vec3 v = lineStart - sphere.getCenter();
float B = 2.0f * (lineDirection * v);
float C = v * v - sphere.getRadius() * sphere.getRadius();
float discriminant = B * B - 4.0f * C;
if (discriminant < 0.0f) // Line and sphere don't intersect.
return false;
float discriminantSqroot = sqrtf(discriminant);
float t0 = (-B - discriminantSqroot) * 0.5f;
frontISect = lineStart + lineDirection * t0;
float t1 = (-B + discriminantSqroot) * 0.5f;
backISect = lineStart + lineDirection * t1;
return true;
}
bool getUnitCylinderLineIntersection(const osg::Vec3& lineStart, const osg::Vec3& lineEnd,
osg::Vec3& isectFront, osg::Vec3& isectBack)
{
osg::Vec3 dir = lineEnd - lineStart;
dir.normalize();
float a = dir[0] * dir[0] + dir[1] * dir[1];
float b = 2.0f * (lineStart[0] * dir[0] + lineStart[1] * dir[1]);
float c = lineStart[0] * lineStart[0] + lineStart[1] * lineStart[1] - 1;
float d = b*b - 4*a*c;
if (d < 0.0f) return false;
float dSqroot = sqrtf(d);
float t0, t1;
if (b > 0.0f)
{
t0 = -(2.0f * c) / (dSqroot + b);
t1 = -(dSqroot + b) / (2.0 * a);
}
else
{
t0 = (2.0f * c) / (dSqroot - b);
t1 = (dSqroot - b) / (2.0 * a);
}
isectFront = lineStart + dir * t0;
isectBack = lineStart + dir * t1;
return true;
}
bool getCylinderLineIntersection(const osg::Cylinder& cylinder,
const osg::Vec3& lineStart, const osg::Vec3& lineEnd,
osg::Vec3& isectFront, osg::Vec3& isectBack)
{
// Compute matrix transformation that takes the cylinder to a unit cylinder with Z-axis as it's axis and
// (0,0,0) as it's center.
float oneOverRadius = 1.0f / cylinder.getRadius();
osg::Matrix toUnitCylInZ = osg::Matrix::translate(-cylinder.getCenter())
* osg::Matrix::scale(oneOverRadius, oneOverRadius, oneOverRadius)
* osg::Matrix(cylinder.getRotation().inverse());
// Transform the lineStart and lineEnd into the unit cylinder space.
osg::Vec3 unitCylLineStart = lineStart * toUnitCylInZ;
osg::Vec3 unitCylLineEnd = lineEnd * toUnitCylInZ;
// Intersect line with unit cylinder.
osg::Vec3 unitCylIsectFront, unitCylIsectBack;
if (! getUnitCylinderLineIntersection(unitCylLineStart, unitCylLineEnd, unitCylIsectFront, unitCylIsectBack))
return false;
// Transform back from unit cylinder space.
osg::Matrix invToUnitCylInZ(osg::Matrix::inverse(toUnitCylInZ));
isectFront = unitCylIsectFront * invToUnitCylInZ;
isectBack = unitCylIsectBack * invToUnitCylInZ;
return true;
}
osg::Vec3 getEyeDirection(const osg::Matrix& viewingMatrix, const osg::Matrix& localToWorld)
{
osg::Vec3 eye, center, up;
viewingMatrix.getLookAt(eye, center, up);
osg::Vec3 eyeDir = eye - center;
// To take a normal from world to local you need to transform it by the transpose of the inverse of the
// world to local matrix. Pre-multipling is equivalent to doing a post-multiplication of the transpose.
osg::Vec3 localEyeDir = localToWorld * eyeDir;
localEyeDir.normalize();
return localEyeDir;
}
osg::Plane computePlaneThruPointAndOrientedToEye(const osg::Matrix& viewingMatrix, const osg::Matrix& localToWorld,
const osg::Vec3& point, bool front)
{
osg::Vec3 planeNormal = getEyeDirection(viewingMatrix, localToWorld);
if (! front) planeNormal = -planeNormal;
osg::Plane plane;
plane.set(planeNormal, point);
return plane;
}
osg::Plane computePlaneParallelToAxisAndOrientedToEye(const osg::Matrix& viewingMatrix, const osg::Matrix& localToWorld,
const osg::Vec3& axisDir, float radius,
osg::Vec3& planeLineStart, osg::Vec3& planeLineEnd,
bool front)
{
osg::Vec3 perpDir = axisDir ^ getEyeDirection(viewingMatrix, localToWorld);
osg::Vec3 planeDir = perpDir ^ axisDir;
planeDir.normalize();
if (! front)
planeDir = -planeDir;
osg::Vec3 planePoint = planeDir * radius + axisDir;
osg::Plane plane;
plane.set(planeDir, planePoint);
planeLineStart = planePoint;
planeLineEnd = planePoint + axisDir;
return plane;
}
}
Projector::Projector() : _worldToLocalDirty(false)
{
}
Projector::~Projector()
{
}
LineProjector::LineProjector()
{
_line = new osg::LineSegment(osg::Vec3(0.0,0.0,0.0), osg::Vec3(1.0,0.0,0.0));
}
LineProjector::LineProjector(const osg::Vec3& s, const osg::Vec3& e)
{
_line = new osg::LineSegment(s,e);
}
LineProjector::~LineProjector()
{
}
bool LineProjector::project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const
{
if (!_line->valid())
{
osg::notify(osg::WARN) << "Warning: Invalid line set. LineProjector::project() failed."<<std::endl;
return false;
}
// Transform the line to world/object coordinate space.
osg::ref_ptr<osg::LineSegment> objectLine = new osg::LineSegment;
objectLine->mult(*_line, getLocalToWorld());
// Project the objectLine onto the window.
osg::ref_ptr<osg::LineSegment> windowLine = new osg::LineSegment;
sv.projectObjectIntoWindow(objectLine->start(), windowLine->start());
sv.projectObjectIntoWindow(objectLine->end(), windowLine->end());
windowLine->start().z() = windowLine->end().z() = 0.0f;
// Can't project if the line is straight into the screen.
if (!windowLine->valid())
return false;
// Compute projection of the point on the windowLine by computing the dot product.
osg::Vec2 windowLineStart(windowLine->start().x(),windowLine->start().y());
osg::Vec2 windowLineEnd(windowLine->end().x(),windowLine->end().y());
osg::Vec2 windowLineDirection = windowLineEnd - windowLineStart;
windowLineDirection.normalize();
float dotProduct = (windowLineDirection) * (pointToProject - windowLineStart);
// Get the closest point on the windowLine from (x,y).
osg::Vec2 closestWindowPt = windowLineStart + windowLineDirection * dotProduct;
// Project the closest point back into the scene and into local space.
osg::ref_ptr<osg::LineSegment> projectedLocalLine = new osg::LineSegment;
sv.projectWindowXYIntoObject((int)closestWindowPt.x(), (int)closestWindowPt.y(), projectedLocalLine->start(), projectedLocalLine->end());
projectedLocalLine->mult(*projectedLocalLine, getWorldToLocal());
// Find the closest point between _line and projectedLocalLine on _line and that's the result.
osg::Vec3 closestPtLine, closestPtProjWorkingLine;
if (! computeClosestPoints(*_line, *projectedLocalLine, closestPtLine, closestPtProjWorkingLine))
return false;
projectedPoint = closestPtLine;
return true;
}
PlaneProjector::PlaneProjector()
{
}
PlaneProjector::PlaneProjector(const osg::Plane& plane)
{
_plane = plane;
}
PlaneProjector::~PlaneProjector()
{
}
bool PlaneProjector::project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const
{
if (!_plane.valid())
{
osg::notify(osg::WARN) << "Warning: Invalid plane set. PlaneProjector::project() failed."<< std::endl;
return false;
}
// Get the near and far points for the mouse point.
osg::Vec3 nearPoint, farPoint;
sv.projectWindowXYIntoObject((int)pointToProject[0],(int)pointToProject[1],nearPoint,farPoint);
// Transform these points into local coordinates.
osg::Vec3 objectNearPoint, objectFarPoint;
objectNearPoint = nearPoint * getWorldToLocal();
objectFarPoint = farPoint * getWorldToLocal();
// Find the intersection of the plane with the line (formed by the near and far points in local coordinates).
return getPlaneLineIntersection(_plane.asVec4(), objectNearPoint, objectFarPoint, projectedPoint);
}
SphereProjector::SphereProjector() : _sphere(new osg::Sphere), _front(true)
{
}
SphereProjector::SphereProjector(osg::Sphere& sphere) : _sphere(&sphere), _front(true)
{
}
SphereProjector::~SphereProjector()
{
}
bool SphereProjector::project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const
{
if (!_sphere->valid())
{
osg::notify(osg::WARN) << "Warning: Invalid sphere. SphereProjector::project() failed." << std::endl;
return false;
}
// Get the near and far points for the mouse point.
osg::Vec3 nearPoint, farPoint;
sv.projectWindowXYIntoObject((int)pointToProject[0],(int)pointToProject[1],nearPoint,farPoint);
// Transform these points into local coordinates.
osg::Vec3 objectNearPoint, objectFarPoint;
objectNearPoint = nearPoint * getWorldToLocal();
objectFarPoint = farPoint * getWorldToLocal();
// Find the intersection of the sphere with the line.
osg::Vec3 dontCare;
if (_front)
return getSphereLineIntersection(*_sphere, objectNearPoint, objectFarPoint, projectedPoint, dontCare);
return getSphereLineIntersection(*_sphere, objectNearPoint, objectFarPoint, dontCare, projectedPoint);
}
bool SphereProjector::isPointInFront(const osg::Vec3& point, const osgUtil::SceneView& sv, const osg::Matrix& localToWorld) const
{
osg::Vec3 centerToPoint = getSphere().getCenter() - point;
if (centerToPoint * getEyeDirection(sv.getViewMatrix(), localToWorld) < 0.0)
return false;
return true;
}
SpherePlaneProjector::SpherePlaneProjector()
{
}
SpherePlaneProjector::SpherePlaneProjector(osg::Sphere& sphere) : SphereProjector(sphere)
{
}
SpherePlaneProjector::~SpherePlaneProjector()
{
}
osg::Quat SpherePlaneProjector::getRotation(const osg::Vec3& p1, bool p1OnSphere, const osg::Vec3& p2, bool p2OnSphere,
float radialFactor) const
{
if (p1OnSphere && p2OnSphere)
{
osg::Quat rotation;
if (_front)
rotation.makeRotate(p1 - getSphere().getCenter(), p2 - getSphere().getCenter());
else
rotation.makeRotate(p2 - getSphere().getCenter(), p1 - getSphere().getCenter());
return rotation;
}
else if (!p1OnSphere && !p2OnSphere)
{
osg::Quat rotation;
rotation.makeRotate(p1 - getSphere().getCenter(), p2 - getSphere().getCenter());
osg::Vec3 axis; double angle;
rotation.getRotate(angle, axis);
osg::Vec3 realAxis;
if (axis * _plane.getNormal() > 0.0f)
realAxis = _plane.getNormal();
else
realAxis = - _plane.getNormal();
osg::Quat rollRotation(angle, realAxis);
osg::Vec3 diff1 = p1 - getSphere().getCenter();
osg::Vec3 diff2 = p2 - getSphere().getCenter();
float d = diff2.length() - diff1.length();
float theta = d / getSphere().getRadius();
if (fabs(theta) < 0.000001 || fabs(theta) > 1.0)
return rollRotation;
diff1.normalize();
osg::Vec3 pullAxis = diff1 ^ _plane.getNormal();
pullAxis.normalize();
osg::Quat pullRotation(radialFactor * theta, pullAxis);
osg::Quat totalRotation = pullRotation * rollRotation;
return totalRotation;
}
else
{
const osg::Vec3& planePoint = getSphere().getCenter();
osg::Vec3 intersection, dontCare;
if (p1OnSphere)
getSphereLineIntersection(getSphere(), p2, planePoint, intersection, dontCare);
else
getSphereLineIntersection(getSphere(), p1, planePoint, intersection, dontCare);
osg::Quat rotation;
if (p1OnSphere)
rotation.makeRotate(p1 - getSphere().getCenter(), intersection - getSphere().getCenter());
else
rotation.makeRotate(intersection - getSphere().getCenter(), p2 - getSphere().getCenter());
return rotation;
}
}
bool SpherePlaneProjector::project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const
{
if (!_sphere->valid())
{
osg::notify(osg::WARN) << "Warning: Invalid sphere. SpherePlaneProjector::project() failed." << std::endl;
return false;
}
// Get the near and far points for the mouse point.
osg::Vec3 nearPoint, farPoint;
sv.projectWindowXYIntoObject((int)pointToProject[0],(int)pointToProject[1],nearPoint,farPoint);
// Transform these points into local coordinates.
osg::Vec3 objectNearPoint, objectFarPoint;
objectNearPoint = nearPoint * getWorldToLocal();
objectFarPoint = farPoint * getWorldToLocal();
// Find the intersection of the sphere with the line.
osg::Vec3 sphereIntersection, dontCare;
bool hitSphere = false;
if (_front)
hitSphere = getSphereLineIntersection(*_sphere, objectNearPoint, objectFarPoint, sphereIntersection, dontCare);
else
hitSphere = getSphereLineIntersection(*_sphere, objectNearPoint, objectFarPoint, dontCare, sphereIntersection);
// Compute plane oriented to the eye.
_plane = computePlaneThruPointAndOrientedToEye(sv.getViewMatrix(), getLocalToWorld(), getSphere().getCenter(), _front);
// Find the intersection on the plane.
osg::Vec3 planeIntersection;
if (hitSphere)
{
if (! getPlaneLineIntersection(_plane.asVec4(), sphereIntersection, sphereIntersection + _plane.getNormal(), planeIntersection))
return false;
}
else
{
if (! getPlaneLineIntersection(_plane.asVec4(), objectNearPoint, objectFarPoint, planeIntersection))
return false;
}
// Distance from the plane intersection point to the center of the sphere.
float dist = (planeIntersection - getSphere().getCenter()).length();
// If the distance is less that the sphere radius choose the sphere intersection else choose
// the plane intersection.
if (dist < getSphere().getRadius())
{
if (! hitSphere) return false;
projectedPoint = sphereIntersection;
_onSphere = true;
}
else
{
projectedPoint = planeIntersection;
_onSphere = false;
}
return true;
}
CylinderProjector::CylinderProjector() : _cylinder(new osg::Cylinder()), _cylinderAxis(0.0,0.0,1.0), _front(true)
{
}
CylinderProjector::CylinderProjector(osg::Cylinder& cylinder) : _front(true)
{
setCylinder(cylinder);
}
CylinderProjector::~CylinderProjector()
{
}
bool CylinderProjector::project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const
{
if (!_cylinder.valid())
{
osg::notify(osg::WARN) << "Warning: Invalid cylinder. CylinderProjector::project() failed."
<< std::endl;
return false;
}
// Get the near and far points for the mouse point.
osg::Vec3 nearPoint, farPoint;
sv.projectWindowXYIntoObject((int)pointToProject[0],(int)pointToProject[1],nearPoint,farPoint);
// Transform these points into local coordinates.
osg::Vec3 objectNearPoint, objectFarPoint;
objectNearPoint = nearPoint * getWorldToLocal();
objectFarPoint = farPoint * getWorldToLocal();
// Find the intersection of the sphere with the line.
osg::Vec3 dontCare;
return getCylinderLineIntersection(*_cylinder, objectNearPoint, objectFarPoint, projectedPoint, dontCare);
}
bool CylinderProjector::isPointInFront(const osg::Vec3& point, const osgUtil::SceneView& sv, const osg::Matrix& localToWorld) const
{
osg::Vec3 closestPointOnAxis;
computeClosestPointOnLine(getCylinder().getCenter(), getCylinder().getCenter() + _cylinderAxis,
point, closestPointOnAxis);
osg::Vec3 perpPoint = point - closestPointOnAxis;
if (perpPoint * getEyeDirection(sv.getViewMatrix(), localToWorld) < 0.0)
return false;
return true;
}
CylinderPlaneProjector::CylinderPlaneProjector()
{
}
CylinderPlaneProjector::CylinderPlaneProjector(osg::Cylinder& cylinder) : CylinderProjector(cylinder)
{
}
CylinderPlaneProjector::~CylinderPlaneProjector()
{
}
bool CylinderPlaneProjector::project(const osg::Vec2& pointToProject, const osgUtil::SceneView& sv, osg::Vec3& projectedPoint) const
{
if (!_cylinder.valid())
{
osg::notify(osg::WARN) << "Warning: Invalid cylinder. CylinderProjector::project() failed."
<< std::endl;
return false;
}
// Get the near and far points for the mouse point.
osg::Vec3 nearPoint, farPoint;
sv.projectWindowXYIntoObject((int)pointToProject[0],(int)pointToProject[1],nearPoint,farPoint);
// Transform these points into local coordinates.
osg::Vec3 objectNearPoint, objectFarPoint;
objectNearPoint = nearPoint * getWorldToLocal();
objectFarPoint = farPoint * getWorldToLocal();
// Find the intersection of the sphere with the line.
osg::Vec3 cylIntersection;
bool hitCylinder = false;
if (_front)
{
osg::Vec3 dontCare;
hitCylinder = getCylinderLineIntersection(*_cylinder, objectNearPoint, objectFarPoint, cylIntersection, dontCare);
}
else
{
osg::Vec3 dontCare;
hitCylinder = getCylinderLineIntersection(*_cylinder, objectNearPoint, objectFarPoint, dontCare, cylIntersection);
}
// Compute plane oriented to the eye.
_plane = computePlaneParallelToAxisAndOrientedToEye(sv.getViewMatrix(), getLocalToWorld(), _cylinderAxis,
getCylinder().getRadius(), _planeLineStart, _planeLineEnd,
_front);
// Find the intersection on the plane.
osg::Vec3 planeIntersection;
getPlaneLineIntersection(_plane.asVec4(), objectNearPoint, objectFarPoint, planeIntersection);
if (hitCylinder)
{
osg::Vec3 projectIntersection;
getPlaneLineIntersection(_plane.asVec4(), cylIntersection, cylIntersection + _plane.getNormal(), projectIntersection);
osg::Vec3 closestPointToCylAxis;
computeClosestPointOnLine(getCylinder().getCenter(), getCylinder().getCenter() + _cylinderAxis,
projectIntersection, closestPointToCylAxis);
// Distance from the plane intersection point to the closest point on the cylinder axis.
float dist = (projectIntersection - closestPointToCylAxis).length();
if (dist < getCylinder().getRadius())
{
if (!hitCylinder) return false;
projectedPoint = cylIntersection;
_onCylinder = true;
}
else
{
projectedPoint = planeIntersection;
_onCylinder = false;
}
}
else
{
projectedPoint = planeIntersection;
_onCylinder = false;
}
return true;
}
osg::Quat CylinderPlaneProjector::getRotation(const osg::Vec3& p1, bool p1OnCyl, const osg::Vec3& p2, bool p2OnCyl) const
{
if (p1OnCyl && p2OnCyl)
{
osg::Vec3 closestPointToCylAxis1, closestPointToCylAxis2;
computeClosestPointOnLine(getCylinder().getCenter(), getCylinder().getCenter() + _cylinderAxis * getCylinder().getHeight(),
p1, closestPointToCylAxis1);
computeClosestPointOnLine(getCylinder().getCenter(), getCylinder().getCenter() + _cylinderAxis * getCylinder().getHeight(),
p2, closestPointToCylAxis2);
osg::Vec3 v1 = p1 - closestPointToCylAxis1;
osg::Vec3 v2 = p2 - closestPointToCylAxis2;
float cosAngle = v1 * v2 / (v1.length() * v2.length());
if (cosAngle > 1.0 || cosAngle < -1.0)
return osg::Quat();
float angle = acosf(cosAngle);
osg::Vec3 rotAxis = v1 ^ v2;
return osg::Quat(angle, rotAxis);
}
else if (!p1OnCyl && !p2OnCyl)
{
osg::Vec3 closestPointToPlaneLine1, closestPointToPlaneLine2;
computeClosestPointOnLine(_planeLineStart, _planeLineEnd,
p1, closestPointToPlaneLine1);
computeClosestPointOnLine(_planeLineStart, _planeLineEnd,
p2, closestPointToPlaneLine2);
osg::Vec3 v1 = p1 - closestPointToPlaneLine1;
osg::Vec3 v2 = p2 - closestPointToPlaneLine2;
osg::Vec3 diff = v2 - v1;
float d = diff.length();
float angle = (getCylinder().getRadius() == 0.0) ? 0.0 : (d / getCylinder().getRadius());
osg::Vec3 rotAxis = _plane.getNormal() ^ v1;
if (v2.length() > v1.length())
return osg::Quat(angle, rotAxis);
else
return osg::Quat(-angle, rotAxis);
}
else
{
osg::Vec3 offCylinderPt = (p1OnCyl) ? p2 : p1;
osg::Vec3 linePtNearest;
computeClosestPointOnLine(_planeLineStart, _planeLineEnd,
offCylinderPt, linePtNearest);
osg::Vec3 dirToOffCylinderPt = offCylinderPt - linePtNearest;
dirToOffCylinderPt.normalize();
osg::Vec3 ptOnCylinder = linePtNearest + dirToOffCylinderPt * getCylinder().getRadius();
if (p1OnCyl)
return (getRotation(p1, true, ptOnCylinder, true) *
getRotation(ptOnCylinder, false, p2, false));
else
return (getRotation(p1, false, ptOnCylinder, false) *
getRotation(ptOnCylinder, true, p2, true));
}
}

View File

@ -0,0 +1,160 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/RotateCylinderDragger>
#include <osgManipulator/Command>
#include <osgManipulator/CommandManager>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/Material>
using namespace osgManipulator;
RotateCylinderDragger::RotateCylinderDragger()
{
_projector = new CylinderPlaneProjector();
setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
}
RotateCylinderDragger::~RotateCylinderDragger()
{
}
bool RotateCylinderDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList&, const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
switch (ea.getEventType())
{
// Pick start.
case (osgGA::GUIEventAdapter::PUSH):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::NodePath nodePathToRoot;
computeNodePathToRoot(*this,nodePathToRoot);
osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
_projector->setLocalToWorld(localToWorld);
_startLocalToWorld = _projector->getLocalToWorld();
_startWorldToLocal = _projector->getWorldToLocal();
if (_projector->isPointInFront(hitIter->getLocalIntersectPoint(), sv, _startLocalToWorld))
_projector->setFront(true);
else
_projector->setFront(false);
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
// Generate the motion command.
osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
cmd->setStage(MotionCommand::START);
cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Set color to pick color.
setMaterialColor(_pickColor,*this);
_prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
_prevRotation = osg::Quat();
_prevPtOnCylinder = _projector->isProjectionOnCylinder();
aa.requestRedraw();
}
return true;
}
// Pick move.
case (osgGA::GUIEventAdapter::DRAG):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::Matrix localToWorld = osg::Matrix(_prevRotation) * _startLocalToWorld;
_projector->setLocalToWorld(localToWorld);
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
osg::Vec3 prevProjectedPoint = _prevWorldProjPt * _projector->getWorldToLocal();
osg::Quat deltaRotation = _projector->getRotation(prevProjectedPoint, _prevPtOnCylinder,
projectedPoint, _projector->isProjectionOnCylinder());
osg::Quat rotation = deltaRotation * _prevRotation;
// Generate the motion command.
osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
cmd->setStage(MotionCommand::MOVE);
cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
cmd->setRotation(rotation);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
_prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
_prevRotation = rotation;
_prevPtOnCylinder = _projector->isProjectionOnCylinder();
aa.requestRedraw();
}
return true;
}
// Pick finish.
case (osgGA::GUIEventAdapter::RELEASE):
{
osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
cmd->setStage(MotionCommand::FINISH);
cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Reset color.
setMaterialColor(_color,*this);
aa.requestRedraw();
return true;
}
default:
return false;
}
return false;
}
void RotateCylinderDragger::setupDefaultGeometry()
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(const_cast<osg::Cylinder*>(&_projector->getCylinder())));
addChild(geode);
}

View File

@ -0,0 +1,162 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/RotateSphereDragger>
#include <osgManipulator/Command>
#include <osgManipulator/CommandManager>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/Material>
#include <iostream>
using namespace osgManipulator;
RotateSphereDragger::RotateSphereDragger() : _prevPtOnSphere(true)
{
_projector = new SpherePlaneProjector();
setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
}
RotateSphereDragger::~RotateSphereDragger()
{
}
bool RotateSphereDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList&, const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
switch (ea.getEventType())
{
// Pick start.
case (osgGA::GUIEventAdapter::PUSH):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::NodePath nodePathToRoot;
computeNodePathToRoot(*this,nodePathToRoot);
osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
_projector->setLocalToWorld(localToWorld);
_startLocalToWorld = _projector->getLocalToWorld();
_startWorldToLocal = _projector->getWorldToLocal();
if (_projector->isPointInFront(hitIter->getLocalIntersectPoint(), sv, _startLocalToWorld))
_projector->setFront(true);
else
_projector->setFront(false);
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
// Generate the motion command.
osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
cmd->setStage(MotionCommand::START);
cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Set color to pick color.
setMaterialColor(_pickColor,*this);
_prevRotation = osg::Quat();
_prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
_prevPtOnSphere = _projector->isProjectionOnSphere();
aa.requestRedraw();
}
return true;
}
// Pick move.
case (osgGA::GUIEventAdapter::DRAG):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::Matrix localToWorld = osg::Matrix(_prevRotation) * _startLocalToWorld;
_projector->setLocalToWorld(localToWorld);
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
osg::Vec3 prevProjectedPoint = _prevWorldProjPt * _projector->getWorldToLocal();
osg::Quat deltaRotation = _projector->getRotation(prevProjectedPoint, _prevPtOnSphere,
projectedPoint, _projector->isProjectionOnSphere(),1.0f);
osg::Quat rotation = deltaRotation * _prevRotation;
// Generate the motion command.
osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
cmd->setStage(MotionCommand::MOVE);
cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
cmd->setRotation(rotation);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
_prevWorldProjPt = projectedPoint * _projector->getLocalToWorld();
_prevRotation = rotation;
_prevPtOnSphere = _projector->isProjectionOnSphere();
aa.requestRedraw();
}
return true;
}
// Pick finish.
case (osgGA::GUIEventAdapter::RELEASE):
{
osg::ref_ptr<Rotate3DCommand> cmd = new Rotate3DCommand();
cmd->setStage(MotionCommand::FINISH);
cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld,_startWorldToLocal);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Reset color.
setMaterialColor(_color,*this);
aa.requestRedraw();
return true;
}
default:
return false;
}
return false;
}
void RotateSphereDragger::setupDefaultGeometry()
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(const_cast<osg::Sphere*>(&_projector->getSphere())));
addChild(geode);
}

View File

@ -0,0 +1,216 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Scale1DDragger>
#include <osgManipulator/Command>
#include <osgManipulator/CommandManager>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Material>
using namespace osgManipulator;
namespace
{
float computeScale(const osg::Vec3& startProjectedPoint,
const osg::Vec3& projectedPoint, float scaleCenter)
{
float denom = startProjectedPoint[0] - scaleCenter;
float scale = denom ? (projectedPoint[0] - scaleCenter)/denom : 1.0;
return scale;
}
}
Scale1DDragger::Scale1DDragger(ScaleMode scaleMode) : Dragger(), _minScale(0.001), _scaleMode(scaleMode)
{
_projector = new LineProjector(osg::Vec3(-0.5f,0.0f,0.0f),osg::Vec3(0.5f,0.0f,0.0f));
setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
}
Scale1DDragger::~Scale1DDragger()
{
}
bool Scale1DDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList&, const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
switch (ea.getEventType())
{
// Pick start.
case (osgGA::GUIEventAdapter::PUSH):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::NodePath nodePathToRoot;
computeNodePathToRoot(*this,nodePathToRoot);
osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
_projector->setLocalToWorld(localToWorld);
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, _startProjectedPoint))
{
_scaleCenter = 0.0f;
if (_scaleMode == SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT)
{
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), _leftHandleNode.get())
!= (*hitIter)._nodePath.end())
_scaleCenter = _projector->getLineEnd()[0];
else if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), _rightHandleNode.get())
!= (*hitIter)._nodePath.end())
_scaleCenter = _projector->getLineStart()[0];
}
// Generate the motion command.
osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();
cmd->setStage(MotionCommand::START);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Set color to pick color.
setMaterialColor(_pickColor,*this);
aa.requestRedraw();
}
return true;
}
// Pick move.
case (osgGA::GUIEventAdapter::DRAG):
{
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
// Generate the motion command.
osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();
// Compute scale.
float scale = computeScale(_startProjectedPoint,projectedPoint,_scaleCenter);
if (scale < getMinScale()) scale = getMinScale();
// Snap the referencePoint to the line start or line end depending on which is closer.
float referencePoint = _startProjectedPoint[0];
if (fabs(_projector->getLineStart()[0] - referencePoint) <
fabs(_projector->getLineEnd()[0] - referencePoint))
referencePoint = _projector->getLineStart()[0];
else
referencePoint = _projector->getLineEnd()[0];
cmd->setStage(MotionCommand::MOVE);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
cmd->setScale(scale);
cmd->setScaleCenter(_scaleCenter);
cmd->setReferencePoint(referencePoint);
cmd->setMinScale(getMinScale());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
aa.requestRedraw();
}
return true;
}
// Pick finish.
case (osgGA::GUIEventAdapter::RELEASE):
{
osg::ref_ptr<Scale1DCommand> cmd = new Scale1DCommand();
cmd->setStage(MotionCommand::FINISH);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Reset color.
setMaterialColor(_color,*this);
aa.requestRedraw();
return true;
}
default:
return false;
}
return false;
}
void Scale1DDragger::setupDefaultGeometry()
{
// Get the line length and direction.
osg::Vec3 lineDir = _projector->getLineEnd()-_projector->getLineStart();
float lineLength = lineDir.length();
lineDir.normalize();
osg::Geode* lineGeode = new osg::Geode;
// Create a line.
{
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(2);
(*vertices)[0] = _projector->getLineStart();
(*vertices)[1] = _projector->getLineEnd();
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
lineGeode->addDrawable(geometry);
}
// Turn of lighting for line and set line width.
lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osg::LineWidth* linewidth = new osg::LineWidth();
linewidth->setWidth(2.0f);
lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
// Add line and cones to the scene.
addChild(lineGeode);
// Create a left box.
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(_projector->getLineStart(), 0.05 * lineLength)));
addChild(geode);
setLeftHandleNode(*geode);
}
// Create a right box.
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(_projector->getLineEnd(), 0.05 * lineLength)));
addChild(geode);
setRightHandleNode(*geode);
}
}

View File

@ -0,0 +1,258 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Scale2DDragger>
#include <osgManipulator/Command>
#include <osgManipulator/CommandManager>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Material>
using namespace osgManipulator;
namespace
{
osg::Vec2 computeScale(const osg::Vec3& startProjectedPoint,
const osg::Vec3& projectedPoint,
const osg::Vec2& scaleCenter)
{
osg::Vec2 scale(1.0,1.0);
if ((startProjectedPoint[0] - scaleCenter[0]) != 0.0)
scale[0] = (projectedPoint[0] - scaleCenter[0])/(startProjectedPoint[0] - scaleCenter[0]);
if ((startProjectedPoint[2] - scaleCenter[1]) != 0.0)
scale[1] = (projectedPoint[2] - scaleCenter[1])/(startProjectedPoint[2] - scaleCenter[1]);
return scale;
}
}
Scale2DDragger::Scale2DDragger(ScaleMode scaleMode) : Dragger(), _minScale(0.001,0.001), _scaleMode(scaleMode)
{
_projector = new PlaneProjector(osg::Plane(0.0,1.0,0.0,0.0));
setColor(osg::Vec4(0.0, 1.0, 0.0, 1.0));
setPickColor(osg::Vec4(1.0, 1.0, 0.0, 1.0));
_topLeftHandlePosition.set (-0.5,0.5);
_bottomLeftHandlePosition.set (-0.5,-0.5);
_bottomRightHandlePosition.set(0.5,-0.5);
_topRightHandlePosition.set (0.5,0.5);
}
Scale2DDragger::~Scale2DDragger()
{
}
bool Scale2DDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList&, const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
switch (ea.getEventType())
{
// Pick start.
case (osgGA::GUIEventAdapter::PUSH):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::NodePath nodePathToRoot;
computeNodePathToRoot(*this,nodePathToRoot);
osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
_projector->setLocalToWorld(localToWorld);
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, _startProjectedPoint))
{
_scaleCenter.set(0.0,0.0);
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), _topLeftHandleNode.get())
!= (*hitIter)._nodePath.end())
{
_referencePoint = _topLeftHandlePosition;
if (_scaleMode == SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT)
_scaleCenter = _bottomRightHandlePosition;
}
else if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), _bottomLeftHandleNode.get())
!= (*hitIter)._nodePath.end())
{
_referencePoint = _bottomLeftHandlePosition;
if (_scaleMode == SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT)
_scaleCenter = _topRightHandlePosition;
}
else if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), _bottomRightHandleNode.get())
!= (*hitIter)._nodePath.end())
{
_referencePoint = _bottomRightHandlePosition;
if (_scaleMode == SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT)
_scaleCenter = _topLeftHandlePosition;
}
else if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), _topRightHandleNode.get())
!= (*hitIter)._nodePath.end())
{
_referencePoint = _topRightHandlePosition;
if (_scaleMode == SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT)
_scaleCenter = _bottomLeftHandlePosition;
}
// Generate the motion command.
osg::ref_ptr<Scale2DCommand> cmd = new Scale2DCommand();
cmd->setStage(MotionCommand::START);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
cmd->setReferencePoint(_referencePoint);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Set color to pick color.
setMaterialColor(_pickColor,*this);
aa.requestRedraw();
}
return true;
}
// Pick move.
case (osgGA::GUIEventAdapter::DRAG):
{
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
// Compute scale.
osg::Vec2 scale = computeScale(_startProjectedPoint,projectedPoint,_scaleCenter);
if (scale[0] < getMinScale()[0]) scale[0] = getMinScale()[0];
if (scale[1] < getMinScale()[1]) scale[1] = getMinScale()[1];
// Generate the motion command.
osg::ref_ptr<Scale2DCommand> cmd = new Scale2DCommand();
cmd->setStage(MotionCommand::MOVE);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
cmd->setScale(scale);
cmd->setScaleCenter(_scaleCenter);
cmd->setReferencePoint(_referencePoint);
cmd->setMinScale(getMinScale());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
aa.requestRedraw();
}
return true;
}
// Pick finish.
case (osgGA::GUIEventAdapter::RELEASE):
{
osg::ref_ptr<Scale2DCommand> cmd = new Scale2DCommand();
cmd->setStage(MotionCommand::FINISH);
cmd->setReferencePoint(_referencePoint);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Reset color.
setMaterialColor(_color,*this);
aa.requestRedraw();
return true;
}
default:
return false;
}
return false;
}
void Scale2DDragger::setupDefaultGeometry()
{
osg::Geode* lineGeode = new osg::Geode;
// Create a line.
{
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0].set(_topLeftHandlePosition[0],0.0,_topLeftHandlePosition[1]);
(*vertices)[1].set(_bottomLeftHandlePosition[0],0.0,_bottomLeftHandlePosition[1]);
(*vertices)[2].set(_bottomRightHandlePosition[0],0.0,_bottomRightHandlePosition[1]);
(*vertices)[3].set(_topRightHandlePosition[0],0.0,_topRightHandlePosition[1]);
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,vertices->size()));
lineGeode->addDrawable(geometry);
}
// Turn of lighting for line and set line width.
lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osg::LineWidth* linewidth = new osg::LineWidth();
linewidth->setWidth(2.0);
lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
// Add line and cones to the scene.
addChild(lineGeode);
// Create a top left box.
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(_topLeftHandlePosition[0],
0.0,_topLeftHandlePosition[1]), 0.05)));
addChild(geode);
setTopLeftHandleNode(*geode);
}
// Create a bottom left box.
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(_bottomLeftHandlePosition[0],
0.0,_bottomLeftHandlePosition[1]), 0.05)));
addChild(geode);
setBottomLeftHandleNode(*geode);
}
// Create a bottom right box.
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(_bottomRightHandlePosition[0],
0.0,_bottomRightHandlePosition[1]), 0.05)));
addChild(geode);
setBottomRightHandleNode(*geode);
}
// Create a top right box.
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(_topRightHandlePosition[0],
0.0,_topRightHandlePosition[1]), 0.05)));
addChild(geode);
setTopRightHandleNode(*geode);
}
}

View File

@ -0,0 +1,101 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/ScaleAxisDragger>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Quat>
using namespace osgManipulator;
ScaleAxisDragger::ScaleAxisDragger()
{
_xDragger = new osgManipulator::Scale1DDragger();
addChild(_xDragger.get());
addDragger(_xDragger.get());
_yDragger = new osgManipulator::Scale1DDragger();
addChild(_yDragger.get());
addDragger(_yDragger.get());
_zDragger = new osgManipulator::Scale1DDragger();
addChild(_zDragger.get());
addDragger(_zDragger.get());
setParentDragger(getParentDragger());
}
ScaleAxisDragger::~ScaleAxisDragger()
{
}
void ScaleAxisDragger::setupDefaultGeometry()
{
// Create a line.
osg::Geode* lineGeode = new osg::Geode;
{
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(2);
(*vertices)[0] = osg::Vec3(0.0f,0.0f,0.0f);
(*vertices)[1] = osg::Vec3(1.0f,0.0f,0.0f);
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
lineGeode->addDrawable(geometry);
}
// Turn of lighting for line and set line width.
{
osg::LineWidth* linewidth = new osg::LineWidth();
linewidth->setWidth(2.0f);
lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
}
// Add line to all the individual 1D draggers.
_xDragger->addChild(lineGeode);
_yDragger->addChild(lineGeode);
_zDragger->addChild(lineGeode);
osg::Geode* geode = new osg::Geode;
// Create a box.
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(1.0f,0.0f,0.0f), 0.05)));
// Add geode to all 1D draggers.
_xDragger->addChild(geode);
_yDragger->addChild(geode);
_zDragger->addChild(geode);
// Rotate Z-axis dragger appropriately.
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 1.0f));
_zDragger->setMatrix(osg::Matrix(rotation));
}
// Rotate Y-axis dragger appropriately.
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
_yDragger->setMatrix(osg::Matrix(rotation));
}
// Send different colors for each dragger.
_xDragger->setColor(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
_yDragger->setColor(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
_zDragger->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
}

View File

@ -0,0 +1,95 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Selection>
#include <osgManipulator/Command>
#include <algorithm>
using namespace osgManipulator;
class FindNodePathToRootVisitor : public osg::NodeVisitor
{
public:
osg::NodePath& _nodePathToRoot;
FindNodePathToRootVisitor(osg::NodePath& np)
: osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS),
_nodePathToRoot(np)
{}
virtual void apply(osg::Node& node)
{
_nodePathToRoot.push_back(&node);
traverse(node);
}
};
void osgManipulator::computeNodePathToRoot(osg::Node& node, osg::NodePath& np)
{
np.clear();
osg::ref_ptr<FindNodePathToRootVisitor> visitor = new FindNodePathToRootVisitor(np);
node.accept(*visitor);
np.pop_back();
std::reverse(np.begin(), np.end());
}
Selection::Selection()
{
}
Selection::~Selection()
{
}
bool Selection::receive(const MotionCommand& command)
{
switch (command.getStage())
{
case MotionCommand::START:
{
// Save the current matrix
_startMotionMatrix = getMatrix();
// Get the LocalToWorld and WorldToLocal matrix for this node.
osg::NodePath nodePathToRoot;
computeNodePathToRoot(*this,nodePathToRoot);
_localToWorld = osg::computeLocalToWorld(nodePathToRoot);
_worldToLocal = osg::Matrix::inverse(_localToWorld);
return true;
}
case MotionCommand::MOVE:
{
// Transform the command's motion matrix into local motion matrix.
osg::Matrix localMotionMatrix = _localToWorld * command.getWorldToLocal()
* command.getMotionMatrix()
* command.getLocalToWorld() * _worldToLocal;
// Transform by the localMotionMatrix
setMatrix(localMotionMatrix * _startMotionMatrix);
return true;
}
case MotionCommand::FINISH:
{
return true;
}
case MotionCommand::NONE:
default:
return false;
}
}

View File

@ -0,0 +1,77 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/TabBoxDragger>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Quat>
using namespace osgManipulator;
TabBoxDragger::TabBoxDragger()
{
for (int i=0; i<6; ++i)
{
_planeDraggers.push_back(new TabPlaneDragger());
addChild(_planeDraggers[i].get());
addDragger(_planeDraggers[i].get());
}
{
_planeDraggers[0]->setMatrix(osg::Matrix::translate(osg::Vec3(0.0,0.5,0.0)));
}
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, -1.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
_planeDraggers[1]->setMatrix(osg::Matrix(rotation)*osg::Matrix::translate(osg::Vec3(0.0,-0.5,0.0)));
}
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
_planeDraggers[2]->setMatrix(osg::Matrix(rotation)*osg::Matrix::translate(osg::Vec3(0.0,0.0,-0.5)));
}
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 1.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 1.0f));
_planeDraggers[3]->setMatrix(osg::Matrix(rotation)*osg::Matrix::translate(osg::Vec3(0.0,0.0,0.5)));
}
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
_planeDraggers[4]->setMatrix(osg::Matrix(rotation)*osg::Matrix::translate(osg::Vec3(-0.5,0.0,0.0)));
}
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 1.0f, 0.0f), osg::Vec3(1.0f, 0.0f, 0.0f));
_planeDraggers[5]->setMatrix(osg::Matrix(rotation)*osg::Matrix::translate(osg::Vec3(0.5,0.0,0.0)));
}
setParentDragger(getParentDragger());
}
TabBoxDragger::~TabBoxDragger()
{
}
void TabBoxDragger::setupDefaultGeometry()
{
for (unsigned int i=0; i<_planeDraggers.size(); ++i)
_planeDraggers[i]->setupDefaultGeometry(false);
}
void TabBoxDragger::setPlaneColor(const osg::Vec4& color)
{
for (unsigned int i=0; i<_planeDraggers.size(); ++i)
_planeDraggers[i]->setPlaneColor(color);
}

View File

@ -0,0 +1,267 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/TabPlaneDragger>
#include <osgManipulator/AntiSquish>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Quat>
#include <osg/PolygonMode>
#include <osg/CullFace>
#include <osg/AutoTransform>
using namespace osgManipulator;
namespace
{
osg::Node* createHandleNode(Scale2DDragger* cornerScaleDragger, float handleScaleFactor, bool twosided)
{
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = osg::Vec3(cornerScaleDragger->getTopLeftHandlePosition()[0],0.0,cornerScaleDragger->getTopLeftHandlePosition()[1]) * handleScaleFactor;
(*vertices)[1] = osg::Vec3(cornerScaleDragger->getBottomLeftHandlePosition()[0],0.0,cornerScaleDragger->getBottomLeftHandlePosition()[1]) * handleScaleFactor;
(*vertices)[2] = osg::Vec3(cornerScaleDragger->getBottomRightHandlePosition()[0],0.0,cornerScaleDragger->getBottomRightHandlePosition()[1]) * handleScaleFactor;
(*vertices)[3] = osg::Vec3(cornerScaleDragger->getTopRightHandlePosition()[0],0.0,cornerScaleDragger->getTopRightHandlePosition()[1]) * handleScaleFactor;
osg::Geometry* geometry = new osg::Geometry();
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size()));
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0,1.0,0.0));
geometry->setNormalArray(normals);
geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
osg::Geode* geode = new osg::Geode;
geode->setName("Dragger Handle");
geode->addDrawable(geometry);
if (!twosided)
{
osg::CullFace* cullface = new osg::CullFace;
cullface->setMode(osg::CullFace::FRONT);
geode->getOrCreateStateSet()->setAttribute(cullface, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
geode->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
}
geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
return geode;
}
osg::Node* createHandleScene(const osg::Vec3& pos, osg::Node* handleNode, float handleScaleFactor)
{
osg::AutoTransform *at = new osg::AutoTransform;
at->setPosition(pos);
at->setPivotPoint(pos * handleScaleFactor);
at->setAutoScaleToScreen(true);
at->addChild(handleNode);
AntiSquish* as = new AntiSquish;
as->setPivot(pos);
as->addChild(at);
return as;
}
void createCornerScaleDraggerGeometry(Scale2DDragger* cornerScaleDragger, osg::Node* handleNode, float handleScaleFactor)
{
// Create a top left box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(cornerScaleDragger->getTopLeftHandlePosition()[0],
0.0,cornerScaleDragger->getTopLeftHandlePosition()[1]),
handleNode, handleScaleFactor);
cornerScaleDragger->addChild(handleScene);
cornerScaleDragger->setTopLeftHandleNode(*handleScene);
}
// Create a bottom left box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(cornerScaleDragger->getBottomLeftHandlePosition()[0],
0.0,cornerScaleDragger->getBottomLeftHandlePosition()[1]),
handleNode, handleScaleFactor);
cornerScaleDragger->addChild(handleScene);
cornerScaleDragger->setBottomLeftHandleNode(*handleScene);
}
// Create a bottom right box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(cornerScaleDragger->getBottomRightHandlePosition()[0],
0.0,cornerScaleDragger->getBottomRightHandlePosition()[1]),
handleNode, handleScaleFactor);
cornerScaleDragger->addChild(handleScene);
cornerScaleDragger->setBottomRightHandleNode(*handleScene);
}
// Create a top right box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(cornerScaleDragger->getTopRightHandlePosition()[0],
0.0,cornerScaleDragger->getTopRightHandlePosition()[1]),
handleNode, handleScaleFactor);
cornerScaleDragger->addChild(handleScene);
cornerScaleDragger->setTopRightHandleNode(*handleScene);
}
}
void createEdgeScaleDraggerGeometry(Scale1DDragger* horzEdgeScaleDragger, Scale1DDragger* vertEdgeScaleDragger,
osg::Node* handleNode, float handleScaleFactor)
{
// Create a left box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(horzEdgeScaleDragger->getLeftHandlePosition(),0.0,0.0),
handleNode, handleScaleFactor);
horzEdgeScaleDragger->addChild(handleScene);
horzEdgeScaleDragger->setLeftHandleNode(*handleScene);
}
// Create a right box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(horzEdgeScaleDragger->getRightHandlePosition(),0.0,0.0),
handleNode, handleScaleFactor);
horzEdgeScaleDragger->addChild(handleScene);
horzEdgeScaleDragger->setRightHandleNode(*handleScene);
}
// Create a top box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(vertEdgeScaleDragger->getLeftHandlePosition(),0.0,0.0),
handleNode, handleScaleFactor);
vertEdgeScaleDragger->addChild(handleScene);
vertEdgeScaleDragger->setLeftHandleNode(*handleScene);
}
// Create a bottom box.
{
osg::Node* handleScene = createHandleScene(osg::Vec3(vertEdgeScaleDragger->getRightHandlePosition(),0.0,0.0),
handleNode, handleScaleFactor);
vertEdgeScaleDragger->addChild(handleScene);
vertEdgeScaleDragger->setRightHandleNode(*handleScene);
}
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(1.0f, 0.0f, 0.0f));
vertEdgeScaleDragger->setMatrix(osg::Matrix(rotation));
}
void createTranslateDraggerGeometry(Scale2DDragger* cornerScaleDragger, TranslatePlaneDragger* translateDragger)
{
// Create a polygon.
{
osg::Geode* geode = new osg::Geode;
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = osg::Vec3(cornerScaleDragger->getTopLeftHandlePosition()[0],0.0,cornerScaleDragger->getTopLeftHandlePosition()[1]);
(*vertices)[1] = osg::Vec3(cornerScaleDragger->getBottomLeftHandlePosition()[0],0.0,cornerScaleDragger->getBottomLeftHandlePosition()[1]);
(*vertices)[2] = osg::Vec3(cornerScaleDragger->getBottomRightHandlePosition()[0],0.0,cornerScaleDragger->getBottomRightHandlePosition()[1]);
(*vertices)[3] = osg::Vec3(cornerScaleDragger->getTopRightHandlePosition()[0],0.0,cornerScaleDragger->getTopRightHandlePosition()[1]);
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size()));
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0,1.0,0.0));
geometry->setNormalArray(normals);
geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
geode->addDrawable(geometry);
osg::PolygonMode* polymode = new osg::PolygonMode;
polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
geode->getOrCreateStateSet()->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
translateDragger->getTranslate2DDragger()->addChild(geode);
}
}
}
TabPlaneDragger::TabPlaneDragger() : _handleScaleFactor(20.0)
{
_cornerScaleDragger = new Scale2DDragger(Scale2DDragger::SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT);
addChild(_cornerScaleDragger.get());
addDragger(_cornerScaleDragger.get());
_horzEdgeScaleDragger = new Scale1DDragger(Scale1DDragger::SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT);
addChild(_horzEdgeScaleDragger.get());
addDragger(_horzEdgeScaleDragger.get());
_vertEdgeScaleDragger = new Scale1DDragger(Scale1DDragger::SCALE_WITH_OPPOSITE_HANDLE_AS_PIVOT);
addChild(_vertEdgeScaleDragger.get());
addDragger(_vertEdgeScaleDragger.get());
_translateDragger = new TranslatePlaneDragger();
_translateDragger->setColor(osg::Vec4(0.7f, 0.7f, 0.7f, 1.0f));
addChild(_translateDragger.get());
addDragger(_translateDragger.get());
setParentDragger(getParentDragger());
}
TabPlaneDragger::~TabPlaneDragger()
{
}
bool TabPlaneDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hl, const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
if (ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) return false;
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
// Since the translate plane and the handleNode lie on the same plane the hit could've been on either one. But we
// need to handle the scaling draggers before the translation. Check if the node path has the scaling nodes else
// check for the scaling nodes in next hit.
if (_cornerScaleDragger->handle(pixel_x, pixel_y, sv, hl, hitIter, ea, aa))
return true;
if (_horzEdgeScaleDragger->handle(pixel_x, pixel_y, sv, hl, hitIter, ea, aa))
return true;
if (_vertEdgeScaleDragger->handle(pixel_x, pixel_y, sv, hl, hitIter, ea, aa))
return true;
osgUtil::IntersectVisitor::HitList::iterator nextHit = hitIter + 1;
while (nextHit != hl.end())
{
if (_cornerScaleDragger->handle(pixel_x, pixel_y, sv, hl, nextHit, ea, aa))
return true;
if (_horzEdgeScaleDragger->handle(pixel_x, pixel_y, sv, hl, nextHit, ea, aa))
return true;
if (_vertEdgeScaleDragger->handle(pixel_x, pixel_y, sv, hl, nextHit, ea, aa))
return true;
++nextHit;
}
if (_translateDragger->handle(pixel_x, pixel_y, sv, hl, hitIter, ea, aa))
return true;
return false;
}
void TabPlaneDragger::setupDefaultGeometry(bool twoSidedHandle)
{
osg::ref_ptr<osg::Node> handleNode = createHandleNode(_cornerScaleDragger.get(), _handleScaleFactor, twoSidedHandle);
createCornerScaleDraggerGeometry(_cornerScaleDragger.get(), handleNode.get(), _handleScaleFactor);
createEdgeScaleDraggerGeometry(_horzEdgeScaleDragger.get(),_vertEdgeScaleDragger.get(),handleNode.get(),_handleScaleFactor);
createTranslateDraggerGeometry(_cornerScaleDragger.get(), _translateDragger.get());
}

View File

@ -0,0 +1,48 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/TabPlaneTrackballDragger>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/PolygonMode>
#include <osg/CullFace>
#include <osg/Quat>
#include <osg/AutoTransform>
using namespace osgManipulator;
TabPlaneTrackballDragger::TabPlaneTrackballDragger()
{
_trackballDragger = new TrackballDragger(true);
addChild(_trackballDragger.get());
addDragger(_trackballDragger.get());
_tabPlaneDragger = new TabPlaneDragger();
addChild(_tabPlaneDragger.get());
addDragger(_tabPlaneDragger.get());
setParentDragger(getParentDragger());
}
TabPlaneTrackballDragger::~TabPlaneTrackballDragger()
{
}
void TabPlaneTrackballDragger::setupDefaultGeometry()
{
_trackballDragger->setupDefaultGeometry();
_tabPlaneDragger->setupDefaultGeometry();
}

View File

@ -0,0 +1,171 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/TrackballDragger>
#include <osgManipulator/AntiSquish>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/PolygonMode>
#include <osg/CullFace>
#include <osg/Quat>
#include <osg/AutoTransform>
using namespace osgManipulator;
namespace
{
osg::Geometry* createCircleGeometry(float radius, unsigned int numSegments)
{
const float angleDelta = 2.0f*osg::PI/(float)numSegments;
const float r = radius;
float angle = 0.0f;
osg::Vec3Array* vertexArray = new osg::Vec3Array(numSegments);
osg::Vec3Array* normalArray = new osg::Vec3Array(numSegments);
for(unsigned int i = 0; i < numSegments; ++i,angle+=angleDelta)
{
float c = cosf(angle);
float s = sinf(angle);
(*vertexArray)[i].set(c*r,s*r,0.0f);
(*normalArray)[i].set(c,s,0.0f);
}
osg::Geometry* geometry = new osg::Geometry();
geometry->setVertexArray(vertexArray);
geometry->setNormalArray(normalArray);
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,vertexArray->size()));
return geometry;
}
}
TrackballDragger::TrackballDragger(bool useAutoTransform)
{
if (useAutoTransform)
{
float pixelSize = 50.0f;
osg::MatrixTransform* scaler = new osg::MatrixTransform;
scaler->setMatrix(osg::Matrix::scale(pixelSize, pixelSize, pixelSize));
osg::AutoTransform *at = new osg::AutoTransform;
at->setAutoScaleToScreen(true);
at->addChild(scaler);
AntiSquish* as = new AntiSquish;
as->addChild(at);
addChild(as);
_xDragger = new RotateCylinderDragger();
scaler->addChild(_xDragger.get());
addDragger(_xDragger.get());
_yDragger = new RotateCylinderDragger();
scaler->addChild(_yDragger.get());
addDragger(_yDragger.get());
_zDragger = new RotateCylinderDragger();
scaler->addChild(_zDragger.get());
addDragger(_zDragger.get());
_xyzDragger = new RotateSphereDragger();
scaler->addChild(_xyzDragger.get());
addDragger(_xyzDragger.get());
}
else
{
_xDragger = new RotateCylinderDragger();
addChild(_xDragger.get());
addDragger(_xDragger.get());
_yDragger = new RotateCylinderDragger();
addChild(_yDragger.get());
addDragger(_yDragger.get());
_zDragger = new RotateCylinderDragger();
addChild(_zDragger.get());
addDragger(_zDragger.get());
_xyzDragger = new RotateSphereDragger();
addChild(_xyzDragger.get());
addDragger(_xyzDragger.get());
}
setParentDragger(getParentDragger());
}
TrackballDragger::~TrackballDragger()
{
}
void TrackballDragger::setupDefaultGeometry()
{
osg::Geode* geode = new osg::Geode;
{
osg::TessellationHints* hints = new osg::TessellationHints;
hints->setCreateTop(false);
hints->setCreateBottom(false);
hints->setCreateBackFace(false);
osg::Cylinder* cylinder = new osg::Cylinder;
cylinder->setHeight(0.15f);
osg::ShapeDrawable* cylinderDrawable = new osg::ShapeDrawable(cylinder,hints);
geode->addDrawable(cylinderDrawable);
setDrawableToAlwaysCull(*cylinderDrawable);
geode->addDrawable(createCircleGeometry(1.0f, 25));
}
// Draw in line mode.
{
osg::PolygonMode* polymode = new osg::PolygonMode;
polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
geode->getOrCreateStateSet()->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(2.0f),osg::StateAttribute::ON);
}
// Add line to all the individual 1D draggers.
_xDragger->addChild(geode);
_yDragger->addChild(geode);
_zDragger->addChild(geode);
// Rotate X-axis dragger appropriately.
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(1.0f, 0.0f, 0.0f));
_xDragger->setMatrix(osg::Matrix(rotation));
}
// Rotate Y-axis dragger appropriately.
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
_yDragger->setMatrix(osg::Matrix(rotation));
}
// Send different colors for each dragger.
_xDragger->setColor(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
_yDragger->setColor(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
_zDragger->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
// Add invisible sphere for pick the spherical dragger.
{
osg::Drawable* sphereDrawable = new osg::ShapeDrawable(new osg::Sphere());
setDrawableToAlwaysCull(*sphereDrawable);
osg::Geode* sphereGeode = new osg::Geode;
sphereGeode->addDrawable(sphereDrawable);
_xyzDragger->addChild(sphereGeode);
}
}

View File

@ -0,0 +1,212 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Translate1DDragger>
#include <osgManipulator/Command>
#include <osgManipulator/CommandManager>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Material>
using namespace osgManipulator;
Translate1DDragger::Translate1DDragger() : Dragger(), _checkForNodeInNodePath(true)
{
_projector = new LineProjector;
setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
}
Translate1DDragger::Translate1DDragger(const osg::Vec3& s, const osg::Vec3& e) : Dragger(), _checkForNodeInNodePath(true)
{
_projector = new LineProjector(s,e);
setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
}
Translate1DDragger::~Translate1DDragger()
{
}
bool Translate1DDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList&, const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (_checkForNodeInNodePath)
{
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
}
switch (ea.getEventType())
{
// Pick start.
case (osgGA::GUIEventAdapter::PUSH):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::NodePath nodePathToRoot;
computeNodePathToRoot(*this,nodePathToRoot);
osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
_projector->setLocalToWorld(localToWorld);
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, _startProjectedPoint))
{
// Generate the motion command.
osg::ref_ptr<TranslateInLineCommand> cmd = new TranslateInLineCommand(_projector->getLineStart(),
_projector->getLineEnd());
cmd->setStage(MotionCommand::START);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Set color to pick color.
setMaterialColor(_pickColor,*this);
aa.requestRedraw();
}
return true;
}
// Pick move.
case (osgGA::GUIEventAdapter::DRAG):
{
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
// Generate the motion command.
osg::ref_ptr<TranslateInLineCommand> cmd = new TranslateInLineCommand(_projector->getLineStart(),
_projector->getLineEnd());
cmd->setStage(MotionCommand::MOVE);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
cmd->setTranslation(projectedPoint - _startProjectedPoint);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
aa.requestRedraw();
}
return true;
}
// Pick finish.
case (osgGA::GUIEventAdapter::RELEASE):
{
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
osg::ref_ptr<TranslateInLineCommand> cmd = new TranslateInLineCommand(_projector->getLineStart(),
_projector->getLineEnd());
cmd->setStage(MotionCommand::FINISH);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Reset color.
setMaterialColor(_color,*this);
aa.requestRedraw();
}
return true;
}
default:
return false;
}
return false;
}
void Translate1DDragger::setupDefaultGeometry()
{
// Get the line length and direction.
osg::Vec3 lineDir = _projector->getLineEnd()-_projector->getLineStart();
float lineLength = lineDir.length();
lineDir.normalize();
osg::Geode* geode = new osg::Geode;
// Create a left cone.
{
osg::Cone* cone = new osg::Cone (_projector->getLineStart(), 0.025f * lineLength, 0.10f * lineLength);
osg::Quat rotation;
rotation.makeRotate(lineDir, osg::Vec3(0.0f, 0.0f, 1.0f));
cone->setRotation(rotation);
geode->addDrawable(new osg::ShapeDrawable(cone));
}
// Create a right cone.
{
osg::Cone* cone = new osg::Cone (_projector->getLineEnd(), 0.025f * lineLength, 0.10f * lineLength);
osg::Quat rotation;
rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), lineDir);
cone->setRotation(rotation);
geode->addDrawable(new osg::ShapeDrawable(cone));
}
// Create an invisible cylinder for picking the line.
{
osg::Cylinder* cylinder = new osg::Cylinder ((_projector->getLineStart()+_projector->getLineEnd())/2, 0.015f * lineLength, lineLength);
osg::Quat rotation;
rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), lineDir);
cylinder->setRotation(rotation);
osg::Drawable* cylinderGeom = new osg::ShapeDrawable(cylinder);
setDrawableToAlwaysCull(*cylinderGeom);
geode->addDrawable(cylinderGeom);
}
osg::Geode* lineGeode = new osg::Geode;
// Create a line.
{
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(2);
(*vertices)[0] = _projector->getLineStart();
(*vertices)[1] = _projector->getLineEnd();
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
lineGeode->addDrawable(geometry);
}
// Turn of lighting for line and set line width.
lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osg::LineWidth* linewidth = new osg::LineWidth();
linewidth->setWidth(2.0f);
lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
// Add line and cones to the scene.
addChild(lineGeode);
addChild(geode);
}

View File

@ -0,0 +1,227 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/Translate2DDragger>
#include <osgManipulator/Command>
#include <osgManipulator/CommandManager>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Material>
using namespace osgManipulator;
Translate2DDragger::Translate2DDragger()
{
_projector = new PlaneProjector(osg::Plane(0.0,1.0,0.0,0.0));
_polygonOffset = new osg::PolygonOffset(-1.0f,-1.0f);
setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
}
Translate2DDragger::Translate2DDragger(const osg::Plane& plane)
{
_projector = new PlaneProjector(plane);
_polygonOffset = new osg::PolygonOffset(-1.0f,-1.0f);
setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
setPickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
}
Translate2DDragger::~Translate2DDragger()
{
}
bool Translate2DDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList&,
const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
switch (ea.getEventType())
{
// Pick start.
case (osgGA::GUIEventAdapter::PUSH):
{
// Get the LocalToWorld matrix for this node and set it for the projector.
osg::NodePath nodePathToRoot;
computeNodePathToRoot(*this,nodePathToRoot);
osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
_projector->setLocalToWorld(localToWorld);
if (_projector->project(osg::Vec2((float)pixel_x, (float)pixel_y), sv, _startProjectedPoint))
{
// Generate the motion command.
osg::ref_ptr<TranslateInPlaneCommand> cmd = new TranslateInPlaneCommand(_projector->getPlane());
cmd->setStage(MotionCommand::START);
cmd->setReferencePoint(_startProjectedPoint);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Set color to pick color.
setMaterialColor(_pickColor,*this);
getOrCreateStateSet()->setAttributeAndModes(_polygonOffset.get(), osg::StateAttribute::ON);
aa.requestRedraw();
}
return true;
}
// Pick move.
case (osgGA::GUIEventAdapter::DRAG):
{
osg::Vec3 projectedPoint;
if (_projector->project(osg::Vec2(pixel_x, pixel_y), sv, projectedPoint))
{
// Generate the motion command.
osg::ref_ptr<TranslateInPlaneCommand> cmd = new TranslateInPlaneCommand(_projector->getPlane());
cmd->setStage(MotionCommand::MOVE);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
cmd->setTranslation(projectedPoint - _startProjectedPoint);
cmd->setReferencePoint(_startProjectedPoint);
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
aa.requestRedraw();
}
return true;
}
// Pick finish.
case (osgGA::GUIEventAdapter::RELEASE):
{
osg::ref_ptr<TranslateInPlaneCommand> cmd = new TranslateInPlaneCommand(_projector->getPlane());
cmd->setStage(MotionCommand::FINISH);
cmd->setReferencePoint(_startProjectedPoint);
cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
// Dispatch command.
if (_commandManager)
{
_commandManager->addSelectionsToCommand(*cmd, *getParentDragger());
_commandManager->dispatch(*cmd);
}
// Reset color.
setMaterialColor(_color,*this);
getOrCreateStateSet()->removeAttribute(_polygonOffset.get());
aa.requestRedraw();
return true;
}
default:
return false;
}
return false;
}
void Translate2DDragger::setupDefaultGeometry()
{
// Create a line.
osg::Geode* lineGeode = new osg::Geode;
{
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(2);
(*vertices)[0] = osg::Vec3(0.0f,0.0f,-0.5f);
(*vertices)[1] = osg::Vec3(0.0f,0.0f,0.5f);
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
lineGeode->addDrawable(geometry);
}
// Turn of lighting for line and set line width.
osg::LineWidth* linewidth = new osg::LineWidth();
linewidth->setWidth(2.0f);
lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osg::Geode* geode = new osg::Geode;
// Create left cone.
{
osg::Cone* cone = new osg::Cone (osg::Vec3(0.0f, 0.0f, -0.5f), 0.025f, 0.10f);
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f,0.0f,-1.0f), osg::Vec3(0.0f, 0.0f, 1.0f));
cone->setRotation(rotation);
geode->addDrawable(new osg::ShapeDrawable(cone));
}
// Create right cone.
{
osg::Cone* cone = new osg::Cone (osg::Vec3(0.0f, 0.0f, 0.5f), 0.025f, 0.10f);
geode->addDrawable(new osg::ShapeDrawable(cone));
}
// Create an invisible cylinder for picking the line.
{
osg::Cylinder* cylinder = new osg::Cylinder (osg::Vec3(0.0f,0.0f,0.0f), 0.015f, 1.0f);
osg::Drawable* drawable = new osg::ShapeDrawable(cylinder);
setDrawableToAlwaysCull(*drawable);
geode->addDrawable(drawable);
}
// MatrixTransform to rotate the geometry according to the normal of the plane.
osg::MatrixTransform* xform = new osg::MatrixTransform;
// Create an arrow in the X axis.
{
osg::MatrixTransform* arrow = new osg::MatrixTransform;
arrow->addChild(lineGeode);
arrow->addChild(geode);
// Rotate X-axis arrow appropriately.
osg::Quat rotation; rotation.makeRotate(osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 0.0f, 1.0f));
arrow->setMatrix(osg::Matrix(rotation));
xform->addChild(arrow);
}
// Create an arrow in the Z axis.
{
osg::Group* arrow = new osg::Group;
arrow->addChild(lineGeode);
arrow->addChild(geode);
xform->addChild(arrow);
}
// Rotate the xform so that the geometry lies on the plane.
{
osg::Vec3 normal = _projector->getPlane().getNormal(); normal.normalize();
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 1.0f, 0.0f), normal);
xform->setMatrix(osg::Matrix(rotation));
}
addChild(xform);
}

View File

@ -0,0 +1,112 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/TranslateAxisDragger>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Quat>
using namespace osgManipulator;
TranslateAxisDragger::TranslateAxisDragger()
{
_xDragger = new Translate1DDragger(osg::Vec3(0.0,0.0,0.0), osg::Vec3(0.0,0.0,1.0));
addChild(_xDragger.get());
addDragger(_xDragger.get());
_yDragger = new Translate1DDragger(osg::Vec3(0.0,0.0,0.0), osg::Vec3(0.0,0.0,1.0));
addChild(_yDragger.get());
addDragger(_yDragger.get());
_zDragger = new Translate1DDragger(osg::Vec3(0.0,0.0,0.0), osg::Vec3(0.0,0.0,1.0));
addChild(_zDragger.get());
addDragger(_zDragger.get());
setParentDragger(getParentDragger());
}
TranslateAxisDragger::~TranslateAxisDragger()
{
}
void TranslateAxisDragger::setupDefaultGeometry()
{
// Create a line.
osg::Geode* lineGeode = new osg::Geode;
{
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(2);
(*vertices)[0] = osg::Vec3(0.0f,0.0f,0.0f);
(*vertices)[1] = osg::Vec3(0.0f,0.0f,1.0f);
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
lineGeode->addDrawable(geometry);
}
// Turn of lighting for line and set line width.
{
osg::LineWidth* linewidth = new osg::LineWidth();
linewidth->setWidth(2.0f);
lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON);
lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
}
// Add line to all the individual 1D draggers.
_xDragger->addChild(lineGeode);
_yDragger->addChild(lineGeode);
_zDragger->addChild(lineGeode);
osg::Geode* geode = new osg::Geode;
// Create a cone.
{
osg::Cone* cone = new osg::Cone (osg::Vec3(0.0f, 0.0f, 1.0f), 0.025f, 0.10f);
geode->addDrawable(new osg::ShapeDrawable(cone));
}
// Create an invisible cylinder for picking the line.
{
osg::Cylinder* cylinder = new osg::Cylinder (osg::Vec3(0.0f,0.0f,0.5f), 0.015f, 1.0f);
osg::Drawable* geometry = new osg::ShapeDrawable(cylinder);
setDrawableToAlwaysCull(*geometry);
geode->addDrawable(geometry);
}
// Add geode to all 1D draggers.
_xDragger->addChild(geode);
_yDragger->addChild(geode);
_zDragger->addChild(geode);
// Rotate X-axis dragger appropriately.
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(1.0f, 0.0f, 0.0f));
_xDragger->setMatrix(osg::Matrix(rotation));
}
// Rotate Y-axis dragger appropriately.
{
osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
_yDragger->setMatrix(osg::Matrix(rotation));
}
// Send different colors for each dragger.
_xDragger->setColor(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
_yDragger->setColor(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
_zDragger->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
}

View File

@ -0,0 +1,108 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
#include <osgManipulator/TranslatePlaneDragger>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/LineWidth>
#include <osg/Quat>
#include <osg/PolygonMode>
#include <osg/CullFace>
#include <osg/AutoTransform>
using namespace osgManipulator;
TranslatePlaneDragger::TranslatePlaneDragger() : _usingTranslate1DDragger(false)
{
_translate2DDragger = new Translate2DDragger();
_translate2DDragger->setColor(osg::Vec4(0.7f, 0.7f, 0.7f, 1.0f));
addChild(_translate2DDragger.get());
addDragger(_translate2DDragger.get());
_translate1DDragger = new Translate1DDragger(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(0.0f,1.0f,0.0f));
_translate1DDragger->setCheckForNodeInNodePath(false);
addChild(_translate1DDragger.get());
addDragger(_translate1DDragger.get());
setParentDragger(getParentDragger());
}
TranslatePlaneDragger::~TranslatePlaneDragger()
{
}
bool TranslatePlaneDragger::handle(int pixel_x, int pixel_y, const osgUtil::SceneView& sv,
const osgUtil::IntersectVisitor::HitList& hl,
const osgUtil::IntersectVisitor::HitList::iterator& hitIter,
const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
// Check if the dragger node is in the nodepath.
if (std::find((*hitIter)._nodePath.begin(), (*hitIter)._nodePath.end(), this) == (*hitIter)._nodePath.end())
return false;
if ((ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) &&
ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
_usingTranslate1DDragger = true;
bool handled = false;
if (_usingTranslate1DDragger)
{
if (_translate1DDragger->handle(pixel_x, pixel_y, sv, hl, hitIter, ea, aa))
handled = true;
}
else
{
if (_translate2DDragger->handle(pixel_x, pixel_y, sv, hl, hitIter, ea, aa))
handled = true;
}
if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
_usingTranslate1DDragger = false;
return handled;
}
void TranslatePlaneDragger::setupDefaultGeometry()
{
// Create a polygon.
{
osg::Geode* geode = new osg::Geode;
osg::Geometry* geometry = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = osg::Vec3(-0.5,0.0,0.5);
(*vertices)[1] = osg::Vec3(-0.5,0.0,-0.5);
(*vertices)[2] = osg::Vec3(0.5,0.0,-0.5);
(*vertices)[3] = osg::Vec3(0.5,0.0,0.5);
geometry->setVertexArray(vertices);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size()));
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0,1.0,0.0));
geometry->setNormalArray(normals);
geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
geode->addDrawable(geometry);
osg::PolygonMode* polymode = new osg::PolygonMode;
polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
geode->getOrCreateStateSet()->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
_translate2DDragger->addChild(geode);
}
}