From 2f71509ebf0a404712f3cc092411f2046d8fc5ec Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 7 Oct 2013 10:38:58 +0000 Subject: [PATCH] =?UTF-8?q?From=20Stephan=20Huber,=20"attached=20you?= =?UTF-8?q?=E2=80=99ll=20find=20a=20bunch=20of=20fixes=20+=20enhancements?= =?UTF-8?q?=20for=20iOS=20and=20OS=20X=20based=20on=20current=20trunk.=20I?= =?UTF-8?q?=20incorporated=20+=20tested=20the=20submission=20from=20Colin?= =?UTF-8?q?=20Cochran,=20so=20his=20submission=20is=20not=20needed=20anymo?= =?UTF-8?q?re.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fixed a bug with multi-touch and touch-id-generation on iOS and OS X. (will fix a bug reported by Colin Cochran, without ditching the existing logic) * removed unnecessary warning-flagss when generating xcode-projects via cmake, will enable the usage of OSG_AGGRESSIVE_WARNING_FLAGS * added support for 10.9 (OS X) * new cmake-variable: IPHONE_VERSION_MIN, this will set the deployment-target (previously hard-coded) If you set the IPHONE_VERSION_MIN to something like 7.0 osg gets compiled also for 64bit (amd64) * cmake defaults now to the clang compiler if IPHONE_VERSION_MIN > 4.2 * cmake now sets some xcode-settings so the compiler uses the c++98-standard (clang defaults to c++11, w/o this I got a lot of linking errors) * removed include-dir for avfoundation-plugin as not needed on OSX/IOS. * enhanced the ios-example, will now show multitouch-information on a hud (similar to the osgmultitouch-example), and more importantly, will compile + link out of the box * small enhancements for the osc-device-plugin (send only one msg for MOVE/DRAG, even if multiple msgs/event is enabled) * better memory-handling for the zeroconf-plugin * fixed a possible bug in the rest-http-plugin when receiving mouse-events. * incorporated a fix from Colin Cochran "forwarded touch events are not transformed into the GL UIView“ " --- CMakeLists.txt | 31 +- CMakeModules/FindAVFoundation.cmake | 10 +- CMakeModules/OsgMacroUtils.cmake | 79 ++-- examples/osgviewerIPhone/CMakeLists.txt | 10 +- .../osgviewerIPhone/iphoneViewerAppDelegate.h | 2 +- .../iphoneViewerAppDelegate.mm | 344 +++++++++++++----- examples/osgviewerIPhone/osgPlugins.h | 4 +- .../RestHttpDevice/RestHttpDevice.cpp | 5 + .../RestHttpDevice/RestHttpDevice.hpp | 4 +- .../AutoDiscoveryBonjourImpl.mm | 22 +- src/osgPlugins/avfoundation/CMakeLists.txt | 3 +- src/osgPlugins/osc/OscSendingDevice.cpp | 9 +- src/osgViewer/GraphicsWindowCocoa.mm | 13 +- src/osgViewer/GraphicsWindowIOS.mm | 18 +- 14 files changed, 378 insertions(+), 176 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d4e04496..e6e2c6dd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,13 +247,16 @@ IF(APPLE) #you need to manually set the default sdk version here SET (IPHONE_SDKVER "6.0" CACHE STRING "IOS SDK-Version") + SET (IPHONE_VERSION_MIN "4.2" CACHE STRING "IOS minimum os version, use 7.0 or greater to get 64bit support") #the below is taken from ogre, it states the gcc stuff needs to happen before PROJECT() is called. I've no clue if we even need it # Force gcc <= 4.2 on iPhone - include(CMakeForceCompiler) - CMAKE_FORCE_C_COMPILER(llvm-gcc-4.2 GNU) - CMAKE_FORCE_CXX_COMPILER(llvm-gcc-4.2 GNU) - SET(GCC_THUMB_SUPPORT NO) + IF(IPHONE_VERSION_MIN LESS "6.0") + include(CMakeForceCompiler) + CMAKE_FORCE_C_COMPILER(llvm-gcc-4.2 GNU) + CMAKE_FORCE_CXX_COMPILER(llvm-gcc-4.2 GNU) + SET(GCC_THUMB_SUPPORT NO) + ENDIF() #set either the device sdk or the simulator sdk. Can't find away to separate these in the same project IF(OSG_BUILD_PLATFORM_IPHONE) @@ -813,6 +816,14 @@ ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # CMake lacks an elseif, so other non-gcc, non-VS compilers need # to be listed below. If unhandled, OSG_AGGRESSIVE_WARNING_FLAGS should # remain unset. + + IF (APPLE) + # set standard lib, clang defaults to c++0x + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++98") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -stdlib=libstdc++ -Wno-overloaded-virtual -Wno-conversion") + set(WARNING_CFLAGS "") + ENDIF() ENDIF() # This part is for the CMake menu option to toggle the warnings on/off. @@ -872,8 +883,14 @@ IF(APPLE AND NOT ANDROID) #set iphone arch and flags taken from http://sites.google.com/site/michaelsafyan/coding/resources/how-to-guides/cross-compile-for-the-iphone/how-to-cross-compile-for-the-iphone-using-cmake IF(OSG_BUILD_PLATFORM_IPHONE) - SET(CMAKE_OSX_ARCHITECTURES "armv6;armv7" CACHE STRING "Build architectures for iOS" FORCE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -miphoneos-version-min=4.1 -mno-thumb -arch armv6 -pipe -no-cpp-precomp" CACHE STRING "Flags used by the compiler during all build types." FORCE) + IF(${IPHONE_VERSION_MIN} LESS "7.0") + SET(CMAKE_OSX_ARCHITECTURES "armv6;armv7" CACHE STRING "Build architectures for iOS" FORCE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -miphoneos-version-min=${IPHONE_VERSION_MIN} -mno-thumb -pipe -no-cpp-precomp" CACHE STRING "Flags used by the compiler during all build types." FORCE) + ELSE() + SET(CMAKE_OSX_ARCHITECTURES "armv7;armv7s;arm64" CACHE STRING "Build architectures for iOS" FORCE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -miphoneos-version-min=${IPHONE_VERSION_MIN} -pipe -no-cpp-precomp" CACHE STRING "Flags used by the compiler during all build types." FORCE) + ENDIF() + ELSE() #simulator uses i386 architectures SET(CMAKE_OSX_ARCHITECTURES "i386" CACHE STRING "Build architectures for iOS Simulator" FORCE) @@ -905,7 +922,7 @@ IF(APPLE AND NOT ANDROID) # FORCE is used because the options are not reflected in the UI otherwise. # Seems like a good place to add version specific compiler flags too. IF(NOT OSG_CONFIG_HAS_BEEN_RUN_BEFORE) - IF(${OSG_OSX_SDK_NAME} STREQUAL "macosx10.8") + IF(${OSG_OSX_SDK_NAME} STREQUAL "macosx10.8" OR ${OSG_OSX_SDK_NAME} STREQUAL "macosx10.9") SET(OSG_DEFAULT_IMAGE_PLUGIN_FOR_OSX "imageio" CACHE STRING "Forced imageio default image plugin for OSX" FORCE) # 64 Bit Works, i386,ppc is not supported any more SET(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "Build architectures for OSX" FORCE) diff --git a/CMakeModules/FindAVFoundation.cmake b/CMakeModules/FindAVFoundation.cmake index 13ae10691..ff888f025 100644 --- a/CMakeModules/FindAVFoundation.cmake +++ b/CMakeModules/FindAVFoundation.cmake @@ -1,22 +1,20 @@ # Locate Apple AVFoundation (next-generation QTKit) # This module defines # AV_FOUNDATION_LIBRARY -# AV_FOUNDATION_FOUND, if false, do not try to link to gdal -# AV_FOUNDATION_INCLUDE_DIR, where to find the headers +# AV_FOUNDATION_FOUND, if false, do not try to link to gdal # # $AV_FOUNDATION_DIR is an environment variable that would # correspond to the ./configure --prefix=$AV_FOUNDATION_DIR # -# Created by Stephan Maximilian Huber +# Created by Stephan Maximilian Huber IF(APPLE) - FIND_PATH(AV_FOUNDATION_INCLUDE_DIR AVFoundation/AVFoundation.h) FIND_LIBRARY(AV_FOUNDATION_LIBRARY AVFoundation) ENDIF() SET(AV_FOUNDATION_FOUND "NO") -IF(AV_FOUNDATION_LIBRARY AND AV_FOUNDATION_INCLUDE_DIR) +IF(AV_FOUNDATION_LIBRARY) SET(AV_FOUNDATION_FOUND "YES") ENDIF() @@ -36,7 +34,7 @@ ELSE() # nothing special here ;-) ELSE() MESSAGE("AVFoundation disabled for SDK < 10.8") - SET(AV_FOUNDATION_FOUND "NO") + SET(AV_FOUNDATION_FOUND "NO") ENDIF() ENDIF() ENDIF() diff --git a/CMakeModules/OsgMacroUtils.cmake b/CMakeModules/OsgMacroUtils.cmake index aa607fa77..7575995ab 100644 --- a/CMakeModules/OsgMacroUtils.cmake +++ b/CMakeModules/OsgMacroUtils.cmake @@ -5,7 +5,7 @@ # NAME of the variables, so the macro gets as arguments the target name and the following list of parameters # is intended as a list of variable names each one containing the path of the libraries to link to # The existance of a variable name with _DEBUG appended is tested and, in case it' s value is used -# for linking to when in debug mode +# for linking to when in debug mode # the content of this library for linking when in debugging ####################################################################################################### @@ -87,12 +87,12 @@ MACRO(LINK_CORELIB_DEFAULT CORELIB_NAME) SET(ALL_GL_LIBRARIES ${ALL_GL_LIBRARIES} ${OPENGL_egl_LIBRARY}) ENDIF() - LINK_EXTERNAL(${CORELIB_NAME} ${ALL_GL_LIBRARIES}) + LINK_EXTERNAL(${CORELIB_NAME} ${ALL_GL_LIBRARIES}) LINK_WITH_VARIABLES(${CORELIB_NAME} OPENTHREADS_LIBRARY) IF(OPENSCENEGRAPH_SONAMES) SET_TARGET_PROPERTIES(${CORELIB_NAME} PROPERTIES VERSION ${OPENSCENEGRAPH_VERSION} SOVERSION ${OPENSCENEGRAPH_SOVERSION}) ENDIF(OPENSCENEGRAPH_SONAMES) - + ENDMACRO(LINK_CORELIB_DEFAULT CORELIB_NAME) @@ -112,11 +112,11 @@ MACRO(SETUP_LINK_LIBRARIES) ###################################################################### # # This set up the libraries to link to, it assumes there are two variable: one common for a group of examples or plugins - # kept in the variable TARGET_COMMON_LIBRARIES and an example or plugin specific kept in TARGET_ADDED_LIBRARIES - # they are combined in a single list checked for unicity + # kept in the variable TARGET_COMMON_LIBRARIES and an example or plugin specific kept in TARGET_ADDED_LIBRARIES + # they are combined in a single list checked for unicity # the suffix ${CMAKE_DEBUG_POSTFIX} is used for differentiating optimized and debug # - # a second variable TARGET_EXTERNAL_LIBRARIES hold the list of libraries not differentiated between debug and optimized + # a second variable TARGET_EXTERNAL_LIBRARIES hold the list of libraries not differentiated between debug and optimized ################################################################################## SET(TARGET_LIBRARIES ${TARGET_COMMON_LIBRARIES}) @@ -151,7 +151,7 @@ MACRO(SETUP_LINK_LIBRARIES) ENDIF(TARGET_LIBRARIES_VARS) IF(MSVC AND OSG_MSVC_VERSIONED_DLL) #when using full path name to specify linkage, it seems that already linked libs must be specified - LINK_EXTERNAL(${TARGET_TARGETNAME} ${ALL_GL_LIBRARIES}) + LINK_EXTERNAL(${TARGET_TARGETNAME} ${ALL_GL_LIBRARIES}) ENDIF(MSVC AND OSG_MSVC_VERSIONED_DLL) ENDMACRO(SETUP_LINK_LIBRARIES) @@ -213,7 +213,7 @@ ENDMACRO(SET_OUTPUT_DIR_PROPERTY_260 TARGET_TARGETNAME RELATIVE_OUTDIR) MACRO(SETUP_LIBRARY LIB_NAME) IF(ANDROID) - SETUP_ANDROID_LIBRARY(${LIB_NAME}) + SETUP_ANDROID_LIBRARY(${LIB_NAME}) ELSE() SET(TARGET_NAME ${LIB_NAME} ) SET(TARGET_TARGETNAME ${LIB_NAME} ) @@ -224,10 +224,13 @@ MACRO(SETUP_LIBRARY LIB_NAME) ${TARGET_SRC} ) SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES FOLDER "OSG Core") + IF(APPLE) + SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS "") + ENDIF() IF(TARGET_LABEL) SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PROJECT_LABEL "${TARGET_LABEL}") ENDIF(TARGET_LABEL) - + IF(TARGET_LIBRARIES) LINK_INTERNAL(${LIB_NAME} ${TARGET_LIBRARIES}) ENDIF() @@ -238,14 +241,14 @@ MACRO(SETUP_LIBRARY LIB_NAME) LINK_WITH_VARIABLES(${LIB_NAME} ${TARGET_LIBRARIES_VARS}) ENDIF(TARGET_LIBRARIES_VARS) LINK_CORELIB_DEFAULT(${LIB_NAME}) - + ENDIF() INCLUDE(ModuleInstall OPTIONAL) ENDMACRO(SETUP_LIBRARY LIB_NAME) MACRO(SETUP_PLUGIN PLUGIN_NAME) IF(ANDROID) - SETUP_ANDROID_LIBRARY(${TARGET_DEFAULT_PREFIX}${PLUGIN_NAME}) + SETUP_ANDROID_LIBRARY(${TARGET_DEFAULT_PREFIX}${PLUGIN_NAME}) ELSE() SET(TARGET_NAME ${PLUGIN_NAME} ) @@ -268,17 +271,17 @@ MACRO(SETUP_PLUGIN PLUGIN_NAME) SET(PACKAGE_COMPONENT libopenscenegraph) ENDIF(${ARGC} GREATER 1) - # Add the VisualStudio versioning info + # Add the VisualStudio versioning info SET(TARGET_SRC ${TARGET_SRC} ${OPENSCENEGRAPH_VERSIONINFO_RC}) - - # here we use the command to generate the library + + # here we use the command to generate the library IF (DYNAMIC_OPENSCENEGRAPH) ADD_LIBRARY(${TARGET_TARGETNAME} MODULE ${TARGET_SRC} ${TARGET_H}) ELSE (DYNAMIC_OPENSCENEGRAPH) ADD_LIBRARY(${TARGET_TARGETNAME} STATIC ${TARGET_SRC} ${TARGET_H}) ENDIF(DYNAMIC_OPENSCENEGRAPH) - + #not sure if needed, but for plugins only Msvc need the d suffix IF(NOT MSVC) IF(NOT UNIX) @@ -289,17 +292,17 @@ MACRO(SETUP_PLUGIN PLUGIN_NAME) SET_OUTPUT_DIR_PROPERTY_260(${TARGET_TARGETNAME} "${OSG_PLUGINS}") # Sets the ouput to be /osgPlugin-X.X.X ; also ensures the /Debug /Release are removed ELSE(NOT CMAKE24) - IF(OSG_MSVC_VERSIONED_DLL) + IF(OSG_MSVC_VERSIONED_DLL) #this is a hack... the build place is set to lib/ by LIBARARY_OUTPUT_PATH equal to OUTPUT_LIBDIR #the .lib will be crated in ../ so going straight in lib by the IMPORT_PREFIX property #because we want dll placed in OUTPUT_BINDIR ie the bin folder sibling of lib, we can use ../../bin to go there, #it is hardcoded, we should compute OUTPUT_BINDIR position relative to OUTPUT_LIBDIR ... to be implemented #changing bin to something else breaks this hack - #the dll are placed in bin/${OSG_PLUGINS} + #the dll are placed in bin/${OSG_PLUGINS} IF(NOT MSVC_IDE) - SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PREFIX "../bin/${OSG_PLUGINS}/") + SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PREFIX "../bin/${OSG_PLUGINS}/") ELSE(NOT MSVC_IDE) SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PREFIX "../../bin/${OSG_PLUGINS}/" IMPORT_PREFIX "../") ENDIF(NOT MSVC_IDE) @@ -317,12 +320,14 @@ MACRO(SETUP_PLUGIN PLUGIN_NAME) SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PROJECT_LABEL "${TARGET_LABEL}") SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES FOLDER "Plugins") - + IF(APPLE) + SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS "") + ENDIF() SETUP_LINK_LIBRARIES() #the installation path are differentiated for win32 that install in bib versus other architecture that install in lib${LIB_POSTFIX}/${OSG_PLUGINS} IF(WIN32) - INSTALL(TARGETS ${TARGET_TARGETNAME} + INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION bin COMPONENT ${PACKAGE_COMPONENT} ARCHIVE DESTINATION lib/${OSG_PLUGINS} COMPONENT libopenscenegraph-dev LIBRARY DESTINATION bin/${OSG_PLUGINS} COMPONENT ${PACKAGE_COMPONENT}) @@ -350,11 +355,11 @@ MACRO(SETUP_EXE IS_COMMANDLINE_APP) ENDIF(NOT TARGET_LABEL) IF(${IS_COMMANDLINE_APP}) - + ADD_EXECUTABLE(${TARGET_TARGETNAME} ${TARGET_SRC} ${TARGET_H}) - + ELSE(${IS_COMMANDLINE_APP}) - + IF(APPLE) # SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${OPENSCENEGRAPH_MAJOR_VERSION}.${OPENSCENEGRAPH_MINOR_VERSION}.${OPENSCENEGRAPH_PATCH_VERSION}") # Short Version is the "marketing version". It is the version @@ -363,6 +368,8 @@ MACRO(SETUP_EXE IS_COMMANDLINE_APP) # Bundle version is the version the OS looks at. SET(MACOSX_BUNDLE_BUNDLE_VERSION "${OPENSCENEGRAPH_MAJOR_VERSION}.${OPENSCENEGRAPH_MINOR_VERSION}.${OPENSCENEGRAPH_PATCH_VERSION}") SET(MACOSX_BUNDLE_GUI_IDENTIFIER "org.openscenegraph.${TARGET_TARGETNAME}" ) + # replace underscore by hyphen + STRING(REGEX REPLACE "_" "-" MACOSX_BUNDLE_GUI_IDENTIFIER ${MACOSX_BUNDLE_GUI_IDENTIFIER}) SET(MACOSX_BUNDLE_BUNDLE_NAME "${TARGET_NAME}" ) # SET(MACOSX_BUNDLE_ICON_FILE "myicon.icns") # SET(MACOSX_BUNDLE_COPYRIGHT "") @@ -382,7 +389,7 @@ MACRO(SETUP_EXE IS_COMMANDLINE_APP) ENDIF(APPLE) ADD_EXECUTABLE(${TARGET_TARGETNAME} ${PLATFORM_SPECIFIC_CONTROL} ${TARGET_SRC} ${TARGET_H}) - + ENDIF(${IS_COMMANDLINE_APP}) SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES PROJECT_LABEL "${TARGET_LABEL}") @@ -396,7 +403,11 @@ MACRO(SETUP_EXE IS_COMMANDLINE_APP) SET_OUTPUT_DIR_PROPERTY_260(${TARGET_TARGETNAME} "") # Ensure the /Debug /Release are removed ENDIF(MSVC_IDE AND OSG_MSVC_VERSIONED_DLL) - SETUP_LINK_LIBRARIES() + IF(APPLE) + SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS "") + ENDIF() + + SETUP_LINK_LIBRARIES() ENDMACRO(SETUP_EXE) @@ -410,11 +421,11 @@ MACRO(SETUP_APPLICATION APPLICATION_NAME) ELSE(${ARGC} GREATER 1) SET(IS_COMMANDLINE_APP 0) ENDIF(${ARGC} GREATER 1) - + SETUP_EXE(${IS_COMMANDLINE_APP}) - + SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES FOLDER "Applications") - + IF(APPLE) INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION bin BUNDLE DESTINATION bin) ELSE(APPLE) @@ -439,13 +450,13 @@ MACRO(SETUP_EXAMPLE EXAMPLE_NAME) ELSE(${ARGC} GREATER 1) SET(IS_COMMANDLINE_APP 0) ENDIF(${ARGC} GREATER 1) - + SETUP_EXE(${IS_COMMANDLINE_APP}) - + SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES FOLDER "Examples") - + IF(APPLE) - INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION share/OpenSceneGraph/bin BUNDLE DESTINATION share/OpenSceneGraph/bin ) + INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION share/OpenSceneGraph/bin BUNDLE DESTINATION share/OpenSceneGraph/bin ) ELSE(APPLE) INSTALL(TARGETS ${TARGET_TARGETNAME} RUNTIME DESTINATION share/OpenSceneGraph/bin COMPONENT openscenegraph-examples ) ENDIF(APPLE) @@ -483,7 +494,7 @@ MACRO(HANDLE_MSVC_DLL) ENDIF(${ARGC} GREATER 1) SET_OUTPUT_DIR_PROPERTY_260(${LIB_NAME} "") # Ensure the /Debug /Release are removed - IF(NOT MSVC_IDE) + IF(NOT MSVC_IDE) IF (NOT CMAKE24) BUILDER_VERSION_GREATER(2 8 0) IF(NOT VALID_BUILDER_VERSION) @@ -516,7 +527,7 @@ MACRO(HANDLE_MSVC_DLL) ELSE (NOT CMAKE24) SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES PREFIX "../../bin/${LIB_PREFIX}${LIB_SOVERSION}-" IMPORT_PREFIX "../") ENDIF (NOT CMAKE24) - ENDIF(NOT MSVC_IDE) + ENDIF(NOT MSVC_IDE) # SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES PREFIX "../../bin/osg${OPENSCENEGRAPH_SOVERSION}-") # SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES IMPORT_PREFIX "../") diff --git a/examples/osgviewerIPhone/CMakeLists.txt b/examples/osgviewerIPhone/CMakeLists.txt index adaabe92d..4697fe047 100644 --- a/examples/osgviewerIPhone/CMakeLists.txt +++ b/examples/osgviewerIPhone/CMakeLists.txt @@ -1,17 +1,19 @@ -SET(TARGET_SRC - iphoneViewerAppDelegate.h +SET(TARGET_SRC + iphoneViewerAppDelegate.h iphoneViewerAppDelegate.mm main.m osgPlugins.h osgIPhoneViewer-Info.plist ) -SET(TARGET_ADDED_LIBRARIES osgdb_osg osgdb_freetype osgdb_imageio) +SET(TARGET_ADDED_LIBRARIES osgdb_osg osgdb_imageio osgdb_avfoundation) #backup setting SET(TMP_OSG_BUILD_APPLICATION_BUNDLES {$OSG_BUILD_APPLICATION_BUNDLES}) SET(OSG_BUILD_APPLICATION_BUNDLES TRUE) SETUP_EXAMPLE(osgViewerIPhone) +SET_TARGET_PROPERTIES(example_osgViewerIPhone PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer") + #restore setting SET(OSG_BUILD_APPLICATION_BUNDLES {$TMP_OSG_BUILD_APPLICATION_BUNDLES}) -SET(CMAKE_EXE_LINKER_FLAGS "-framework QuartzCore -framework Foundation -framework OpenGLES -framework UIKit") +SET(CMAKE_EXE_LINKER_FLAGS "-framework QuartzCore -framework Foundation -framework OpenGLES -framework UIKit -framework ImageIO -framework CoreImage -framework MobileCoreServices -framework CoreGraphics") diff --git a/examples/osgviewerIPhone/iphoneViewerAppDelegate.h b/examples/osgviewerIPhone/iphoneViewerAppDelegate.h index cb3038afc..25fa77e2c 100644 --- a/examples/osgviewerIPhone/iphoneViewerAppDelegate.h +++ b/examples/osgviewerIPhone/iphoneViewerAppDelegate.h @@ -17,7 +17,7 @@ UIWindow* _window; //main application window - UIAccelerationValue accel[3]; + CADisplayLink* _displayLink; osg::ref_ptr _viewer; osg::ref_ptr _root; diff --git a/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm b/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm index 3433400a6..7b24eff0c 100644 --- a/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm +++ b/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm @@ -1,39 +1,243 @@ -//Created by Thomas Hogarth 2009 +// Created by Thomas Hogarth 2009 +// cleaned up by Stephan Huber 2013 +// -// -//This exampe shows how to render osg into an existing windw. Apple recommends apps only have one window on IPhone so this -// will be your best bet. -// +// this example will create a fullscreen window showing a grey box. You can interact with it via +// multi-touch gestures. #import "iphoneViewerAppDelegate.h" -#include +#include #include -//inckude the iphone specific windowing stuff + +//include the iphone specific windowing stuff #include -#define kAccelerometerFrequency 30.0 // Hz -#define kFilteringFactor 0.1 - @implementation iphoneViewerAppDelegate @synthesize _window; +osg::Camera* createHUD(unsigned int w, unsigned int h) +{ + // create a camera to set up the projection and model view matrices, and the subgraph to draw in the HUD + osg::Camera* camera = new osg::Camera; + + // set the projection matrix + camera->setProjectionMatrix(osg::Matrix::ortho2D(0,w,0,h)); + + // 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); + + // we don't want the camera to grab event focus from the viewers main camera(s). + camera->setAllowEventFocus(false); + + + + // add to this camera a subgraph to render + { + + osg::Geode* geode = new osg::Geode(); + + std::string timesFont("fonts/arial.ttf"); + + // turn lighting off for the text and disable depth test to ensure it's always ontop. + osg::StateSet* stateset = geode->getOrCreateStateSet(); + stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + + osg::Vec3 position(50.0f,h-50,0.0f); + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(position); + text->setText("A simple multi-touch-example\n1 touch = rotate, \n2 touches = drag + scale, \n3 touches = home"); + } + + camera->addChild(geode); + } + + return camera; +} + + +class TestMultiTouchEventHandler : public osgGA::GUIEventHandler { +public: + TestMultiTouchEventHandler(osg::Group* parent_group) + : osgGA::GUIEventHandler(), + _cleanupOnNextFrame(false) + { + createTouchRepresentations(parent_group, 10); + } + +private: + void createTouchRepresentations(osg::Group* parent_group, unsigned int num_objects) + { + // create some geometry which is shown for every touch-point + for(unsigned int i = 0; i != num_objects; ++i) + { + std::ostringstream ss; + + osg::Geode* geode = new osg::Geode(); + + osg::ShapeDrawable* drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3(0,0,0), 100)); + drawable->setColor(osg::Vec4(0.5, 0.5, 0.5,1)); + geode->addDrawable(drawable); + + ss << "Touch " << i; + + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + drawable->setDataVariance(osg::Object::DYNAMIC); + _drawables.push_back(drawable); + + + text->setFont("fonts/arial.ttf"); + text->setPosition(osg::Vec3(110,0,0)); + text->setText(ss.str()); + _texts.push_back(text); + text->setDataVariance(osg::Object::DYNAMIC); + + + + osg::MatrixTransform* mat = new osg::MatrixTransform(); + mat->addChild(geode); + mat->setNodeMask(0x0); + + _mats.push_back(mat); + + parent_group->addChild(mat); + } + + parent_group->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + } + + virtual bool handle (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa, osg::Object *, osg::NodeVisitor *) + { + switch(ea.getEventType()) + { + case osgGA::GUIEventAdapter::FRAME: + if (_cleanupOnNextFrame) { + cleanup(0); + _cleanupOnNextFrame = false; + } + break; + + case osgGA::GUIEventAdapter::PUSH: + case osgGA::GUIEventAdapter::DRAG: + case osgGA::GUIEventAdapter::RELEASE: + { + // is this a multi-touch event? + if (!ea.isMultiTouchEvent()) + return false; + + unsigned int j(0); + + // iterate over all touch-points and update the geometry + unsigned num_touch_ended(0); + + for(osgGA::GUIEventAdapter::TouchData::iterator i = ea.getTouchData()->begin(); i != ea.getTouchData()->end(); ++i, ++j) + { + const osgGA::GUIEventAdapter::TouchData::TouchPoint& tp = (*i); + _mats[j]->setMatrix(osg::Matrix::translate(tp.x, ea.getWindowHeight() - tp.y, 0)); + _mats[j]->setNodeMask(0xffff); + + std::ostringstream ss; + ss << "Touch " << tp.id; + _texts[j]->setText(ss.str()); + + switch (tp.phase) + { + case osgGA::GUIEventAdapter::TOUCH_BEGAN: + _drawables[j]->setColor(osg::Vec4(0,1,0,1)); + std::cout << "touch began: " << ss.str() << std::endl; + break; + + case osgGA::GUIEventAdapter::TOUCH_MOVED: + //std::cout << "touch moved: " << ss.str() << std::endl; + _drawables[j]->setColor(osg::Vec4(1,1,1,1)); + break; + + case osgGA::GUIEventAdapter::TOUCH_ENDED: + _drawables[j]->setColor(osg::Vec4(1,0,0,1)); + std::cout << "touch ended: " << ss.str() << std::endl; + ++num_touch_ended; + break; + + case osgGA::GUIEventAdapter::TOUCH_STATIONERY: + _drawables[j]->setColor(osg::Vec4(0.8,0.8,0.8,1)); + break; + + default: + break; + + } + } + + // hide unused geometry + cleanup(j); + + //check if all touches ended + if ((ea.getTouchData()->getNumTouchPoints() > 0) && (ea.getTouchData()->getNumTouchPoints() == num_touch_ended)) + { + _cleanupOnNextFrame = true; + } + + // reposition mouse-pointer + aa.requestWarpPointer((ea.getWindowX() + ea.getWindowWidth()) / 2.0, (ea.getWindowY() + ea.getWindowHeight()) / 2.0); + } + break; + + default: + break; + } + + return false; + } + + void cleanup(unsigned int j) + { + for(unsigned k = j; k < _mats.size(); ++k) { + _mats[k]->setNodeMask(0x0); + } + } + + std::vector _drawables; + std::vector _mats; + std::vector _texts; + bool _cleanupOnNextFrame; + +}; + + // -//Called once app has finished launching, create the viewer then realize. Can't call viewer->run as will +//Called once app has finished launching, create the viewer then realize. Can't call viewer->run as will //block the final inialization of the windowing system // - (void)applicationDidFinishLaunching:(UIApplication *)application { - std::string test_string; - test_string = "huhu"; - //get the screen size CGRect lFrame = [[UIScreen mainScreen] bounds]; unsigned int w = lFrame.size.width; unsigned int h = lFrame.size.height; + //create the viewer + _viewer = new osgViewer::Viewer(); + + + /* + + // If you want full control over the graphics context / window creation, please uncomment this section + // create the main window at screen size self._window = [[UIWindow alloc] initWithFrame: lFrame]; @@ -41,7 +245,7 @@ [_window makeKeyAndVisible]; -//create our graphics context directly so we can pass our own window + //create our graphics context directly so we can pass our own window osg::ref_ptr traits = new osg::GraphicsContext::Traits; // Init the Windata Variable that holds the handle for the Window to display OSG in. @@ -53,97 +257,65 @@ traits->width = w; traits->height = h; traits->depth = 16; //keep memory down, default is currently 24 - //traits->alpha = 8; - //traits->stencil = 8; traits->windowDecoration = false; traits->doubleBuffer = true; traits->sharedContext = 0; traits->setInheritedWindowPixelFormat = true; - //traits->windowName = "osgViewer"; - + traits->samples = 4; + traits->sampleBuffers = 1; + traits->inheritedWindowData = windata; // Create the Graphics Context osg::ref_ptr graphicsContext = osg::GraphicsContext::createGraphicsContext(traits.get()); - - //create the viewer - _viewer = new osgViewer::Viewer(); - //if the context was created then attach to our viewer + + // if the context was created then attach to our viewer if(graphicsContext) { _viewer->getCamera()->setGraphicsContext(graphicsContext); _viewer->getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); } + */ - //create scene and attch to viewer //create root _root = new osg::MatrixTransform(); //load and attach scene model osg::ref_ptr model = (osgDB::readNodeFile("hog.osg")); - _root->addChild(model); + if (model) { + _root->addChild(model); + } + else { + osg::Geode* geode = new osg::Geode(); + osg::ShapeDrawable* drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3(1,1,1), 1)); + geode->addDrawable(drawable); + _root->addChild(geode); + } - osg::Geode* geode = new osg::Geode(); - osg::ShapeDrawable* drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3(1,1,1), 1)); - geode->addDrawable(drawable); - _root->addChild(geode); - + osg::Camera* hud_camera = createHUD(w,h); + _root->addChild(hud_camera); - //create and attach ortho camera for hud text - osg::ref_ptr _hudCamera = new osg::CameraNode; - - // set the projection matrix - _hudCamera->setProjectionMatrix(osg::Matrix::ortho2D(0,w,0,h)); - - // set the view matrix - _hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - _hudCamera->setViewMatrix(osg::Matrix::identity()); - - // only clear the depth buffer - _hudCamera->setClearMask(GL_DEPTH_BUFFER_BIT); - - // draw subgraph after main camera view. - _hudCamera->setRenderOrder(osg::CameraNode::POST_RENDER); - _root->addChild(_hudCamera.get()); - - //attcg text to hud - /*osg::ref_ptr text = new osgText::Text; - osg::ref_ptr textGeode = new osg::Geode(); - osg::StateSet* stateset = textGeode->getOrCreateStateSet(); - stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); - - textGeode->addDrawable( text ); - _hudCamera->addChild(textGeode.get()); - std::string timesFont("arial.ttf"); - osg::Vec3 position = osg::Vec3(w/2.0f, h/2.0f, 0.0f); - osg::Vec3 delta(0.0f,-120.0f,0.0f); - - - text->setFont(timesFont); - text->setCharacterSize(20.0,1.0); - text->setColor(osg::Vec4(0.8,0.8,0.8,1.0)); - text->setPosition(position); - text->setMaximumHeight(480); - text->setMaximumWidth(320); - text->setAlignment(osgText::Text::CENTER_CENTER ); - text->setText("It's a Hogs life...");*/ - _viewer->setSceneData(_root.get()); - _viewer->setCameraManipulator(new osgGA::TrackballManipulator); - _viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);//SingleThreaded DrawThreadPerContext + _viewer->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator()); - // - //_viewer->realize(); + _viewer->addEventHandler(new TestMultiTouchEventHandler(hud_camera)); + - osg::setNotifyLevel(osg::DEBUG_FP); + // sun single-threaded + _viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); - [NSTimer scheduledTimerWithTimeInterval:1.0/30.0 target:self selector:@selector(updateScene) userInfo:nil repeats:YES]; + _viewer->realize(); + + // render a frame so the window-manager shows some content and not only an empty + black window + _viewer->frame(); + + + // create a display link, which will update our scene on every screen-refresh + _displayLink = [application.keyWindow.screen displayLinkWithTarget:self selector:@selector(updateScene)]; + [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - //Configure and start accelerometer - [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)]; - [[UIAccelerometer sharedAccelerometer] setDelegate:self]; } @@ -165,21 +337,15 @@ } --(void)applicationWillTerminate:(UIApplication *)application{ +-(void)applicationWillTerminate:(UIApplication *)application { + if (_displayLink) + [_displayLink invalidate]; + _displayLink = NULL; _root = NULL; _viewer = NULL; } -// -//Accelorometer -// -- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration -{ - //Use a basic low-pass filter to only keep the gravity in the accelerometer values - accel[0] = acceleration.x * kFilteringFactor + accel[0] * (1.0 - kFilteringFactor); - accel[1] = acceleration.y * kFilteringFactor + accel[1] * (1.0 - kFilteringFactor); - accel[2] = acceleration.z * kFilteringFactor + accel[2] * (1.0 - kFilteringFactor); -} + - (void)dealloc { diff --git a/examples/osgviewerIPhone/osgPlugins.h b/examples/osgviewerIPhone/osgPlugins.h index 229d91afb..6ed790eb1 100644 --- a/examples/osgviewerIPhone/osgPlugins.h +++ b/examples/osgviewerIPhone/osgPlugins.h @@ -14,6 +14,6 @@ USE_GRAPICSWINDOW_IMPLEMENTATION(IOS) USE_OSGPLUGIN(osg) USE_OSGPLUGIN(imageio) - -USE_OSGPLUGIN(freetype) +USE_OSGPLUGIN(avfoundation) +//USE_OSGPLUGIN(freetype) diff --git a/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp b/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp index 7e556479b..1743ca81b 100644 --- a/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp +++ b/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp @@ -267,6 +267,11 @@ RestHttpDevice::RestHttpDevice(const std::string& listening_address, const std:: , _firstEventLocalTimeStamp() , _firstEventRemoteTimeStamp(-1) , _lastEventRemoteTimeStamp(0) + , _currentMouseX(0.0f) + , _currentMouseY(0.0f) + , _targetMouseX(0.0f) + , _targetMouseY(0.0f) + , _targetMouseChanged(false) { setCapabilities(RECEIVE_EVENTS); diff --git a/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp b/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp index b0f5f3c89..982d12022 100644 --- a/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp +++ b/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp @@ -171,7 +171,7 @@ public: virtual bool checkEvents() { - if ((fabs(_currentMouseX - _targetMouseY) > 0.1f) || (fabs(_currentMouseY - _targetMouseY) > 0.1)) + if (_targetMouseChanged && (fabs(_currentMouseX - _targetMouseY) > 0.1f) || (fabs(_currentMouseY - _targetMouseY) > 0.1)) { static const float scalar = 0.2f; _currentMouseX = (1.0f - scalar) * _currentMouseX + scalar * _targetMouseX; @@ -183,6 +183,7 @@ public: void setTargetMousePosition(float x, float y, bool force = false) { + _targetMouseChanged = true; _targetMouseX = x; _targetMouseY = y; if (force) { _currentMouseX = x; _currentMouseY = y; @@ -200,6 +201,7 @@ private: double _firstEventRemoteTimeStamp; double _lastEventRemoteTimeStamp; float _currentMouseX, _currentMouseY, _targetMouseX, _targetMouseY; + bool _targetMouseChanged; }; diff --git a/src/osgPlugins/ZeroConfDevice/AutoDiscoveryBonjourImpl.mm b/src/osgPlugins/ZeroConfDevice/AutoDiscoveryBonjourImpl.mm index 1ca400d21..063c73799 100755 --- a/src/osgPlugins/ZeroConfDevice/AutoDiscoveryBonjourImpl.mm +++ b/src/osgPlugins/ZeroConfDevice/AutoDiscoveryBonjourImpl.mm @@ -68,10 +68,8 @@ @property (readonly, retain) NSMutableArray *services; @property (readwrite, retain) NSString *type; -@property (readwrite, assign) BOOL isConnected; @property (readwrite, retain) NSNetServiceBrowser *browser; -@property (readwrite, retain) NSNetService *connectedService; @end @@ -80,15 +78,12 @@ @synthesize browser; @synthesize type; @synthesize services; -@synthesize isConnected; -@synthesize connectedService; -(id)initWithType: (NSString*) in_type withImpl:(AutoDiscoveryClientImpl*) in_impl { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; services = [NSMutableArray new]; self.browser = [[NSNetServiceBrowser new] init]; self.browser.delegate = self; - self.isConnected = NO; self.type = in_type; impl = in_impl; [self.browser searchForServicesOfType:in_type inDomain:@""]; @@ -97,9 +92,15 @@ } -(void)dealloc { - self.connectedService = nil; + + [self.browser stop]; + self.browser.delegate = nil; + self.browser = nil; + [services makeObjectsPerformSelector:@selector(setDelegate:) withObject:nil]; + [services makeObjectsPerformSelector:@selector(stop)]; [services release]; + [super dealloc]; } @@ -118,16 +119,11 @@ { int ndx = [services indexOfObject: aService]; impl->servicesRemoved([services objectAtIndex: ndx]); - + aService.delegate = nil; [services removeObject:aService]; - if ( aService == self.connectedService ) self.isConnected = NO; - - } -(void)netServiceDidResolveAddress:(NSNetService *)service { - self.isConnected = YES; - self.connectedService = service; //NSLog(@"hostname: %@", [service hostName]); @@ -220,4 +216,4 @@ void AutoDiscoveryClientImpl::servicesRemoved(void* key) AutoDiscoveryClientImpl::~AutoDiscoveryClientImpl() { [_controller release]; -} \ No newline at end of file +} diff --git a/src/osgPlugins/avfoundation/CMakeLists.txt b/src/osgPlugins/avfoundation/CMakeLists.txt index 3ede192ba..b09d36e93 100644 --- a/src/osgPlugins/avfoundation/CMakeLists.txt +++ b/src/osgPlugins/avfoundation/CMakeLists.txt @@ -1,6 +1,5 @@ -INCLUDE_DIRECTORIES( ${AV_FOUNDATION_INCLUDE_DIR} ) -SET(TARGET_SRC +SET(TARGET_SRC OSXAVFoundationVideo.mm OSXAVFoundationVideo.h ../QTKit/VideoFrameDispatcher.h diff --git a/src/osgPlugins/osc/OscSendingDevice.cpp b/src/osgPlugins/osc/OscSendingDevice.cpp index fd9cf5a55..f5e191cf0 100644 --- a/src/osgPlugins/osc/OscSendingDevice.cpp +++ b/src/osgPlugins/osc/OscSendingDevice.cpp @@ -51,9 +51,14 @@ void OscSendingDevice::sendEvent(const osgGA::GUIEventAdapter &ea) { static osc::int64 msg_id(0); bool msg_sent(false); - for(unsigned int i = 0; i < _numMessagesPerEvent; ++i) { + unsigned int num_messages = _numMessagesPerEvent; + + if((ea.getEventType() == osgGA::GUIEventAdapter::DRAG) || (ea.getEventType() == osgGA::GUIEventAdapter::MOVE)) + num_messages = 1; + + for(unsigned int i = 0; i < num_messages; ++i) { msg_sent = sendEventImpl(ea, msg_id); - if ((_delayBetweenSendsInMilliSecs > 0) && (i < _numMessagesPerEvent-1)) + if ((_delayBetweenSendsInMilliSecs > 0) && (i < num_messages-1)) OpenThreads::Thread::microSleep(1000 * _delayBetweenSendsInMilliSecs); } if (msg_sent) diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index b2801ae5d..bd3c52ada 100644 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -312,7 +312,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) #if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) - (osgGA::GUIEventAdapter::TouchPhase) convertTouchPhase: (NSTouchPhase) phase; -- (unsigned int)computeTouchId: (NSTouch*) touch; +- (unsigned int)computeTouchId: (NSTouch*) touch mayCleanup: (BOOL) may_cleanup; - (void)touchesBeganWithEvent:(NSEvent *)event; - (void)touchesMovedWithEvent:(NSEvent *)event; - (void)touchesEndedWithEvent:(NSEvent *)event; @@ -813,7 +813,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) } -- (unsigned int)computeTouchId: (NSTouch*) touch +- (unsigned int)computeTouchId: (NSTouch*) touch mayCleanup: (BOOL) may_cleanup { unsigned int result(0); @@ -847,7 +847,8 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) { NSNumber* n = [_touchPoints objectForKey: [touch identity]]; result = [n intValue]; - [_touchPoints removeObjectForKey: [touch identity]]; + if(may_cleanup) + [_touchPoints removeObjectForKey: [touch identity]]; if([_touchPoints count] == 0) { _lastTouchPointId = 0; } @@ -876,7 +877,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) NSTouch *touch = [[allTouches allObjects] objectAtIndex:i]; NSPoint pos = [touch normalizedPosition]; osg::Vec2 pixelPos(pos.x * bounds.size.width, (1-pos.y) * bounds.size.height); - unsigned int touch_id = [self computeTouchId: touch]; + unsigned int touch_id = [self computeTouchId: touch mayCleanup:FALSE]; if (!osg_event) { osg_event = _win->getEventQueue()->touchBegan(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y()); } else { @@ -897,7 +898,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) NSTouch *touch = [[allTouches allObjects] objectAtIndex:i]; NSPoint pos = [touch normalizedPosition]; osg::Vec2 pixelPos(pos.x * bounds.size.width, (1 - pos.y) * bounds.size.height); - unsigned int touch_id = [self computeTouchId: touch]; + unsigned int touch_id = [self computeTouchId: touch mayCleanup:FALSE]; if (!osg_event) { osg_event = _win->getEventQueue()->touchMoved(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y()); } else { @@ -919,7 +920,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) NSTouch *touch = [[allTouches allObjects] objectAtIndex:i]; NSPoint pos = [touch normalizedPosition]; osg::Vec2 pixelPos(pos.x * bounds.size.width, (1 - pos.y) * bounds.size.height); - unsigned int touch_id = [self computeTouchId: touch]; + unsigned int touch_id = [self computeTouchId: touch mayCleanup: TRUE]; if (!osg_event) { osg_event = _win->getEventQueue()->touchEnded(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y(), 1); } else { diff --git a/src/osgViewer/GraphicsWindowIOS.mm b/src/osgViewer/GraphicsWindowIOS.mm index c4cf370d0..89b54e977 100644 --- a/src/osgViewer/GraphicsWindowIOS.mm +++ b/src/osgViewer/GraphicsWindowIOS.mm @@ -163,7 +163,7 @@ typedef std::map TouchPointsIdMapping; } -- (unsigned int)computeTouchId: (UITouch*) touch +- (unsigned int)computeTouchId: (UITouch*) touch mayCleanup: (bool)may_cleanup { unsigned int result(0); @@ -202,10 +202,10 @@ typedef std::map TouchPointsIdMapping; { TouchPointsIdMapping::iterator itr = _touchPointsIdMapping->find(touch); // std::cout<< "remove: " << touch << " num: " << _touchPointsIdMapping->size() << " found: " << (itr != _touchPointsIdMapping->end()) << std::endl; - if (itr != _touchPointsIdMapping->end()) { result = itr->second; - _touchPointsIdMapping->erase(itr); + if(may_cleanup) + _touchPointsIdMapping->erase(itr); } if(_touchPointsIdMapping->size() == 0) { _lastTouchPointId = 0; @@ -576,9 +576,9 @@ typedef std::map TouchPointsIdMapping; { UITouch *touch = [[allTouches allObjects] objectAtIndex:i]; - CGPoint pos = [touch locationInView:touch.view]; + CGPoint pos = [touch locationInView:self]; osg::Vec2 pixelPos = [self convertPointToPixel: osg::Vec2(pos.x,pos.y)]; - unsigned int touch_id = [self computeTouchId: touch]; + unsigned int touch_id = [self computeTouchId: touch mayCleanup: FALSE]; if (!osg_event) { osg_event = _win->getEventQueue()->touchBegan(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y()); @@ -599,9 +599,9 @@ typedef std::map TouchPointsIdMapping; for(int i=0; i<[allTouches count]; i++) { UITouch *touch = [[allTouches allObjects] objectAtIndex:i]; - CGPoint pos = [touch locationInView:touch.view]; + CGPoint pos = [touch locationInView:self]; osg::Vec2 pixelPos = [self convertPointToPixel: osg::Vec2(pos.x,pos.y)]; - unsigned int touch_id = [self computeTouchId: touch]; + unsigned int touch_id = [self computeTouchId: touch mayCleanup: FALSE]; if (!osg_event) { osg_event = _win->getEventQueue()->touchMoved(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y()); @@ -623,9 +623,9 @@ typedef std::map TouchPointsIdMapping; for(int i=0; i<[allTouches count]; i++) { UITouch *touch = [[allTouches allObjects] objectAtIndex:i]; - CGPoint pos = [touch locationInView:touch.view]; + CGPoint pos = [touch locationInView:self]; osg::Vec2 pixelPos = [self convertPointToPixel: osg::Vec2(pos.x,pos.y)]; - unsigned int touch_id = [self computeTouchId: touch]; + unsigned int touch_id = [self computeTouchId: touch mayCleanup: TRUE]; if (!osg_event) { osg_event = _win->getEventQueue()->touchEnded(touch_id, [self convertTouchPhase: [touch phase]], pixelPos.x(), pixelPos.y(), [touch tapCount]); } else {