Просмотр исходного кода

Merge branch 'next' of https://github.com/blackberry-gaming/GamePlay into next-ablake

Conflicts:
	gameplay/src/Container.cpp
	gameplay/src/Form.cpp
Adam Blake 13 лет назад
Родитель
Сommit
48fbf29317
40 измененных файлов с 313 добавлено и 335 удалено
  1. 2 1
      CHANGES.md
  2. 2 2
      README.md
  3. 1 1
      gameplay-encoder/src/GPBFile.cpp
  4. 1 3
      gameplay/gameplay.vcxproj
  5. 1 7
      gameplay/gameplay.vcxproj.filters
  6. 16 17
      gameplay/src/AnimationClip.cpp
  7. 8 7
      gameplay/src/AnimationClip.h
  8. 1 1
      gameplay/src/AnimationController.cpp
  9. 1 1
      gameplay/src/AnimationController.h
  10. 0 1
      gameplay/src/AnimationTarget.cpp
  11. 1 1
      gameplay/src/AudioController.cpp
  12. 1 1
      gameplay/src/AudioController.h
  13. 9 15
      gameplay/src/Base.h
  14. 8 8
      gameplay/src/Container.cpp
  15. 3 3
      gameplay/src/Container.h
  16. 5 1
      gameplay/src/Control.h
  17. 16 14
      gameplay/src/Game.cpp
  18. 11 11
      gameplay/src/Game.h
  19. 6 0
      gameplay/src/Joystick.cpp
  20. 1 1
      gameplay/src/Node.cpp
  21. 6 8
      gameplay/src/ParticleEmitter.cpp
  22. 2 3
      gameplay/src/ParticleEmitter.h
  23. 2 2
      gameplay/src/PhysicsCharacter.cpp
  24. 65 5
      gameplay/src/PhysicsCollisionObject.cpp
  25. 46 8
      gameplay/src/PhysicsCollisionObject.h
  26. 2 3
      gameplay/src/PhysicsConstraint.cpp
  27. 19 18
      gameplay/src/PhysicsController.cpp
  28. 23 6
      gameplay/src/PhysicsController.h
  29. 0 1
      gameplay/src/PhysicsGenericConstraint.cpp
  30. 0 72
      gameplay/src/PhysicsMotionState.cpp
  31. 0 61
      gameplay/src/PhysicsMotionState.h
  32. 0 1
      gameplay/src/PhysicsRigidBody.cpp
  33. 2 2
      gameplay/src/Platform.h
  34. 7 7
      gameplay/src/PlatformAndroid.cpp
  35. 8 8
      gameplay/src/PlatformMacOSX.mm
  36. 7 7
      gameplay/src/PlatformQNX.cpp
  37. 11 11
      gameplay/src/PlatformWin32.cpp
  38. 9 9
      gameplay/src/PlatformiOS.mm
  39. 4 1
      gameplay/src/SceneLoader.cpp
  40. 6 6
      gameplay/src/ScreenDisplayer.h

+ 2 - 1
CHANGES.md

@@ -5,7 +5,8 @@
 - User Interface support for scrolling with scrollbars on Container.
 - PVRTC, ATC and DXT texture compression support.
 - Performance improvements in user interface forms and text.
-- Performance improvements in animations on transforms.
+- Performance improvements in animations on transforms.
+- Performance improvements using NEON math for BlackBerry and iOS.
 - Fixes for improvements in error handling throughout all systems.
 - Fixes supporting built-in Maya COLLADA exporter via DAE_FBX export.
 - Fixes for latest FBX SDK 2013 support.

+ 2 - 2
README.md

@@ -3,7 +3,7 @@ An open-source, cross-platform 3D native C++ game framework making it easy to le
 
 ## Supported Mobile Platforms
 - BlackBerry 10 and PlayBook 2.0 (using BlackBerry Native SDK)
-- Google Android 2.3+ (using Google Android NDK r7, SDK API level 9+)
+- Google Android 2.3+ (using Google Android NDK, SDK API level 9+)
 - Apple iOS 5.1 (using Apple XCode 4.3.2)
 
 ## Supported Desktop Platforms
@@ -11,8 +11,8 @@ An open-source, cross-platform 3D native C++ game framework making it easy to le
 - Apple MacOS X (using Apple XCode 4.3.2)
 
 ## Roadmap for 'next' branch
-- Gamepad support
 - Lua script bindings
+- Gamepad support
 - Vehicle physics
 - Terrain
 - Lightmaps

+ 1 - 1
gameplay-encoder/src/GPBFile.cpp

@@ -429,7 +429,7 @@ void GPBFile::decomposeTransformAnimationChannel(Animation* animation, const Ani
 
 static bool isAlmostOne(float value)
 {
-    return std::abs(value - 1.0f) < EPSILON;
+    return std::fabs(value - 1.0f) < EPSILON;
 }
 
 }

+ 1 - 3
gameplay/gameplay.vcxproj

@@ -73,7 +73,6 @@
     <ClCompile Include="src\PhysicsGenericConstraint.cpp" />
     <ClCompile Include="src\PhysicsGhostObject.cpp" />
     <ClCompile Include="src\PhysicsHingeConstraint.cpp" />
-    <ClCompile Include="src\PhysicsMotionState.cpp" />
     <ClCompile Include="src\PhysicsRigidBody.cpp" />
     <ClCompile Include="src\PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\PhysicsSpringConstraint.cpp" />
@@ -167,7 +166,6 @@
     <ClInclude Include="src\PhysicsGenericConstraint.h" />
     <ClInclude Include="src\PhysicsGhostObject.h" />
     <ClInclude Include="src\PhysicsHingeConstraint.h" />
-    <ClInclude Include="src\PhysicsMotionState.h" />
     <ClInclude Include="src\PhysicsRigidBody.h" />
     <ClInclude Include="src\PhysicsSocketConstraint.h" />
     <ClInclude Include="src\PhysicsSpringConstraint.h" />
@@ -365,4 +363,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 1 - 7
gameplay/gameplay.vcxproj.filters

@@ -192,9 +192,6 @@
     <ClCompile Include="src\PhysicsSpringConstraint.cpp">
       <Filter>src</Filter>
     </ClCompile>
-    <ClCompile Include="src\PhysicsMotionState.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
     <ClCompile Include="src\SceneLoader.cpp">
       <Filter>src</Filter>
     </ClCompile>
@@ -440,9 +437,6 @@
     <ClInclude Include="src\PhysicsController.h">
       <Filter>src</Filter>
     </ClInclude>
-    <ClInclude Include="src\PhysicsMotionState.h">
-      <Filter>src</Filter>
-    </ClInclude>
     <ClInclude Include="src\PhysicsRigidBody.h">
       <Filter>src</Filter>
     </ClInclude>
@@ -715,4 +709,4 @@
       <Filter>src</Filter>
     </None>
   </ItemGroup>
-</Project>
+</Project>

+ 16 - 17
gameplay/src/AnimationClip.cpp

@@ -84,7 +84,7 @@ unsigned long AnimationClip::getEndTime() const
     return _endTime;
 }
 
-unsigned long AnimationClip::getElaspedTime() const
+float AnimationClip::getElaspedTime() const
 {
     return _elapsedTime;
 }
@@ -120,7 +120,7 @@ void AnimationClip::setActiveDuration(unsigned long duration)
     else
     {
         _activeDuration = _duration;
-        _repeatCount = (float) _activeDuration / (float) _duration;
+        _repeatCount = (float)_activeDuration / (float)_duration;
     }
 }
 
@@ -242,7 +242,7 @@ void AnimationClip::crossFade(AnimationClip* clip, unsigned long duration)
     // Set and intiliaze this clip to fade out
     setClipStateBit(CLIP_IS_FADING_OUT_STARTED_BIT);
     setClipStateBit(CLIP_IS_FADING_OUT_BIT);
-    _crossFadeOutElapsed = 0L;
+    _crossFadeOutElapsed = 0.0f;
     _crossFadeOutDuration = duration;
     
     // If this clip is currently not playing, we should start playing it.
