From e8b5272b02105108c79aa780842bba51e5cf596f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 7 Oct 2013 10:05:09 +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 | 4 +- CMakeModules/OsgMacroUtils.cmake | 13 +- 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, 342 insertions(+), 140 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47ef3f4b1..01a3e094d 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) @@ -819,6 +822,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. @@ -878,8 +889,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) @@ -911,7 +928,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 6224ec010..ff888f025 100644 --- a/CMakeModules/FindAVFoundation.cmake +++ b/CMakeModules/FindAVFoundation.cmake @@ -2,7 +2,6 @@ # 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_DIR is an environment variable that would # correspond to the ./configure --prefix=$AV_FOUNDATION_DIR @@ -11,12 +10,11 @@ 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() diff --git a/CMakeModules/OsgMacroUtils.cmake b/CMakeModules/OsgMacroUtils.cmake index 264ba44dd..7575995ab 100644 --- a/CMakeModules/OsgMacroUtils.cmake +++ b/CMakeModules/OsgMacroUtils.cmake @@ -224,6 +224,9 @@ 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) @@ -317,7 +320,9 @@ 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} @@ -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 "") @@ -396,6 +403,10 @@ 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) + IF(APPLE) + SET_TARGET_PROPERTIES(${TARGET_TARGETNAME} PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS "") + ENDIF() + SETUP_LINK_LIBRARIES() ENDMACRO(SETUP_EXE) 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 {