@@ -282,8 +282,8 @@ void AnimationClip::addListener(AnimationClip::Listener* listener, unsigned long
                 // otherwise, it will just be set the next time the clip gets played.
                 if (isClipStateBitSet(CLIP_IS_PLAYING_BIT))
                 {
-                    unsigned long currentTime = _elapsedTime % _duration;
-                    GP_ASSERT(**_listenerItr);
+                    float currentTime = fmodf(_elapsedTime, (float)_duration);
+                    GP_ASSERT(**_listenerItr || *_listenerItr == _listeners->end());
                     if ((_speed >= 0.0f && currentTime < eventTime && (*_listenerItr == _listeners->end() || eventTime < (**_listenerItr)->_eventTime)) || 
                         (_speed <= 0 && currentTime > eventTime && (*_listenerItr == _listeners->begin() || eventTime > (**_listenerItr)->_eventTime)))
                         *_listenerItr = itr;
@@ -313,7 +313,7 @@ void AnimationClip::addEndListener(AnimationClip::Listener* listener)
     _endListeners->push_back(listener);
 }
 
-bool AnimationClip::update(unsigned long elapsedTime)
+bool AnimationClip::update(float elapsedTime)
 {
     if (isClipStateBitSet(CLIP_IS_PAUSED_BIT))
     {
@@ -338,9 +338,9 @@ bool AnimationClip::update(unsigned long elapsedTime)
             _elapsedTime = _activeDuration + _elapsedTime;
     }
 
-    unsigned long currentTime = 0L;
+    float currentTime = 0.0f;
     // Check to see if clip is complete.
-    if (_repeatCount != REPEAT_INDEFINITE && ((_speed >= 0.0f && _elapsedTime >= (long) _activeDuration) || (_speed <= 0.0f && _elapsedTime <= 0L)))
+    if (_repeatCount != REPEAT_INDEFINITE && ((_speed >= 0.0f && _elapsedTime >= _activeDuration) || (_speed <= 0.0f && _elapsedTime <= 0.0f)))
     {
         resetClipStateBit(CLIP_IS_STARTED_BIT);
         
@@ -349,34 +349,33 @@ bool AnimationClip::update(unsigned long elapsedTime)
             // If _duration == 0, we have a "pose". Just set currentTime to 0.
             if (_duration == 0)
             {
-                currentTime = 0L;
+                currentTime = 0.0f;
             }
             else
             {
-                currentTime = _activeDuration % _duration; // Get's the fractional part of the final repeat.
-                if (currentTime == 0L)
+                currentTime = (float)(_activeDuration % _duration); // Get's the fractional part of the final repeat.
+                if (currentTime == 0.0f)
                     currentTime = _duration;
             }
         }
         else
         {
-            currentTime = 0L; // If we are negative speed, the end value should be 0.
+            currentTime = 0.0f; // If we are negative speed, the end value should be 0.
         }
     }
     else
     {
         // If _duration == 0, we have a "pose". Just set currentTime to 0.
         if (_duration == 0)
-            currentTime = 0L;
+            currentTime = 0.0f;
         else // Gets portion/fraction of the repeat.
-            currentTime = _elapsedTime % _duration;
+            currentTime = fmodf(_elapsedTime, _duration);
     }
 
     // Notify any listeners of Animation events.
     if (_listeners)
     {
         GP_ASSERT(_listenerItr);
-        GP_ASSERT(**_listenerItr);
 
         if (_speed >= 0.0f)
         {
@@ -407,7 +406,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
     // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
     GP_ASSERT(_animation);
     GP_ASSERT(_animation->_duration > 0);
-    float percentComplete = (float)(_startTime + currentTime) / (float) _animation->_duration;
+    float percentComplete = ((float)_startTime + currentTime) / (float)_animation->_duration;
     
     if (isClipStateBitSet(CLIP_IS_FADING_OUT_BIT))
     {
@@ -429,7 +428,7 @@ bool AnimationClip::update(unsigned long elapsedTime)
         if (_crossFadeOutElapsed < _crossFadeOutDuration)
         {
             // Calculate this clip's blend weight.
-            float tempBlendWeight = (float) (_crossFadeOutDuration - _crossFadeOutElapsed) / (float) _crossFadeOutDuration;
+            float tempBlendWeight = ((float)_crossFadeOutDuration - _crossFadeOutElapsed) / (float)_crossFadeOutDuration;
             
             // If this clip is fading in, adjust the crossfade clip's weight to be a percentage of your current blend weight
             if (isClipStateBitSet(CLIP_IS_FADING_IN_BIT))

+ 8 - 7
gameplay/src/AnimationClip.h

@@ -103,7 +103,7 @@ public:
      *
      * @return The elapsed time of the AnimationClip (in milliseconds).
      */
-    unsigned long getElaspedTime() const;
+    float getElaspedTime() const;
 
     /**
      * Sets the AnimationClip's repeat count. Overrides repeat duration.
@@ -126,7 +126,7 @@ public:
      *
      * Use REPEAT_INDEFINITE to play the AnimationClip indefinitely.
      *
-     * @param duration The active duration that is set on the AnimationClip.
+     * @param duration The active duration that is set on the AnimationClip, in milliseconds.
      */
     void setActiveDuration(unsigned long duration);
 
@@ -140,7 +140,7 @@ public:
     /**
      * Gets the AnimationClip's duration.
      *
-     * @return the AnimationClip's duration.
+     * @return the AnimationClip's duration, in milliseconds.
      */
     unsigned long getDuration() const;
 
@@ -283,7 +283,7 @@ private:
     /**
      * Updates the animation with the elapsed time.
      */
-    bool update(unsigned long elapsedTime);
+    bool update(float elapsedTime);
 
     /**
      * Handles when the AnimationClip begins.
@@ -319,10 +319,10 @@ private:
     float _repeatCount;                                 // The clip's repeat count.
     unsigned long _activeDuration;                      // The active duration of the clip.
     float _speed;                                       // The speed that the clip is playing. Default is 1.0. Negative goes in reverse.
-    unsigned long _timeStarted;                         // The game time when this clip was actually started.
-    long _elapsedTime;                                  // Time elapsed while the clip is running.
+    double _timeStarted;                                // The game time when this clip was actually started.
+    float _elapsedTime;                                 // Time elapsed while the clip is running.
     AnimationClip* _crossFadeToClip;                    // The clip to cross fade to.
-    unsigned long _crossFadeOutElapsed;                 // The amount of time that has elapsed for the crossfade.
+    float _crossFadeOutElapsed;                         // The amount of time that has elapsed for the crossfade.
     unsigned long _crossFadeOutDuration;                // The duration of the cross fade.
     float _blendWeight;                                 // The clip's blendweight.
     std::vector<AnimationValue*> _values;               // AnimationValue holder.
@@ -333,4 +333,5 @@ private:
 };
 
 }
+
 #endif

+ 1 - 1
gameplay/src/AnimationController.cpp

@@ -93,7 +93,7 @@ void AnimationController::unschedule(AnimationClip* clip)
         _state = IDLE;
 }
 
-void AnimationController::update(long elapsedTime)
+void AnimationController::update(float elapsedTime)
 {
     if (_state != RUNNING)
         return;

+ 1 - 1
gameplay/src/AnimationController.h

@@ -94,7 +94,7 @@ private:
     /**
      * Callback for when the controller receives a frame update event.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
     
     State _state;                                 // The current state of the AnimationController.
     std::list<AnimationClip*> _runningClips;      // A list of running AnimationClips.

+ 0 - 1
gameplay/src/AnimationTarget.cpp

@@ -419,7 +419,6 @@ Animation::Channel* AnimationTarget::getChannel(const char* id) const
     if (_animationChannels)
     {
         std::vector<Animation::Channel*>::iterator itr = _animationChannels->begin();
-        GP_ASSERT(*itr);
 
         if (id == NULL)
             return (*itr);

+ 1 - 1
gameplay/src/AudioController.cpp

@@ -91,7 +91,7 @@ void AudioController::resume()
     }
 }
 
-void AudioController::update(long elapsedTime)
+void AudioController::update(float elapsedTime)
 {
     AudioListener* listener = AudioListener::getInstance();
     if (listener)

+ 1 - 1
gameplay/src/AudioController.h

@@ -52,7 +52,7 @@ private:
     /**
      * Controller update.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
 
 
     ALCdevice* _alcDevice;

+ 9 - 15
gameplay/src/Base.h

@@ -39,6 +39,8 @@ using std::size_t;
 using std::min;
 using std::max;
 using std::modf;
+using std::fmodf;
+using std::fmodl;
 
 // Common
 #ifndef NULL
@@ -60,20 +62,9 @@ extern void printError(const char* format, ...);
 
 // Assert macros.
 #ifdef _DEBUG
-#ifdef WIN32
-#define GP_FORCE_ASSERTION_FAILURE do { __debugbreak(); } while (0)
-#else
-#define GP_FORCE_ASSERTION_FAILURE do { assert(0); } while (0)
-#endif
-#define GP_ASSERT(expression) do { \
-    if (!(expression)) \
-    { \
-        printError("%s -- Assertion '" #expression "' failed.\n", __current__func__); \
-        GP_FORCE_ASSERTION_FAILURE; \
-    } } while (0)
+#define GP_ASSERT(expression) assert(expression)
 #else
-#define GP_FORCE_ASSERTION_FAILURE do { (void)sizeof(int); } while (0)
-#define GP_ASSERT(expression) do { (void)sizeof(expression); } while (0)
+#define GP_ASSERT(expression)
 #endif
 
 // Error macro.
@@ -85,7 +76,7 @@ extern void printError(const char* format, ...);
         printError("%s -- ", __current__func__); \
         printError(__VA_ARGS__); \
         printError("\n"); \
-        GP_FORCE_ASSERTION_FAILURE; \
+        assert(0); \
         std::exit(-1); \
     } while (0)
 #endif
@@ -191,7 +182,7 @@ extern void printError(const char* format, ...);
     #define glClearDepth glClearDepthf
     #define OPENGL_ES
     #define USE_PVRTC
-    #ifdef __ARM__
+    #ifdef __arm__
         #define USE_NEON
     #endif
 #elif __ANDROID__
@@ -220,6 +211,9 @@ extern void printError(const char* format, ...);
         #define glClearDepth glClearDepthf
         #define OPENGL_ES
         #define USE_VAO
+        #ifdef __arm__
+            #define USE_NEON
+        #endif
     #elif TARGET_OS_MAC
         #include <OpenGL/gl.h>
         #include <OpenGL/glext.h>

+ 8 - 8
gameplay/src/Container.cpp

@@ -568,9 +568,9 @@ Layout::Type Container::getLayoutType(const char* layoutString)
 void Container::updateScroll()
 {
     // Update Time.
-    static long lastFrameTime = Game::getGameTime();
-    long frameTime = Game::getGameTime();
-    long elapsedTime = (frameTime - lastFrameTime);
+    double lastFrameTime = Game::getGameTime();
+    double frameTime = Game::getGameTime();
+    float elapsedTime = (float)(frameTime - lastFrameTime);
     lastFrameTime = frameTime;
 
     const Theme::Border& containerBorder = getBorder(_state);
@@ -617,9 +617,9 @@ void Container::updateScroll()
         _scrollingVelocity.x *= dampening;
         _scrollingVelocity.y *= dampening;
 
-        if (abs(_scrollingVelocity.x) < 100.0f)
+        if (fabs(_scrollingVelocity.x) < 100.0f)
             _scrollingVelocity.x = 0.0f;
-        if (abs(_scrollingVelocity.y) < 100.0f)
+        if (fabs(_scrollingVelocity.y) < 100.0f)
             _scrollingVelocity.y = 0.0f;
     }
 
@@ -762,7 +762,7 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
     case Touch::TOUCH_RELEASE:
         _scrolling = false;
         long gameTime = Game::getAbsoluteTime();
-        long timeSinceLastMove = gameTime - _scrollingLastTime;
+        float timeSinceLastMove = (float)(gameTime - _scrollingLastTime);
         if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
         {
             _scrollingVelocity.set(0, 0);
@@ -773,9 +773,9 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
         int dx = _scrollingLastX - _scrollingFirstX;
         int dy = _scrollingLastY - _scrollingFirstY;
 
-        long timeTakenX = gameTime - _scrollingStartTimeX;
+        float timeTakenX = (float)(gameTime - _scrollingStartTimeX);
         float elapsedSecsX = (float)timeTakenX * 0.001f;
-        long timeTakenY = gameTime - _scrollingStartTimeY;
+        float timeTakenY = (float)(gameTime - _scrollingStartTimeY);
         float elapsedSecsY = (float)timeTakenY * 0.001f;
 
         float vx = dx;

+ 3 - 3
gameplay/src/Container.h

@@ -413,15 +413,15 @@ protected:
     /** 
      * Time we started scrolling in the x
      */ 
-    long _scrollingStartTimeX;
+    double _scrollingStartTimeX;
     /** 
      * Time we started scrolling in the y
      */ 
-    long _scrollingStartTimeY;
+    double _scrollingStartTimeY;
     /** 
      * The last time we were scrolling
      */
-    long _scrollingLastTime;
+    double _scrollingLastTime;
     /** 
      * Speed to continue scrolling at after touch release.
      */ 

+ 5 - 1
gameplay/src/Control.h

@@ -899,6 +899,11 @@ protected:
      */
     Rectangle _viewportClipBounds;
 
+    /**
+     * Previous frame's absolute clip bounds, to be cleared if necessary.
+     */
+    Rectangle _clearBounds;         
+
     /**
      * If the control is dirty and need updating.
      */
@@ -979,7 +984,6 @@ private:
     
     bool _styleOverridden;
     Theme::Skin* _skin;
-    Rectangle _clearBounds;         // Previous frame's absolute clip bounds, to be cleared if necessary.
 };
 
 }

+ 16 - 14
gameplay/src/Game.cpp

@@ -13,8 +13,8 @@ namespace gameplay
 {
 
 static Game* __gameInstance = NULL;
-long Game::_pausedTimeLast = 0L;
-long Game::_pausedTimeTotal = 0L;
+double Game::_pausedTimeLast = 0.0;
+double Game::_pausedTimeTotal = 0.0;
 
 Game::Game() 
     : _initialized(false), _state(UNINITIALIZED), 
@@ -48,12 +48,12 @@ Game* Game::getInstance()
     return __gameInstance;
 }
 
-long Game::getAbsoluteTime()
+double Game::getAbsoluteTime()
 {
     return Platform::getAbsoluteTime();
 }
 
-long Game::getGameTime()
+double Game::getGameTime()
 {
     return Platform::getAbsoluteTime() - _pausedTimeTotal;
 }
@@ -193,9 +193,9 @@ void Game::frame()
         GP_ASSERT(_physicsController);
 
         // Update Time.
-        static long lastFrameTime = Game::getGameTime();
-        long frameTime = Game::getGameTime();
-        long elapsedTime = (frameTime - lastFrameTime);
+        static double lastFrameTime = Game::getGameTime();
+        double frameTime = getGameTime();
+        float elapsedTime = (frameTime - lastFrameTime);
         lastFrameTime = frameTime;
 
         // Update the scheduled and running animations.
@@ -206,11 +206,13 @@ void Game::frame()
     
         // Update the physics.
         _physicsController->update(elapsedTime);
+
         // Application Update.
         update(elapsedTime);
 
         // Audio Rendering.
         _audioController->update(elapsedTime);
+
         // Graphics Rendering.
         render(elapsedTime);
 
@@ -220,7 +222,7 @@ void Game::frame()
         {
             _frameRate = _frameCount;
             _frameCount = 0;
-            _frameLastFPS = Game::getGameTime();
+            _frameLastFPS = getGameTime();
         }
     }
     else
@@ -303,7 +305,7 @@ void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactI
 {
 }
 
-void Game::schedule(long timeOffset, TimeListener* timeListener, void* cookie)
+void Game::schedule(float timeOffset, TimeListener* timeListener, void* cookie)
 {
     GP_ASSERT(_timeEvents);
     TimeEvent timeEvent(getGameTime() + timeOffset, timeListener, cookie);
@@ -322,9 +324,9 @@ void Game::updateOnce()
     GP_ASSERT(_physicsController);
 
     // Update Time.
-    static long lastFrameTime = Game::getGameTime();
-    long frameTime = Game::getGameTime();
-    long elapsedTime = (frameTime - lastFrameTime);
+    static double lastFrameTime = getGameTime();
+    double frameTime = getGameTime();
+    float elapsedTime = (frameTime - lastFrameTime);
     lastFrameTime = frameTime;
 
     // Update the internal controllers.
@@ -358,7 +360,7 @@ void Game::loadConfig()
     }
 }
 
-void Game::fireTimeEvents(long frameTime)
+void Game::fireTimeEvents(double frameTime)
 {
     while (_timeEvents->size() > 0)
     {
@@ -373,7 +375,7 @@ void Game::fireTimeEvents(long frameTime)
     }
 }
 
-Game::TimeEvent::TimeEvent(long time, TimeListener* timeListener, void* cookie)
+Game::TimeEvent::TimeEvent(double time, TimeListener* timeListener, void* cookie)
             : time(time), listener(timeListener), cookie(cookie)
 {
 }

+ 11 - 11
gameplay/src/Game.h

@@ -79,7 +79,7 @@ public:
      * 
      * @return The total absolute running time (in milliseconds).
      */
-    static long getAbsoluteTime();
+    static double getAbsoluteTime();
 
     /**
      * Gets the total game time (in milliseconds). This is the total accumulated game time (unpaused).
@@ -89,7 +89,7 @@ public:
      * 
      * @return The total game time (in milliseconds).
      */
-    static long getGameTime();
+    static double getGameTime();
 
     /**
      * Gets the game state.
@@ -297,7 +297,7 @@ public:
      * @param timeListener The TimeListener that will receive the event.
      * @param cookie The cookie data that the time event will contain.
      */
-    void schedule(long timeOffset, TimeListener* timeListener, void* cookie = 0);
+    void schedule(float timeOffset, TimeListener* timeListener, void* cookie = 0);
 
 protected:
 
@@ -324,7 +324,7 @@ protected:
      *
      * @param elapsedTime The elapsed game time.
      */
-    virtual void update(long elapsedTime) = 0;
+    virtual void update(float elapsedTime) = 0;
 
     /**
      * Render callback for handling rendering routines.
@@ -334,7 +334,7 @@ protected:
      *
      * @param elapsedTime The elapsed game time.
      */
-    virtual void render(long elapsedTime) = 0;
+    virtual void render(float elapsedTime) = 0;
 
     /**
      * Renders a single frame once and then swaps it to the display.
@@ -363,7 +363,7 @@ private:
     {
     public:
 
-        TimeEvent(long time, TimeListener* timeListener, void* cookie);
+        TimeEvent(double time, TimeListener* timeListener, void* cookie);
         // The comparator is used to determine the order of time events in the priority queue.
         bool operator<(const TimeEvent& v) const;
         
@@ -371,7 +371,7 @@ private:
          * The game time.
          * @see Game::getGameTime()
          */
-        long time;
+        double time;
         TimeListener* listener;
         void* cookie;
     };
@@ -398,7 +398,7 @@ private:
      * 
      * @param frameTime The current game frame time. Used to determine which time events need to be fired.
      */
-    void fireTimeEvents(long frameTime);
+    void fireTimeEvents(double frameTime);
 
     /**
      * Loads the game configuration.
@@ -407,9 +407,9 @@ private:
 
     bool _initialized;                          // If game has initialized yet.
     State _state;                               // The game state.
-    static long _pausedTimeLast;                // The last time paused.
-    static long _pausedTimeTotal;               // The total time paused.
-    long _frameLastFPS;                         // The last time the frame count was updated.
+    static double _pausedTimeLast;              // The last time paused.
+    static double _pausedTimeTotal;             // The total time paused.
+    double _frameLastFPS;                       // The last time the frame count was updated.
     unsigned int _frameCount;                   // The current frame count.
     unsigned int _frameRate;                    // The current frame rate.
     unsigned int _width;                        // The game's display width.

+ 6 - 0
gameplay/src/Joystick.cpp

@@ -165,6 +165,12 @@ bool Joystick::touchEvent(Touch::TouchEvent touchEvent, int x, int y, unsigned i
 void Joystick::update(const Control* container, const Vector2& offset)
 {
     Control::update(container, offset);
+
+    _clearBounds.x -= _radius;
+    _clearBounds.y -= _radius;
+    float radiusx2 = _radius + _radius;
+    _clearBounds.width += radiusx2;
+    _clearBounds.height += radiusx2;
 }
 
 void Joystick::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)

+ 1 - 1
gameplay/src/Node.cpp

@@ -21,7 +21,7 @@ namespace gameplay
 {
 
 Node::Node(const char* id)
-    : _scene(NULL), _firstChild(NULL), _nextSibling(NULL), _prevSibling(NULL), _parent(NULL), _childCount(NULL),
+    : _scene(NULL), _firstChild(NULL), _nextSibling(NULL), _prevSibling(NULL), _parent(NULL), _childCount(0),
     _nodeFlags(NODE_FLAG_VISIBLE), _camera(NULL), _light(NULL), _model(NULL), _form(NULL), _audioSource(NULL), _particleEmitter(NULL),
     _collisionObject(NULL), _dirtyBits(NODE_DIRTY_ALL), _notifyHierarchyChanged(true), _userData(NULL)
 {

+ 6 - 8
gameplay/src/ParticleEmitter.cpp

@@ -28,7 +28,7 @@ ParticleEmitter::ParticleEmitter(SpriteBatch* batch, unsigned int particleCountM
     _spriteBatch(batch), _spriteTextureBlending(BLEND_TRANSPARENT),  _spriteTextureWidth(0), _spriteTextureHeight(0), _spriteTextureWidthRatio(0), _spriteTextureHeightRatio(0), _spriteTextureCoords(NULL),
     _spriteAnimated(false),  _spriteLooped(false), _spriteFrameCount(1), _spriteFrameRandomOffset(0),_spriteFrameDuration(0L), _spriteFrameDurationSecs(0.0f), _spritePercentPerFrame(0.0f),
     _node(NULL), _orbitPosition(false), _orbitVelocity(false), _orbitAcceleration(false),
-    _timePerEmission(PARTICLE_EMISSION_RATE_TIME_INTERVAL), _timeLast(0L), _timeRunning(0L)
+    _timePerEmission(PARTICLE_EMISSION_RATE_TIME_INTERVAL), _timeRunning(0)
 {
     GP_ASSERT(particleCountMax);
     _particles = new Particle[particleCountMax];
@@ -228,7 +228,6 @@ void ParticleEmitter::setEmissionRate(unsigned int rate)
 void ParticleEmitter::start()
 {
     _started = true;
-    _timeLast = Game::getGameTime();
 }
 
 void ParticleEmitter::stop()
@@ -786,8 +785,7 @@ ParticleEmitter::TextureBlending ParticleEmitter::getTextureBlendingFromString(c
     }
 }
 
-
-void ParticleEmitter::update(long elapsedTime)
+void ParticleEmitter::update(float elapsedTime)
 {
     if (!isActive())
     {
@@ -795,7 +793,7 @@ void ParticleEmitter::update(long elapsedTime)
     }
 
     // Calculate the time passed since last update.
-    float elapsedSecs = (float)elapsedTime * 0.001f;
+    float elapsedSecs = elapsedTime * 0.001f;
 
     if (_started && _emissionRate)
     {
@@ -804,13 +802,13 @@ void ParticleEmitter::update(long elapsedTime)
 
         // How many particles should we emit this frame?
         GP_ASSERT(_timePerEmission);
-        unsigned int emitCount = _timeRunning / _timePerEmission;
-            
+        unsigned int emitCount = (unsigned int)(_timeRunning / _timePerEmission);
+
         if (emitCount)
         {
             if ((int)_timePerEmission > 0)
             {
-                _timeRunning %= (int)_timePerEmission;
+                _timeRunning = fmodl(_timeRunning, _timePerEmission);
             }
 
             emit(emitCount);

+ 2 - 3
gameplay/src/ParticleEmitter.h

@@ -608,7 +608,7 @@ public:
      *
      * @param elapsedTime The amount of time that has passed since the last call to update(), in milliseconds.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
 
     /**
      * Draws the particles currently being emitted.
@@ -733,8 +733,7 @@ private:
     bool _orbitVelocity;
     bool _orbitAcceleration;
     float _timePerEmission;
-    long _timeLast;
-    long _timeRunning;
+    double _timeRunning;
 };
 
 }

+ 2 - 2
gameplay/src/PhysicsCharacter.cpp

@@ -285,7 +285,7 @@ void PhysicsCharacter::updateCurrentVelocity()
         temp.normalize();
         temp *= -_forwardVelocity;
         _normalizedVelocity += btVector3(temp.x, temp.y, temp.z);
-        velocity2 = std::max(std::abs(velocity2), std::abs(_forwardVelocity*_forwardVelocity));
+        velocity2 = std::max(std::fabs(velocity2), std::fabs(_forwardVelocity*_forwardVelocity));
     }
 
     // Add right velocity contribution.
@@ -295,7 +295,7 @@ void PhysicsCharacter::updateCurrentVelocity()
         temp.normalize();
         temp *= _rightVelocity;
         _normalizedVelocity += btVector3(temp.x, temp.y, temp.z);
-        velocity2 = std::max(std::abs(velocity2), std::abs(_rightVelocity*_rightVelocity));
+        velocity2 = std::max(std::fabs(velocity2), std::fabs(_rightVelocity*_rightVelocity));
     }
 
     // Compute final combined movement vectors

+ 65 - 5
gameplay/src/PhysicsCollisionObject.cpp

@@ -2,6 +2,7 @@
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
 #include "Game.h"
+#include "Node.h"
 
 namespace gameplay
 {
@@ -55,11 +56,6 @@ PhysicsCollisionShape* PhysicsCollisionObject::getCollisionShape() const
     return _collisionShape;
 }
 
-PhysicsMotionState* PhysicsCollisionObject::getMotionState() const
-{
-    return _motionState;
-}
-
 bool PhysicsCollisionObject::isKinematic() const
 {
     switch (getType())
@@ -151,4 +147,68 @@ bool PhysicsCollisionObject::CollisionPair::operator < (const CollisionPair& col
     return false;
 }
 
+PhysicsCollisionObject::PhysicsMotionState::PhysicsMotionState(Node* node, const Vector3* centerOfMassOffset) : _node(node),
+    _centerOfMassOffset(btTransform::getIdentity())
+{
+    if (centerOfMassOffset)
+    {
+        // Store the center of mass offset.
+        _centerOfMassOffset.setOrigin(BV(*centerOfMassOffset));
+    }
+
+    updateTransformFromNode();
+}
+
+PhysicsCollisionObject::PhysicsMotionState::~PhysicsMotionState()
+{
+}
+
+void PhysicsCollisionObject::PhysicsMotionState::getWorldTransform(btTransform &transform) const
+{
+    GP_ASSERT(_node);
+    if (_node->getCollisionObject() && _node->getCollisionObject()->isKinematic())
+        updateTransformFromNode();
+
+    transform = _centerOfMassOffset.inverse() * _worldTransform;
+}
+
+void PhysicsCollisionObject::PhysicsMotionState::setWorldTransform(const btTransform &transform)
+{
+    GP_ASSERT(_node);
+
+    _worldTransform = transform * _centerOfMassOffset;
+        
+    const btQuaternion& rot = _worldTransform.getRotation();
+    const btVector3& pos = _worldTransform.getOrigin();
+
+    _node->setRotation(rot.x(), rot.y(), rot.z(), rot.w());
+    _node->setTranslation(pos.x(), pos.y(), pos.z());
+}
+
+void PhysicsCollisionObject::PhysicsMotionState::updateTransformFromNode() const
+{
+    GP_ASSERT(_node);
+
+    // Store the initial world transform (minus the scale) for use by Bullet later on.
+    Quaternion rotation;
+    const Matrix& m = _node->getWorldMatrix();
+    m.getRotation(&rotation);
+
+    if (!_centerOfMassOffset.getOrigin().isZero())
+    {
+        // When there is a center of mass offset, we modify the initial world transformation
+        // so that when physics is initially applied, the object is in the correct location.
+        btTransform offset = btTransform(BQ(rotation), btVector3(0.0f, 0.0f, 0.0f)) * _centerOfMassOffset.inverse();
+
+        btVector3 origin(m.m[12] + _centerOfMassOffset.getOrigin().getX() + offset.getOrigin().getX(), 
+                         m.m[13] + _centerOfMassOffset.getOrigin().getY() + offset.getOrigin().getY(), 
+                         m.m[14] + _centerOfMassOffset.getOrigin().getZ() + offset.getOrigin().getZ());
+        _worldTransform = btTransform(BQ(rotation), origin);
+    }
+    else
+    {
+        _worldTransform = btTransform(BQ(rotation), btVector3(m.m[12], m.m[13], m.m[14]));
+    }
+}
+
 }

+ 46 - 8
gameplay/src/PhysicsCollisionObject.h

@@ -3,7 +3,6 @@
 
 #include "Vector3.h"
 #include "PhysicsCollisionShape.h"
-#include "PhysicsMotionState.h"
 
 namespace gameplay
 {
@@ -211,6 +210,52 @@ public:
 
 protected:
 
+    /**
+     * Interface between GamePlay and Bullet to keep object transforms synchronized properly.
+     * 
+     * @see btMotionState
+     */
+    class PhysicsMotionState : public btMotionState
+    {
+        friend class PhysicsConstraint;
+
+    public:
+
+        /**
+         * Creates a physics motion state for a rigid body.
+         * 
+         * @param node The node that owns the rigid body that the motion state is being created for.
+         * @param centerOfMassOffset The translation offset to the center of mass of the rigid body.
+         */
+        PhysicsMotionState(Node* node, const Vector3* centerOfMassOffset = NULL);
+
+        /**
+         * Destructor.
+         */
+        virtual ~PhysicsMotionState();
+
+        /**
+         * @see btMotionState#getWorldTransform
+         */
+        virtual void getWorldTransform(btTransform &transform) const;
+
+        /**
+         * @see btMotionState#setWorldTransform
+         */
+        virtual void setWorldTransform(const btTransform &transform);
+
+        /**
+         * Updates the motion state's world transform from the GamePlay Node object's world transform.
+         */
+        void updateTransformFromNode() const;
+
+    private:
+
+        Node* _node;
+        btTransform _centerOfMassOffset;
+        mutable btTransform _worldTransform;
+    };
+
     /**
      * Constructor.
      */
@@ -223,13 +268,6 @@ protected:
      */
     virtual btCollisionObject* getCollisionObject() const = 0;
 
-    /**
-     * Returns the physics motion state.
-     *
-     * @return The motion state object.
-     */
-    PhysicsMotionState* getMotionState() const;
-
     /**
      * Pointer to Node contained by this collision object.
      */ 

+ 2 - 3
gameplay/src/PhysicsConstraint.cpp

@@ -2,7 +2,6 @@
 #include "PhysicsConstraint.h"
 #include "Game.h"
 #include "Node.h"
-#include "PhysicsMotionState.h"
 #include "PhysicsRigidBody.h"
 
 namespace gameplay
@@ -166,8 +165,8 @@ Vector3 PhysicsConstraint::getWorldCenterOfMass(const Model* model)
 
 Vector3 PhysicsConstraint::offsetByCenterOfMass(const Node* node, const Vector3& v)
 {
-    GP_ASSERT(node && node->getCollisionObject() && node->getCollisionObject()->getMotionState());
-    btVector3 centerOfMassOffset = (node->getCollisionObject()->getMotionState())->_centerOfMassOffset.getOrigin();
+    GP_ASSERT(node && node->getCollisionObject() && node->getCollisionObject()->_motionState);
+    btVector3 centerOfMassOffset = node->getCollisionObject()->_motionState->_centerOfMassOffset.getOrigin();
     return Vector3(v.x + centerOfMassOffset.x(), v.y + centerOfMassOffset.y(), v.z + centerOfMassOffset.z());
 }
 

+ 19 - 18
gameplay/src/PhysicsController.cpp

@@ -2,7 +2,6 @@
 #include "PhysicsController.h"
 #include "PhysicsRigidBody.h"
 #include "PhysicsCharacter.h"
-#include "PhysicsMotionState.h"
 #include "Game.h"
 #include "MeshPart.h"
 #include "Bundle.h"
@@ -24,13 +23,15 @@ PhysicsController::PhysicsController()
   : _collisionConfiguration(NULL), _dispatcher(NULL),
     _overlappingPairCache(NULL), _solver(NULL), _world(NULL), _ghostPairCallback(NULL),
     _debugDrawer(NULL), _status(PhysicsController::Listener::DEACTIVATED), _listeners(NULL),
-    _gravity(btScalar(0.0), btScalar(-9.8), btScalar(0.0))
+    _gravity(btScalar(0.0), btScalar(-9.8), btScalar(0.0)), _collisionCallback(NULL)
 {
     // Default gravity is 9.8 along the negative Y axis.
+    _collisionCallback = new CollisionCallback(this);
 }
 
 PhysicsController::~PhysicsController()
 {
+    SAFE_DELETE(_collisionCallback);
     SAFE_DELETE(_ghostPairCallback);
     SAFE_DELETE(_debugDrawer);
     SAFE_DELETE(_listeners);
@@ -265,14 +266,14 @@ bool PhysicsController::sweepTest(PhysicsCollisionObject* object, const Vector3&
     return false;
 }
 
-btScalar PhysicsController::addSingleResult(btManifoldPoint& cp, const btCollisionObject* a, int partIdA, int indexA, 
+btScalar PhysicsController::CollisionCallback::addSingleResult(btManifoldPoint& cp, const btCollisionObject* a, int partIdA, int indexA, 
     const btCollisionObject* b, int partIdB, int indexB)
 {
-    GP_ASSERT(Game::getInstance()->getPhysicsController());
+    GP_ASSERT(_pc);
 
     // Get pointers to the PhysicsCollisionObject objects.
-    PhysicsCollisionObject* objectA = Game::getInstance()->getPhysicsController()->getCollisionObject(a);
-    PhysicsCollisionObject* objectB = Game::getInstance()->getPhysicsController()->getCollisionObject(b);
+    PhysicsCollisionObject* objectA = _pc->getCollisionObject(a);
+    PhysicsCollisionObject* objectB = _pc->getCollisionObject(b);
 
     // If the given collision object pair has collided in the past, then
     // we notify the listeners only if the pair was not colliding
@@ -281,20 +282,20 @@ btScalar PhysicsController::addSingleResult(btManifoldPoint& cp, const btCollisi
     PhysicsCollisionObject::CollisionPair pair(objectA, objectB);
 
     CollisionInfo* collisionInfo;
-    if (_collisionStatus.count(pair) > 0)
+    if (_pc->_collisionStatus.count(pair) > 0)
     {
-        collisionInfo = &_collisionStatus[pair];
+        collisionInfo = &_pc->_collisionStatus[pair];
     }
     else
     {
         // Add a new collision pair for these objects.
-        collisionInfo = &_collisionStatus[pair];
+        collisionInfo = &_pc->_collisionStatus[pair];
 
         // Add the appropriate listeners.
         PhysicsCollisionObject::CollisionPair p1(pair.objectA, NULL);
-        if (_collisionStatus.count(p1) > 0)
+        if (_pc->_collisionStatus.count(p1) > 0)
         {
-            const CollisionInfo& ci = _collisionStatus[p1];
+            const CollisionInfo& ci = _pc->_collisionStatus[p1];
             std::vector<PhysicsCollisionObject::CollisionListener*>::const_iterator iter = ci._listeners.begin();
             for (; iter != ci._listeners.end(); iter++)
             {
@@ -303,9 +304,9 @@ btScalar PhysicsController::addSingleResult(btManifoldPoint& cp, const btCollisi
             }
         }
         PhysicsCollisionObject::CollisionPair p2(pair.objectB, NULL);
-        if (_collisionStatus.count(p2) > 0)
+        if (_pc->_collisionStatus.count(p2) > 0)
         {
-            const CollisionInfo& ci = _collisionStatus[p2];
+            const CollisionInfo& ci = _pc->_collisionStatus[p2];
             std::vector<PhysicsCollisionObject::CollisionListener*>::const_iterator iter = ci._listeners.begin();
             for (; iter != ci._listeners.end(); iter++)
             {
@@ -381,7 +382,7 @@ void PhysicsController::resume()
     // Unused
 }
 
-void PhysicsController::update(long elapsedTime)
+void PhysicsController::update(float elapsedTime)
 {
     GP_ASSERT(_world);
 
@@ -390,7 +391,7 @@ void PhysicsController::update(long elapsedTime)
     //
     // Note that stepSimulation takes elapsed time in seconds
     // so we divide by 1000 to convert from milliseconds.
-    _world->stepSimulation((float)elapsedTime * 0.001, 10);
+    _world->stepSimulation(elapsedTime * 0.001f, 10);
 
     // If we have status listeners, then check if our status has changed.
     if (_listeners)
@@ -471,9 +472,9 @@ void PhysicsController::update(long elapsedTime)
         if ((iter->second._status & REGISTERED) != 0 && (iter->second._status & REMOVE) == 0)
         {
             if (iter->first.objectB)
-                _world->contactPairTest(iter->first.objectA->getCollisionObject(), iter->first.objectB->getCollisionObject(), *this);
+                _world->contactPairTest(iter->first.objectA->getCollisionObject(), iter->first.objectB->getCollisionObject(), *_collisionCallback);
             else
-                _world->contactTest(iter->first.objectA->getCollisionObject(), *this);
+                _world->contactTest(iter->first.objectA->getCollisionObject(), *_collisionCallback);
         }
     }
 
@@ -694,7 +695,7 @@ PhysicsCollisionShape* PhysicsController::createShape(Node* node, const PhysicsC
                 // Automatically compute bounding box from mesh's bounding box.
                 BoundingBox box;
                 getBoundingBox(node, &box);
-                collisionShape = createBox(Vector3(std::abs(box.max.x - box.min.x), std::abs(box.max.y - box.min.y), std::abs(box.max.z - box.min.z)), scale);
+                collisionShape = createBox(Vector3(std::fabs(box.max.x - box.min.x), std::fabs(box.max.y - box.min.y), std::fabs(box.max.z - box.min.z)), scale);
 
                 computeCenterOfMass(box.getCenter(), scale, centerOfMassOffset);
             }

+ 23 - 6
gameplay/src/PhysicsController.h

@@ -16,7 +16,7 @@ namespace gameplay
 /**
  * Defines a class for controlling game physics.
  */
-class PhysicsController : public btCollisionWorld::ContactResultCallback
+class PhysicsController
 {
     friend class Game;
     friend class PhysicsConstraint;
@@ -264,14 +264,30 @@ public:
      */
     bool sweepTest(PhysicsCollisionObject* object, const Vector3& endPosition, PhysicsController::HitResult* result = NULL);
 
-protected:
+private:
 
     /**
-     * Internal function used for Bullet integration (do not use or override).
+     * Internal class used to integrate with Bullet collision callbacks.
      */
-    btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* a, int partIdA, int indexA, const btCollisionObject* b, int partIdB, int indexB);    
+    class CollisionCallback : public btCollisionWorld::ContactResultCallback
+    {
+    public:
+        /**
+         * Constructor.
+         * 
+         * @param pc The physics controller that owns the callback.
+         */
+        CollisionCallback(PhysicsController* pc) : _pc(pc) {}
 
-private:
+    protected:
+        /**
+            * Internal function used for Bullet integration (do not use or override).
+            */
+        btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* a, int partIdA, int indexA, const btCollisionObject* b, int partIdB, int indexB);    
+
+    private:
+        PhysicsController* _pc;
+    };
 
     // Internal constants for the collision status cache.
     static const int DIRTY;
@@ -321,7 +337,7 @@ private:
     /**
      * Controller update.
      */
-    void update(long elapsedTime);
+    void update(float elapsedTime);
 
     // Adds the given collision listener for the two given collision objects.
     void addCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB);
@@ -459,6 +475,7 @@ private:
     std::vector<Listener*>* _listeners;
     Vector3 _gravity;
     std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo> _collisionStatus;
+    CollisionCallback* _collisionCallback;
 
 };
 

+ 0 - 1
gameplay/src/PhysicsGenericConstraint.cpp

@@ -1,7 +1,6 @@
 #include "Base.h"
 #include "PhysicsGenericConstraint.h"
 #include "Node.h"
-#include "PhysicsMotionState.h"
 #include "PhysicsRigidBody.h"
 
 namespace gameplay

+ 0 - 72
gameplay/src/PhysicsMotionState.cpp

@@ -1,72 +0,0 @@
-#include "Base.h"
-#include "PhysicsMotionState.h"
-#include "Node.h"
-
-namespace gameplay
-{
-
-PhysicsMotionState::PhysicsMotionState(Node* node, const Vector3* centerOfMassOffset) : _node(node),
-    _centerOfMassOffset(btTransform::getIdentity())
-{
-    if (centerOfMassOffset)
-    {
-        // Store the center of mass offset.
-        _centerOfMassOffset.setOrigin(BV(*centerOfMassOffset));
-    }
-
-    updateTransformFromNode();
-}
-
-PhysicsMotionState::~PhysicsMotionState()
-{
-}
-
-void PhysicsMotionState::getWorldTransform(btTransform &transform) const
-{
-    GP_ASSERT(_node);
-    if (_node->getCollisionObject() && _node->getCollisionObject()->isKinematic())
-        updateTransformFromNode();
-
-    transform = _centerOfMassOffset.inverse() * _worldTransform;
-}
-
-void PhysicsMotionState::setWorldTransform(const btTransform &transform)
-{
-    GP_ASSERT(_node);
-
-    _worldTransform = transform * _centerOfMassOffset;
-        
-    const btQuaternion& rot = _worldTransform.getRotation();
-    const btVector3& pos = _worldTransform.getOrigin();
-
-    _node->setRotation(rot.x(), rot.y(), rot.z(), rot.w());
-    _node->setTranslation(pos.x(), pos.y(), pos.z());
-}
-
-void PhysicsMotionState::updateTransformFromNode() const
-{
-    GP_ASSERT(_node);
-
-    // Store the initial world transform (minus the scale) for use by Bullet later on.
-    Quaternion rotation;
-    const Matrix& m = _node->getWorldMatrix();
-    m.getRotation(&rotation);
-
-    if (!_centerOfMassOffset.getOrigin().isZero())
-    {
-        // When there is a center of mass offset, we modify the initial world transformation
-        // so that when physics is initially applied, the object is in the correct location.
-        btTransform offset = btTransform(BQ(rotation), btVector3(0.0f, 0.0f, 0.0f)) * _centerOfMassOffset.inverse();
-
-        btVector3 origin(m.m[12] + _centerOfMassOffset.getOrigin().getX() + offset.getOrigin().getX(), 
-                         m.m[13] + _centerOfMassOffset.getOrigin().getY() + offset.getOrigin().getY(), 
-                         m.m[14] + _centerOfMassOffset.getOrigin().getZ() + offset.getOrigin().getZ());
-        _worldTransform = btTransform(BQ(rotation), origin);
-    }
-    else
-    {
-        _worldTransform = btTransform(BQ(rotation), btVector3(m.m[12], m.m[13], m.m[14]));
-    }
-}
-
-}

+ 0 - 61
gameplay/src/PhysicsMotionState.h

@@ -1,61 +0,0 @@
-#ifndef PHYSICSMOTIONSTATE_H_
-#define PHYSICSMOTIONSTATE_H_
-
-#include "Vector3.h"
-
-namespace gameplay
-{
-
-class Node;
-
-/**
- * Interface between GamePlay and Bullet to keep object transforms synchronized properly.
- * 
- * @see btMotionState
- */
-class PhysicsMotionState : public btMotionState
-{
-    friend class PhysicsCollisionObject;
-    friend class PhysicsRigidBody;
-    friend class PhysicsGhostObject;
-    friend class PhysicsCharacter;
-    friend class PhysicsConstraint;
-
-protected:
-
-    /**
-     * Creates a physics motion state for a rigid body.
-     * 
-     * @param node The node that owns the rigid body that the motion state is being created for.
-     * @param centerOfMassOffset The translation offset to the center of mass of the rigid body.
-     */
-    PhysicsMotionState(Node* node, const Vector3* centerOfMassOffset = NULL);
-
-    /**
-     * Destructor.
-     */
-    virtual ~PhysicsMotionState();
-
-    /**
-     * @see btMotionState#getWorldTransform
-     */
-    virtual void getWorldTransform(btTransform &transform) const;
-
-    /**
-     * @see btMotionState#setWorldTransform
-     */
-    virtual void setWorldTransform(const btTransform &transform);
-
-private:
-
-    // Updates the motion state's world transform from the GamePlay Node object's world transform.
-    void updateTransformFromNode() const;
-
-    Node* _node;
-    btTransform _centerOfMassOffset;
-    mutable btTransform _worldTransform;
-};
-
-}
-
-#endif

+ 0 - 1
gameplay/src/PhysicsRigidBody.cpp

@@ -1,6 +1,5 @@
 #include "Base.h"
 #include "PhysicsRigidBody.h"
-#include "PhysicsMotionState.h"
 #include "PhysicsController.h"
 #include "Game.h"
 #include "Image.h"

+ 2 - 2
gameplay/src/Platform.h

@@ -67,14 +67,14 @@ public:
      *
      * @return The absolute platform time. (in milliseconds)
      */
-    static long getAbsoluteTime();
+    static double getAbsoluteTime();
 
     /**
      * Sets the absolute platform time since the start of the message pump.
      *
      * @param time The time to set (in milliseconds).
      */
-    static void setAbsoluteTime(long time);
+    static void setAbsoluteTime(double time);
 
     /**
      * Gets whether vertical sync is enabled for the game display.

+ 7 - 7
gameplay/src/PlatformAndroid.cpp

@@ -25,8 +25,8 @@ static EGLConfig __eglConfig = 0;
 static int __width;
 static int __height;
 static struct timespec __timespec;
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static ASensorManager* __sensorManager;
 static ASensorEventQueue* __sensorEventQueue;
@@ -47,10 +47,10 @@ PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
 namespace gameplay
 {
 
-static long timespec2millis(struct timespec *a)
+static double timespec2millis(struct timespec *a)
 {
     GP_ASSERT(a);
-    return a->tv_sec*1000 + a->tv_nsec/1000000;
+    return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
 }
 
 extern void printError(const char* format, ...)
@@ -858,16 +858,16 @@ unsigned int Platform::getDisplayHeight()
     return __height;
 }
     
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     clock_gettime(CLOCK_REALTIME, &__timespec);
-    long now = timespec2millis(&__timespec);
+    double now = timespec2millis(&__timespec);
     __timeAbsolute = now - __timeStart;
 
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 8 - 8
gameplay/src/PlatformMacOSX.mm

@@ -21,8 +21,8 @@ static int __height = 720;
 static float ACCELEROMETER_FACTOR_X = 90.0f / __width;
 static float ACCELEROMETER_FACTOR_Y = 90.0f / __height;
 
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static float __pitch;
 static float __roll;
@@ -37,17 +37,17 @@ static char* __title = NULL;
 static bool __fullscreen = false;
 
 
-long getMachTimeInMilliseconds()
+double getMachTimeInMilliseconds()
 {
-    static const int64_t kOneMillion = 1000 * 1000;
+    static const double kOneMillion = 1000 * 1000;
     static mach_timebase_info_data_t s_timebase_info;
     
     if (s_timebase_info.denom == 0) 
         (void) mach_timebase_info(&s_timebase_info);
     
     // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
-    GP_ASSERT(kOneMillion * s_timebase_info.denom);
-    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
+    GP_ASSERT(s_timebase_info.denom);
+    return ((double)mach_absolute_time() * (double)s_timebase_info.numer) / (kOneMillion * (double)s_timebase_info.denom);
 }
 
 
@@ -717,13 +717,13 @@ unsigned int Platform::getDisplayHeight()
     return __height;
 }
 
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     __timeAbsolute = getMachTimeInMilliseconds();
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 7 - 7
gameplay/src/PlatformQNX.cpp

@@ -22,8 +22,8 @@
 using namespace std;
 
 struct timespec __timespec;
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static screen_context_t __screenContext;
 static screen_window_t __screenWindow;
@@ -751,10 +751,10 @@ error:
 /**
  * Convert the timespec into milliseconds.
  */
-long timespec2millis(struct timespec *a)
+double timespec2millis(struct timespec *a)
 {
     GP_ASSERT(a);
-    return a->tv_sec*1000 + a->tv_nsec/1000000;
+    return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
 }
 
 /**
@@ -1044,16 +1044,16 @@ unsigned int Platform::getDisplayHeight()
     return __screenWindowSize[1];
 }
 
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     clock_gettime(CLOCK_REALTIME, &__timespec);
-    long now = timespec2millis(&__timespec);
+    double now = timespec2millis(&__timespec);
     __timeAbsolute = now - __timeStart;
 
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 11 - 11
gameplay/src/PlatformWin32.cpp

@@ -14,9 +14,9 @@ using gameplay::printError;
 static int __width = 1280;
 static int __height = 720;
 
-static long __timeTicksPerMillis;
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeTicksPerMillis;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static float __roll;
 static float __pitch;
@@ -276,11 +276,6 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
     switch (msg)
     {
-    case WM_PAINT:
-        gameplay::Game::getInstance()->frame();
-        SwapBuffers(__hdc);
-        return 0;
-
     case WM_CLOSE:
         DestroyWindow(__hwnd);
         return 0;
@@ -637,7 +632,7 @@ int Platform::enterMessagePump()
     // Get the initial time.
     LARGE_INTEGER tps;
     QueryPerformanceFrequency(&tps);
-    __timeTicksPerMillis = (long)(tps.QuadPart / 1000L);
+    __timeTicksPerMillis = (double)(tps.QuadPart / 1000L);
     LARGE_INTEGER queryTime;
     QueryPerformanceCounter(&queryTime);
     GP_ASSERT(__timeTicksPerMillis);
@@ -667,6 +662,11 @@ int Platform::enterMessagePump()
                 break;
             }
         }
+        else
+        {
+            _game->frame();
+            SwapBuffers(__hdc);
+        }
 
         // If we are done, then exit.
         if (_game->getState() == Game::UNINITIALIZED)
@@ -691,7 +691,7 @@ unsigned int Platform::getDisplayHeight()
     return __height;
 }
     
-long Platform::getAbsoluteTime()
+double Platform::getAbsoluteTime()
 {
     LARGE_INTEGER queryTime;
     QueryPerformanceCounter(&queryTime);
@@ -701,7 +701,7 @@ long Platform::getAbsoluteTime()
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 9 - 9
gameplay/src/PlatformiOS.mm

@@ -37,14 +37,14 @@ extern const int WINDOW_SCALE = [[UIScreen mainScreen] scale];
 static AppDelegate *__appDelegate = NULL;
 static View* __view = NULL;
 
-static long __timeStart;
-static long __timeAbsolute;
+static double __timeStart;
+static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static float __pitch;
 static float __roll;
 
 
-long getMachTimeInMilliseconds();
+double getMachTimeInMilliseconds();
 
 int getKey(unichar keyCode);
 
@@ -580,17 +580,17 @@ int getKey(unichar keyCode);
 @end
 
 
-long getMachTimeInMilliseconds()
+dobule getMachTimeInMilliseconds()
 {
-    static const int64_t kOneMillion = 1000 * 1000;
+    static const double kOneMillion = 1000 * 1000;
     static mach_timebase_info_data_t s_timebase_info;
     
     if (s_timebase_info.denom == 0) 
         (void) mach_timebase_info(&s_timebase_info);
     
     // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
-    GP_ASSERT(kOneMillion * s_timebase_info.denom);
-    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
+    GP_ASSERT(s_timebase_info.denom);
+    return ((double)mach_absolute_time() * (double)s_timebase_info.numer) / (kOneMillion * (double)s_timebase_info.denom);
 }
 
 int getKey(unichar keyCode) 
@@ -868,13 +868,13 @@ unsigned int Platform::getDisplayHeight()
     return size.height;
 }
 
-long Platform::getAbsoluteTime()
+dobule Platform::getAbsoluteTime()
 {
     __timeAbsolute = getMachTimeInMilliseconds();
     return __timeAbsolute;
 }
 
-void Platform::setAbsoluteTime(long time)
+void Platform::setAbsoluteTime(double time)
 {
     __timeAbsolute = time;
 }

+ 4 - 1
gameplay/src/SceneLoader.cpp

@@ -131,7 +131,7 @@ void SceneLoader::addSceneNodeProperty(SceneNode& sceneNode, SceneNodeProperty::
 
     // If there is a non-GPB file that needs to be loaded later, add an 
     // empty entry to the properties table to signify it.
-    if (urlStr.length() > 0 && urlStr.find(".gpb") == urlStr.npos && _properties.count(urlStr) == 0)
+    if (urlStr.length() > 0 && urlStr.find(".") != urlStr.npos && urlStr.find(".gpb") == urlStr.npos && _properties.count(urlStr) == 0)
         _properties[urlStr] = NULL;
 
     // Add the node property to the list of node properties to be resolved later.
@@ -177,6 +177,9 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
             return;
         }
 
+        // If the URL didn't specify a particular namespace within the file, pick the first one.
+        p = (strlen(p->getNamespace()) > 0) ? p : p->getNextNamespace();
+
         switch (snp._type)
         {
         case SceneNodeProperty::AUDIO:

+ 6 - 6
gameplay/src/ScreenDisplayer.h

@@ -27,7 +27,7 @@ public:
      * @param cookie See {@link Game#renderOnce}.
      * @param time The minimum amount of time to display the screen (in milliseconds).
      */
-    template <typename T> void run(T* instance, void (T::*method) (void*), void* cookie, long time);
+    template <typename T> void run(T* instance, void (T::*method) (void*), void* cookie, unsigned long time);
 
     /**
      * Destructor.
@@ -37,14 +37,14 @@ public:
 private:
 
     long _time;
-    long _startTime;
+    double _startTime;
 };
 
-inline ScreenDisplayer::ScreenDisplayer() : _time(0L), _startTime(0L)
+inline ScreenDisplayer::ScreenDisplayer() : _time(0L), _startTime(0)
 {
 }
 
-template <typename T> void ScreenDisplayer::run(T* instance, void (T::*method) (void*), void* cookie, long time)
+template <typename T> void ScreenDisplayer::run(T* instance, void (T::*method) (void*), void* cookie, unsigned long time)
 {
     _time = time;
     Game::getInstance()->renderOnce(instance, method, cookie);
@@ -53,9 +53,9 @@ template <typename T> void ScreenDisplayer::run(T* instance, void (T::*method) (
 
 inline ScreenDisplayer::~ScreenDisplayer()
 {
-    long elapsedTime = Game::getInstance()->getGameTime() - _startTime;
+    long elapsedTime = (long)(Game::getInstance()->getGameTime() - _startTime);
     if (elapsedTime < _time)
-        Platform::sleep(_time - (Game::getInstance()->getGameTime() - _startTime));
+        Platform::sleep(_time - elapsedTime);
 }
 
 /**