Browse Source

Merge pull request #1430 from Areloch/release-3.8

Release 3.8
Areloch 10 years ago
parent
commit
51fa8a3b5b
100 changed files with 1063 additions and 444 deletions
  1. 2 0
      CMakeLists.txt
  2. 1 1
      Engine/lib/collada/src/dae/daeStringTable.cpp
  3. 5 1
      Engine/lib/convexDecomp/NvRemoveTjunctions.cpp
  4. 4 4
      Engine/lib/convexDecomp/NvSimpleTypes.h
  5. 1 1
      Engine/lib/libvorbis/lib/codebook.c
  6. 17 17
      Engine/source/T3D/aiPlayer.cpp
  7. 3 1
      Engine/source/T3D/aiPlayer.h
  8. 53 0
      Engine/source/T3D/camera.cpp
  9. 3 0
      Engine/source/T3D/camera.h
  10. 1 1
      Engine/source/T3D/convexShape.cpp
  11. 38 8
      Engine/source/T3D/decal/decalManager.cpp
  12. 1 1
      Engine/source/T3D/examples/renderMeshExample.cpp
  13. 7 5
      Engine/source/T3D/fps/guiClockHud.cpp
  14. 7 5
      Engine/source/T3D/fps/guiHealthTextHud.cpp
  15. 8 6
      Engine/source/T3D/fps/guiShapeNameHud.cpp
  16. 2 2
      Engine/source/T3D/fx/fxFoliageReplicator.cpp
  17. 2 2
      Engine/source/T3D/fx/fxFoliageReplicator.h
  18. 1 1
      Engine/source/T3D/fx/precipitation.cpp
  19. 4 0
      Engine/source/T3D/gameBase/gameBase.h
  20. 25 0
      Engine/source/T3D/gameBase/gameConnection.cpp
  21. 6 2
      Engine/source/T3D/gameBase/gameConnection.h
  22. 37 12
      Engine/source/T3D/gameFunctions.cpp
  23. 0 8
      Engine/source/T3D/gameTSCtrl.cpp
  24. 0 10
      Engine/source/T3D/gameTSCtrl.h
  25. 3 2
      Engine/source/T3D/lightAnimData.cpp
  26. 5 5
      Engine/source/T3D/physics/bullet/btPlayer.cpp
  27. 53 0
      Engine/source/T3D/player.cpp
  28. 2 0
      Engine/source/T3D/player.h
  29. 1 1
      Engine/source/T3D/projectile.cpp
  30. 111 44
      Engine/source/T3D/shapeBase.cpp
  31. 11 4
      Engine/source/T3D/shapeBase.h
  32. 7 5
      Engine/source/T3D/tsStatic.cpp
  33. 9 10
      Engine/source/T3D/turret/turretShape.cpp
  34. 3 0
      Engine/source/T3D/vehicles/wheeledVehicle.cpp
  35. 0 13
      Engine/source/app/mainLoop.cpp
  36. 1 19
      Engine/source/app/version.cpp
  37. 1 1
      Engine/source/collision/boxConvex.cpp
  38. 1 1
      Engine/source/console/arrayObject.cpp
  39. 0 4
      Engine/source/console/astNodes.cpp
  40. 5 4
      Engine/source/console/compiledEval.cpp
  41. 1 1
      Engine/source/console/compiler.h
  42. 5 3
      Engine/source/console/console.h
  43. 2 5
      Engine/source/console/consoleFunctions.cpp
  44. 2 1
      Engine/source/console/consoleObject.cpp
  45. 12 15
      Engine/source/console/consoleParser.cpp
  46. 1 5
      Engine/source/console/consoleTypes.h
  47. 8 0
      Engine/source/console/dynamicTypes.h
  48. 1 1
      Engine/source/console/engineDoc.cpp
  49. 4 0
      Engine/source/console/engineFunctions.h
  50. 9 9
      Engine/source/console/enginePrimitives.h
  51. 6 6
      Engine/source/console/engineStructs.h
  52. 3 3
      Engine/source/console/engineTypeInfo.h
  53. 47 1
      Engine/source/console/engineTypes.h
  54. 1 1
      Engine/source/console/sim.h
  55. 4 4
      Engine/source/console/simObjectRef.h
  56. 1 1
      Engine/source/console/typeValidators.cpp
  57. 6 5
      Engine/source/core/module.h
  58. 1 1
      Engine/source/core/stream/bitStream.cpp
  59. 5 8
      Engine/source/core/stream/fileStream.cpp
  60. 5 3
      Engine/source/core/strings/stringFunctions.h
  61. 2 3
      Engine/source/core/util/FastDelegate.h
  62. 1 1
      Engine/source/core/util/rawData.h
  63. 5 1
      Engine/source/core/util/str.cpp
  64. 3 3
      Engine/source/core/util/str.h
  65. 1 1
      Engine/source/core/util/tUnmanagedVector.h
  66. 2 2
      Engine/source/core/util/tVector.h
  67. 1 1
      Engine/source/environment/editors/guiMeshRoadEditorCtrl.cpp
  68. 1 1
      Engine/source/environment/editors/guiMeshRoadEditorCtrl.h
  69. 1 1
      Engine/source/environment/editors/guiRiverEditorCtrl.cpp
  70. 1 1
      Engine/source/environment/editors/guiRiverEditorCtrl.h
  71. 1 1
      Engine/source/environment/editors/guiRoadEditorCtrl.cpp
  72. 1 1
      Engine/source/environment/editors/guiRoadEditorCtrl.h
  73. 5 4
      Engine/source/environment/scatterSky.cpp
  74. 6 5
      Engine/source/forest/editor/forestSelectionTool.cpp
  75. 1 1
      Engine/source/forest/forest.cpp
  76. 1 1
      Engine/source/forest/forestCollision.cpp
  77. 12 12
      Engine/source/forest/forestDataFile.cpp
  78. 2 2
      Engine/source/forest/forestWindEmitter.cpp
  79. 2 2
      Engine/source/forest/forestWindMgr.cpp
  80. 5 6
      Engine/source/gfx/D3D9/gfxD3D9Device.cpp
  81. 3 3
      Engine/source/gfx/D3D9/gfxD3D9Device.h
  82. 1 1
      Engine/source/gfx/D3D9/gfxD3D9EnumTranslate.h
  83. 3 3
      Engine/source/gfx/D3D9/pc/gfxD3D9EnumTranslate.pc.cpp
  84. 1 1
      Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.cpp
  85. 14 8
      Engine/source/gfx/gFont.cpp
  86. 5 3
      Engine/source/gfx/gfxDevice.cpp
  87. 68 8
      Engine/source/gfx/gfxDevice.h
  88. 7 6
      Engine/source/gfx/gfxTextureManager.cpp
  89. 4 4
      Engine/source/gfx/gfxVertexBuffer.h
  90. 5 4
      Engine/source/gfx/gfxVertexFormat.cpp
  91. 6 2
      Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h
  92. 266 41
      Engine/source/gui/3d/guiTSControl.cpp
  93. 27 3
      Engine/source/gui/3d/guiTSControl.h
  94. 0 3
      Engine/source/gui/containers/guiContainer.cpp
  95. 1 1
      Engine/source/gui/containers/guiContainer.h
  96. 1 1
      Engine/source/gui/containers/guiRolloutCtrl.h
  97. 28 24
      Engine/source/gui/containers/guiScrollCtrl.cpp
  98. 1 1
      Engine/source/gui/containers/guiSplitContainer.cpp
  99. 1 1
      Engine/source/gui/containers/guiSplitContainer.h
  100. 2 2
      Engine/source/gui/containers/guiTabBookCtrl.cpp

+ 2 - 0
CMakeLists.txt

@@ -2,6 +2,8 @@ cmake_minimum_required (VERSION 2.8.12)
 
 
 set(TORQUE_APP_NAME "" CACHE STRING "the app name")
 set(TORQUE_APP_NAME "" CACHE STRING "the app name")
 
 
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/temp" CACHE PATH "default install path" FORCE )
+
 if("${TORQUE_APP_NAME}" STREQUAL "")
 if("${TORQUE_APP_NAME}" STREQUAL "")
 	message(FATAL_ERROR "Please set TORQUE_APP_NAME first")
 	message(FATAL_ERROR "Please set TORQUE_APP_NAME first")
 endif()
 endif()

+ 1 - 1
Engine/lib/collada/src/dae/daeStringTable.cpp

@@ -58,7 +58,7 @@ void daeStringTable::clear()
 {
 {
 	unsigned int i;
 	unsigned int i;
 	for (i=0;i<_stringBuffersList.getCount();i++)
 	for (i=0;i<_stringBuffersList.getCount();i++)
-#if _MSC_VER <= 1200
+#if defined(_MSC_VER) && (_MSC_VER <= 1200)
 		delete [] (char *) _stringBuffersList[i];
 		delete [] (char *) _stringBuffersList[i];
 #else
 #else
 		delete [] _stringBuffersList[i];
 		delete [] _stringBuffersList[i];

+ 5 - 1
Engine/lib/convexDecomp/NvRemoveTjunctions.cpp

@@ -60,8 +60,12 @@ NvRemoveTjunctions.cpp : A code snippet to remove tjunctions from a triangle mes
 #include <vector>
 #include <vector>
 #ifdef __APPLE__
 #ifdef __APPLE__
    #include <ext/hash_map>
    #include <ext/hash_map>
-#else
+#elif LINUX
    #include <hash_map>
    #include <hash_map>
+#elif _MSC_VER < 1500
+   #include <hash_map>
+#elif _MSC_VER > 1800
+   #include <unordered_map>
 #endif
 #endif
 #include "NvUserMemAlloc.h"
 #include "NvUserMemAlloc.h"
 #include "NvHashMap.h"
 #include "NvHashMap.h"

+ 4 - 4
Engine/lib/convexDecomp/NvSimpleTypes.h

@@ -87,7 +87,7 @@ NvSimpleTypes.h : Defines basic data types for integers and floats.
 	typedef float				NxF32;
 	typedef float				NxF32;
 	typedef double				NxF64;
 	typedef double				NxF64;
 		
 		
-#elif LINUX
+#elif defined(LINUX)
 	typedef long long			NxI64;
 	typedef long long			NxI64;
 	typedef signed int			NxI32;
 	typedef signed int			NxI32;
 	typedef signed short		NxI16;
 	typedef signed short		NxI16;
@@ -101,7 +101,7 @@ NvSimpleTypes.h : Defines basic data types for integers and floats.
 	typedef float				NxF32;
 	typedef float				NxF32;
 	typedef double				NxF64;
 	typedef double				NxF64;
 
 
-#elif __APPLE__
+#elif defined(__APPLE__)
 	typedef long long			NxI64;
 	typedef long long			NxI64;
 	typedef signed int			NxI32;
 	typedef signed int			NxI32;
 	typedef signed short		NxI16;
 	typedef signed short		NxI16;
@@ -115,7 +115,7 @@ NvSimpleTypes.h : Defines basic data types for integers and floats.
 	typedef float				NxF32;
 	typedef float				NxF32;
 	typedef double				NxF64;
 	typedef double				NxF64;
 
 
-#elif __CELLOS_LV2__
+#elif defined(__CELLOS_LV2__)
 	typedef long long			NxI64;
 	typedef long long			NxI64;
 	typedef signed int			NxI32;
 	typedef signed int			NxI32;
 	typedef signed short		NxI16;
 	typedef signed short		NxI16;
@@ -129,7 +129,7 @@ NvSimpleTypes.h : Defines basic data types for integers and floats.
 	typedef float				NxF32;
 	typedef float				NxF32;
 	typedef double				NxF64;
 	typedef double				NxF64;
 
 
-#elif _XBOX
+#elif defined(_XBOX)
 	typedef __int64				NxI64;
 	typedef __int64				NxI64;
 	typedef signed int			NxI32;
 	typedef signed int			NxI32;
 	typedef signed short		NxI16;
 	typedef signed short		NxI16;

+ 1 - 1
Engine/lib/libvorbis/lib/codebook.c

@@ -450,7 +450,7 @@ long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
       }
       }
     }
     }
   }else{
   }else{
-    int i,j;
+    int i;
 
 
     for(i=0;i<n;){
     for(i=0;i<n;){
       a[i++]=0.f;
       a[i++]=0.f;

+ 17 - 17
Engine/source/T3D/aiPlayer.cpp

@@ -259,7 +259,7 @@ void AIPlayer::setAimObject( GameBase *targetObject )
  * @param targetObject The object to target
  * @param targetObject The object to target
  * @param offset       The offest from the target location to aim at
  * @param offset       The offest from the target location to aim at
  */
  */
-void AIPlayer::setAimObject( GameBase *targetObject, Point3F offset )
+void AIPlayer::setAimObject(GameBase *targetObject, const Point3F& offset)
 {
 {
    mAimObject = targetObject;
    mAimObject = targetObject;
    mTargetInLOS = false;
    mTargetInLOS = false;
@@ -725,24 +725,20 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
 
 
    // Create a new path.
    // Create a new path.
    NavPath *path = new NavPath();
    NavPath *path = new NavPath();
-   if(path)
+
+   path->mMesh = getNavMesh();
+   path->mFrom = getPosition();
+   path->mTo = pos;
+   path->mFromSet = path->mToSet = true;
+   path->mAlwaysRender = true;
+   path->mLinkTypes = mLinkTypes;
+   path->mXray = true;
+   // Paths plan automatically upon being registered.
+   if(!path->registerObject())
    {
    {
-      path->mMesh = getNavMesh();
-      path->mFrom = getPosition();
-      path->mTo = pos;
-      path->mFromSet = path->mToSet = true;
-      path->mAlwaysRender = true;
-      path->mLinkTypes = mLinkTypes;
-      path->mXray = true;
-      // Paths plan automatically upon being registered.
-      if(!path->registerObject())
-      {
-         delete path;
-         return false;
-      }
-   }
-   else
+      delete path;
       return false;
       return false;
+   }
 
 
    if(path->success())
    if(path->success())
    {
    {
@@ -831,11 +827,15 @@ void AIPlayer::followObject(SceneObject *obj, F32 radius)
    if(!isServerObject())
    if(!isServerObject())
       return;
       return;
 
 
+   if ((mFollowData.lastPos - obj->getPosition()).len()<mMoveTolerance)
+      return;
+
    if(setPathDestination(obj->getPosition()))
    if(setPathDestination(obj->getPosition()))
    {
    {
       clearCover();
       clearCover();
       mFollowData.object = obj;
       mFollowData.object = obj;
       mFollowData.radius = radius;
       mFollowData.radius = radius;
+      mFollowData.lastPos = obj->getPosition();
    }
    }
 }
 }
 
 

+ 3 - 1
Engine/source/T3D/aiPlayer.h

@@ -122,10 +122,12 @@ private:
       SimObjectPtr<SceneObject> object;
       SimObjectPtr<SceneObject> object;
       /// Distance at whcih to follow.
       /// Distance at whcih to follow.
       F32 radius;
       F32 radius;
+      Point3F lastPos;
       /// Default constructor.
       /// Default constructor.
       FollowData() : object(NULL)
       FollowData() : object(NULL)
       {
       {
          radius = 5.0f;
          radius = 5.0f;
+         lastPos = Point3F::Zero;
       }
       }
    };
    };
 
 
@@ -161,7 +163,7 @@ public:
 
 
    // Targeting and aiming sets/gets
    // Targeting and aiming sets/gets
    void setAimObject( GameBase *targetObject );
    void setAimObject( GameBase *targetObject );
-   void setAimObject( GameBase *targetObject, Point3F offset );
+   void setAimObject(GameBase *targetObject, const Point3F& offset);
    GameBase* getAimObject() const  { return mAimObject; }
    GameBase* getAimObject() const  { return mAimObject; }
    void setAimLocation( const Point3F &location );
    void setAimLocation( const Point3F &location );
    Point3F getAimLocation() const { return mAimLocation; }
    Point3F getAimLocation() const { return mAimLocation; }

+ 53 - 0
Engine/source/T3D/camera.cpp

@@ -279,6 +279,7 @@ Camera::Camera()
 
 
    mLastAbsoluteYaw = 0.0f;
    mLastAbsoluteYaw = 0.0f;
    mLastAbsolutePitch = 0.0f;
    mLastAbsolutePitch = 0.0f;
+   mLastAbsoluteRoll = 0.0f;
 
 
    // For NewtonFlyMode
    // For NewtonFlyMode
    mNewtonRotation = false;
    mNewtonRotation = false;
@@ -379,6 +380,57 @@ void Camera::getCameraTransform(F32* pos, MatrixF* mat)
    mat->mul( gCamFXMgr.getTrans() );
    mat->mul( gCamFXMgr.getTrans() );
 }
 }
 
 
+void Camera::getEyeCameraTransform(IDisplayDevice *displayDevice, U32 eyeId, MatrixF *outMat)
+{
+   // The camera doesn't support a third person mode,
+   // so we want to override the default ShapeBase behavior.
+   ShapeBase * obj = dynamic_cast<ShapeBase*>(static_cast<SimObject*>(mOrbitObject));
+   if(obj && static_cast<ShapeBaseData*>(obj->getDataBlock())->observeThroughObject)
+      obj->getEyeCameraTransform(displayDevice, eyeId, outMat);
+   else
+   {
+      Parent::getEyeCameraTransform(displayDevice, eyeId, outMat);
+   }
+}
+
+DisplayPose Camera::calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose)
+{
+   // NOTE: this is intended to be similar to updateMove
+   DisplayPose outPose;
+   outPose.orientation = EulerF(0,0,0);
+   outPose.position = inPose.position;
+
+   // Pitch
+   outPose.orientation.x = (inPose.orientation.x - mLastAbsolutePitch);
+
+   // Constrain the range of mRot.x
+   while (outPose.orientation.x  < -M_PI_F) 
+      outPose.orientation.x += M_2PI_F;
+   while (outPose.orientation.x  > M_PI_F) 
+      outPose.orientation.x -= M_2PI_F;
+
+   // Yaw
+   outPose.orientation.z = (inPose.orientation.z - mLastAbsoluteYaw);
+
+   // Constrain the range of mRot.z
+   while (outPose.orientation.z < -M_PI_F) 
+      outPose.orientation.z += M_2PI_F;
+   while (outPose.orientation.z > M_PI_F) 
+      outPose.orientation.z -= M_2PI_F;
+
+   // Bank
+   if (mDataBlock->cameraCanBank)
+   {
+      outPose.orientation.y = (inPose.orientation.y - mLastAbsoluteRoll);
+   }
+
+   // Constrain the range of mRot.y
+   while (outPose.orientation.y > M_PI_F) 
+      outPose.orientation.y -= M_2PI_F;
+
+   return outPose;
+}
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 
 
 F32 Camera::getCameraFov()
 F32 Camera::getCameraFov()
@@ -547,6 +599,7 @@ void Camera::processTick(const Move* move)
 
 
                mLastAbsoluteYaw = emove->rotZ[emoveIndex];
                mLastAbsoluteYaw = emove->rotZ[emoveIndex];
                mLastAbsolutePitch = emove->rotX[emoveIndex];
                mLastAbsolutePitch = emove->rotX[emoveIndex];
+               mLastAbsoluteRoll = emove->rotY[emoveIndex];
 
 
                // Bank
                // Bank
                mRot.y = emove->rotY[emoveIndex];
                mRot.y = emove->rotY[emoveIndex];

+ 3 - 0
Engine/source/T3D/camera.h

@@ -113,6 +113,7 @@ class Camera: public ShapeBase
 
 
       F32 mLastAbsoluteYaw;            ///< Stores that last absolute yaw value as passed in by ExtendedMove
       F32 mLastAbsoluteYaw;            ///< Stores that last absolute yaw value as passed in by ExtendedMove
       F32 mLastAbsolutePitch;          ///< Stores that last absolute pitch value as passed in by ExtendedMove
       F32 mLastAbsolutePitch;          ///< Stores that last absolute pitch value as passed in by ExtendedMove
+      F32 mLastAbsoluteRoll;           ///< Stores that last absolute roll value as passed in by ExtendedMove
 
 
       /// @name NewtonFlyMode
       /// @name NewtonFlyMode
       /// @{
       /// @{
@@ -235,6 +236,8 @@ class Camera: public ShapeBase
       virtual void processTick( const Move* move );
       virtual void processTick( const Move* move );
       virtual void interpolateTick( F32 delta);
       virtual void interpolateTick( F32 delta);
       virtual void getCameraTransform( F32* pos,MatrixF* mat );
       virtual void getCameraTransform( F32* pos,MatrixF* mat );
+      virtual void getEyeCameraTransform( IDisplayDevice *display, U32 eyeId, MatrixF *outMat );
+      virtual DisplayPose calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose);
 
 
       virtual void writePacketData( GameConnection* conn, BitStream* stream );
       virtual void writePacketData( GameConnection* conn, BitStream* stream );
       virtual void readPacketData( GameConnection* conn, BitStream* stream );
       virtual void readPacketData( GameConnection* conn, BitStream* stream );

+ 1 - 1
Engine/source/T3D/convexShape.cpp

@@ -502,7 +502,7 @@ void ConvexShape::prepRenderImage( SceneRenderState *state )
    }
    }
    */
    */
 
 
-   if ( mVertexBuffer.isNull() )
+   if ( mVertexBuffer.isNull() || !state)
       return;
       return;
 
 
    // If we don't have a material instance after the override then 
    // If we don't have a material instance after the override then 

+ 38 - 8
Engine/source/T3D/decal/decalManager.cpp

@@ -1235,8 +1235,30 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
          currentBatch = &batches.last();
          currentBatch = &batches.last();
          currentBatch->startDecal = i;
          currentBatch->startDecal = i;
          currentBatch->decalCount = 1;
          currentBatch->decalCount = 1;
-         currentBatch->iCount = decal->mIndxCount;
-         currentBatch->vCount = decal->mVertCount;
+
+         // Shrink and warning: preventing a potential crash.
+         currentBatch->iCount =
+             (decal->mIndxCount > smMaxIndices) ? smMaxIndices : decal->mIndxCount;
+         currentBatch->vCount =
+             (decal->mVertCount > smMaxVerts) ? smMaxVerts : decal->mVertCount;
+#ifdef TORQUE_DEBUG
+         // we didn't mean send a spam to the console
+         static U32 countMsgIndx = 0;
+         if ( (decal->mIndxCount > smMaxIndices) && ((countMsgIndx++ % 1024) == 0) ) {
+            Con::warnf(
+               "DecalManager::prepRenderImage() - Shrinked indices of decal."
+               " Lost %u.",  (decal->mIndxCount - smMaxIndices)
+            );
+         }
+         static U32 countMsgVert = 0;
+         if ( (decal->mVertCount > smMaxVerts) && ((countMsgVert++ % 1024) == 0) ) {
+            Con::warnf(
+               "DecalManager::prepRenderImage() - Shrinked vertices of decal."
+               " Lost %u.",  (decal->mVertCount - smMaxVerts)
+            );
+         }
+#endif
+
          currentBatch->mat = mat;
          currentBatch->mat = mat;
          currentBatch->matInst = decal->mDataBlock->getMaterialInstance();
          currentBatch->matInst = decal->mDataBlock->getMaterialInstance();
          currentBatch->priority = decal->getRenderPriority();         
          currentBatch->priority = decal->getRenderPriority();         
@@ -1299,15 +1321,21 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
       {
       {
          DecalInstance *dinst = mDecalQueue[j];
          DecalInstance *dinst = mDecalQueue[j];
 
 
-         for ( U32 k = 0; k < dinst->mIndxCount; k++ )
+         const U32 indxCount =
+             (dinst->mIndxCount > currentBatch.iCount) ?
+             currentBatch.iCount : dinst->mIndxCount;
+         for ( U32 k = 0; k < indxCount; k++ )
          {
          {
             *( pbPtr + ioffset + k ) = dinst->mIndices[k] + voffset;            
             *( pbPtr + ioffset + k ) = dinst->mIndices[k] + voffset;            
          }
          }
 
 
-         ioffset += dinst->mIndxCount;
+         ioffset += indxCount;
 
 
-         dMemcpy( vpPtr + voffset, dinst->mVerts, sizeof( DecalVertex ) * dinst->mVertCount );
-         voffset += dinst->mVertCount;
+         const U32 vertCount =
+             (dinst->mVertCount > currentBatch.vCount) ?
+             currentBatch.vCount : dinst->mVertCount;
+         dMemcpy( vpPtr + voffset, dinst->mVerts, sizeof( DecalVertex ) * vertCount );
+         voffset += vertCount;
 
 
          // Ugly hack for ProjectedShadow!
          // Ugly hack for ProjectedShadow!
          if ( (dinst->mFlags & CustomDecal) && dinst->mCustomTex != NULL )
          if ( (dinst->mFlags & CustomDecal) && dinst->mCustomTex != NULL )
@@ -1357,8 +1385,10 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
       pb->lock( &pbPtr );
       pb->lock( &pbPtr );
 
 
       // Memcpy from system to video memory.
       // Memcpy from system to video memory.
-      dMemcpy( vpPtr, vertData, sizeof( DecalVertex ) * currentBatch.vCount );
-      dMemcpy( pbPtr, indexData, sizeof( U16 ) * currentBatch.iCount );
+      const U32 vpCount = sizeof( DecalVertex ) * currentBatch.vCount;
+      dMemcpy( vpPtr, vertData, vpCount );
+      const U32 pbCount = sizeof( U16 ) * currentBatch.iCount;
+      dMemcpy( pbPtr, indexData, pbCount );
 
 
       pb->unlock();
       pb->unlock();
       vb->unlock();
       vb->unlock();

+ 1 - 1
Engine/source/T3D/examples/renderMeshExample.cpp

@@ -269,7 +269,7 @@ void RenderMeshExample::prepRenderImage( SceneRenderState *state )
       createGeometry();
       createGeometry();
 
 
    // If we have no material then skip out.
    // If we have no material then skip out.
-   if ( !mMaterialInst )
+   if ( !mMaterialInst || !state)
       return;
       return;
 
 
    // If we don't have a material instance after the override then 
    // If we don't have a material instance after the override then 

+ 7 - 5
Engine/source/T3D/fps/guiClockHud.cpp

@@ -113,9 +113,11 @@ void GuiClockHud::initPersistFields()
 
 
 void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
 void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
 {
 {
+   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
+
    // Background first
    // Background first
    if (mShowFill)
    if (mShowFill)
-      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
+      drawUtil->drawRectFill(updateRect, mFillColor);
 
 
    // Convert ms time into hours, minutes and seconds.
    // Convert ms time into hours, minutes and seconds.
    S32 time = S32(getTime());
    S32 time = S32(getTime());
@@ -129,13 +131,13 @@ void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
    // Center the text
    // Center the text
    offset.x += (getWidth() - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;
    offset.x += (getWidth() - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;
    offset.y += (getHeight() - mProfile->mFont->getHeight()) / 2;
    offset.y += (getHeight() - mProfile->mFont->getHeight()) / 2;
-   GFX->getDrawUtil()->setBitmapModulation(mTextColor);
-   GFX->getDrawUtil()->drawText(mProfile->mFont, offset, buf);
-   GFX->getDrawUtil()->clearBitmapModulation();
+   drawUtil->setBitmapModulation(mTextColor);
+   drawUtil->drawText(mProfile->mFont, offset, buf);
+   drawUtil->clearBitmapModulation();
 
 
    // Border last
    // Border last
    if (mShowFrame)
    if (mShowFrame)
-      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);
+      drawUtil->drawRect(updateRect, mFrameColor);
 }
 }
 
 
 
 

+ 7 - 5
Engine/source/T3D/fps/guiHealthTextHud.cpp

@@ -162,10 +162,12 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
       else  
       else  
          mValue = 100 - (100 * control->getDamageValue());    
          mValue = 100 - (100 * control->getDamageValue());    
    }  
    }  
+
+   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
   
   
    // If enabled draw background first  
    // If enabled draw background first  
    if (mShowFill)  
    if (mShowFill)  
-      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);  
+      drawUtil->drawRectFill(updateRect, mFillColor);  
   
   
    // Prepare text and center it  
    // Prepare text and center it  
    S32 val = (S32)mValue;    
    S32 val = (S32)mValue;    
@@ -190,11 +192,11 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
       }  
       }  
    }  
    }  
   
   
-   GFX->getDrawUtil()->setBitmapModulation(tColor);    
-   GFX->getDrawUtil()->drawText(mProfile->mFont, offset, buf);    
-   GFX->getDrawUtil()->clearBitmapModulation();    
+   drawUtil->setBitmapModulation(tColor);    
+   drawUtil->drawText(mProfile->mFont, offset, buf);    
+   drawUtil->clearBitmapModulation();    
   
   
    // If enabled draw the border last  
    // If enabled draw the border last  
    if (mShowFrame)  
    if (mShowFrame)  
-      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);  
+      drawUtil->drawRect(updateRect, mFrameColor);  
 }  
 }  

+ 8 - 6
Engine/source/T3D/fps/guiShapeNameHud.cpp

@@ -196,7 +196,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
 
 
    // Collision info. We're going to be running LOS tests and we
    // Collision info. We're going to be running LOS tests and we
    // don't want to collide with the control object.
    // don't want to collide with the control object.
-   static U32 losMask = TerrainObjectType | ShapeBaseObjectType;
+   static U32 losMask = TerrainObjectType | ShapeBaseObjectType | StaticObjectType;
    control->disableCollision();
    control->disableCollision();
 
 
    // All ghosted objects are added to the server connection group,
    // All ghosted objects are added to the server connection group,
@@ -301,18 +301,20 @@ void GuiShapeNameHud::drawName(Point2I offset, const char *name, F32 opacity)
    offset.x -= width / 2;
    offset.x -= width / 2;
    offset.y -= height / 2;
    offset.y -= height / 2;
 
 
+   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
+
    // Background fill first
    // Background fill first
    if (mShowLabelFill)
    if (mShowLabelFill)
-      GFX->getDrawUtil()->drawRectFill(RectI(offset, extent), mLabelFillColor);
+      drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor);
 
 
    // Deal with opacity and draw.
    // Deal with opacity and draw.
    mTextColor.alpha = opacity;
    mTextColor.alpha = opacity;
-   GFX->getDrawUtil()->setBitmapModulation(mTextColor);
-   GFX->getDrawUtil()->drawText(mProfile->mFont, offset + mLabelPadding, name);
-   GFX->getDrawUtil()->clearBitmapModulation();
+   drawUtil->setBitmapModulation(mTextColor);
+   drawUtil->drawText(mProfile->mFont, offset + mLabelPadding, name);
+   drawUtil->clearBitmapModulation();
 
 
    // Border last
    // Border last
    if (mShowLabelFrame)
    if (mShowLabelFrame)
-      GFX->getDrawUtil()->drawRect(RectI(offset, extent), mLabelFrameColor);
+      drawUtil->drawRect(RectI(offset, extent), mLabelFrameColor);
 }
 }
 
 

+ 2 - 2
Engine/source/T3D/fx/fxFoliageReplicator.cpp

@@ -248,7 +248,7 @@ fxFoliageCulledList::fxFoliageCulledList(Box3F SearchBox, fxFoliageCulledList* I
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 
 
-void fxFoliageCulledList::FindCandidates(Box3F SearchBox, fxFoliageCulledList* InVec)
+void fxFoliageCulledList::FindCandidates(const Box3F& SearchBox, fxFoliageCulledList* InVec)
 {
 {
    // Search the Culled List.
    // Search the Culled List.
    for (U32 i = 0; i < InVec->GetListCount(); i++)
    for (U32 i = 0; i < InVec->GetListCount(); i++)
@@ -1028,7 +1028,7 @@ void fxFoliageReplicator::SetupBuffers()
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 
 
-Box3F fxFoliageReplicator::FetchQuadrant(Box3F Box, U32 Quadrant)
+Box3F fxFoliageReplicator::FetchQuadrant(const Box3F& Box, U32 Quadrant)
 {
 {
    Box3F QuadrantBox;
    Box3F QuadrantBox;
 
 

+ 2 - 2
Engine/source/T3D/fx/fxFoliageReplicator.h

@@ -86,7 +86,7 @@ public:
    fxFoliageCulledList(Box3F SearchBox, fxFoliageCulledList* InVec);
    fxFoliageCulledList(Box3F SearchBox, fxFoliageCulledList* InVec);
    ~fxFoliageCulledList() {};
    ~fxFoliageCulledList() {};
 
 
-   void FindCandidates(Box3F SearchBox, fxFoliageCulledList* InVec);
+   void FindCandidates(const Box3F& SearchBox, fxFoliageCulledList* InVec);
 
 
    U32 GetListCount(void) { return mCulledObjectSet.size(); };
    U32 GetListCount(void) { return mCulledObjectSet.size(); };
    fxFoliageItem* GetElement(U32 index) { return mCulledObjectSet[index]; };
    fxFoliageItem* GetElement(U32 index) { return mCulledObjectSet[index]; };
@@ -157,7 +157,7 @@ protected:
 
 
    void SyncFoliageReplicators(void);
    void SyncFoliageReplicators(void);
 
 
-   Box3F FetchQuadrant(Box3F Box, U32 Quadrant);
+   Box3F FetchQuadrant(const Box3F& Box, U32 Quadrant);
    void ProcessQuadrant(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList, U32 Quadrant);
    void ProcessQuadrant(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList, U32 Quadrant);
    void ProcessNodeChildren(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList);
    void ProcessNodeChildren(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList);
 
 

+ 1 - 1
Engine/source/T3D/fx/precipitation.cpp

@@ -1293,7 +1293,7 @@ void Precipitation::interpolateTick(F32 delta)
 void Precipitation::processTick(const Move *)
 void Precipitation::processTick(const Move *)
 {
 {
    //nothing to do on the server
    //nothing to do on the server
-   if (isServerObject() || mDataBlock == NULL)
+   if (isServerObject() || mDataBlock == NULL || isHidden())
       return;
       return;
 
 
    const U32 currTime = Platform::getVirtualMilliseconds();
    const U32 currTime = Platform::getVirtualMilliseconds();

+ 4 - 0
Engine/source/T3D/gameBase/gameBase.h

@@ -39,6 +39,9 @@
 #include "scene/sceneManager.h"    
 #include "scene/sceneManager.h"    
 #define __SCENEMANAGER_H__  
 #define __SCENEMANAGER_H__  
 #endif
 #endif
+#ifndef _IDISPLAYDEVICE_H_
+#include "platform/output/IDisplayDevice.h"
+#endif
 
 
 class NetConnection;
 class NetConnection;
 class ProcessList;
 class ProcessList;
@@ -418,6 +421,7 @@ public:
    
    
    // Not implemented here, but should return the Camera to world transformation matrix
    // Not implemented here, but should return the Camera to world transformation matrix
    virtual void getCameraTransform (F32 *pos, MatrixF *mat ) { *mat = MatrixF::Identity; }
    virtual void getCameraTransform (F32 *pos, MatrixF *mat ) { *mat = MatrixF::Identity; }
+   virtual void getEyeCameraTransform ( IDisplayDevice *device, U32 eyeId, MatrixF *mat ) { *mat = MatrixF::Identity; }
 
 
    /// Returns the water object we are colliding with, it is up to derived
    /// Returns the water object we are colliding with, it is up to derived
    /// classes to actually set this object.
    /// classes to actually set this object.

+ 25 - 0
Engine/source/T3D/gameBase/gameConnection.cpp

@@ -235,6 +235,7 @@ GameConnection::GameConnection()
 
 
 GameConnection::~GameConnection()
 GameConnection::~GameConnection()
 {
 {
+   setDisplayDevice(NULL);
    delete mAuthInfo;
    delete mAuthInfo;
    for(U32 i = 0; i < mConnectArgc; i++)
    for(U32 i = 0; i < mConnectArgc; i++)
       dFree(mConnectArgv[i]);
       dFree(mConnectArgv[i]);
@@ -673,6 +674,30 @@ bool GameConnection::getControlCameraTransform(F32 dt, MatrixF* mat)
    return true;
    return true;
 }
 }
 
 
+bool GameConnection::getControlCameraEyeTransforms(IDisplayDevice *display, MatrixF *transforms)
+{
+   GameBase* obj = getCameraObject();
+   if(!obj)
+      return false;
+
+   GameBase* cObj = obj;
+   while((cObj = cObj->getControlObject()) != 0)
+   {
+      if(cObj->useObjsEyePoint())
+         obj = cObj;
+   }
+
+   // Perform operation on left & right eyes. For each we need to calculate the world space 
+   // of the rotated eye offset and add that onto the camera world space.
+   for (U32 i=0; i<2; i++)
+   {
+      obj->getEyeCameraTransform(display, i, &transforms[i]);
+   }
+
+   return true;
+}
+
+
 bool GameConnection::getControlCameraDefaultFov(F32 * fov)
 bool GameConnection::getControlCameraDefaultFov(F32 * fov)
 {
 {
    //find the last control object in the chain (client->player->turret->whatever...)
    //find the last control object in the chain (client->player->turret->whatever...)

+ 6 - 2
Engine/source/T3D/gameBase/gameConnection.h

@@ -269,6 +269,10 @@ public:
    bool getControlCameraTransform(F32 dt,MatrixF* mat);
    bool getControlCameraTransform(F32 dt,MatrixF* mat);
    bool getControlCameraVelocity(Point3F *vel);
    bool getControlCameraVelocity(Point3F *vel);
 
 
+   /// Returns the eye transforms for the control object, using supplemental information 
+   /// from the provided IDisplayDevice.
+   bool getControlCameraEyeTransforms(IDisplayDevice *display, MatrixF *transforms);
+   
    bool getControlCameraDefaultFov(F32 *fov);
    bool getControlCameraDefaultFov(F32 *fov);
    bool getControlCameraFov(F32 *fov);
    bool getControlCameraFov(F32 *fov);
    bool setControlCameraFov(F32 fov);
    bool setControlCameraFov(F32 fov);
@@ -280,8 +284,8 @@ public:
    void setFirstPerson(bool firstPerson);
    void setFirstPerson(bool firstPerson);
    
    
    bool hasDisplayDevice() const { return mDisplayDevice != NULL; }
    bool hasDisplayDevice() const { return mDisplayDevice != NULL; }
-   const IDisplayDevice* getDisplayDevice() const { return mDisplayDevice; }
-   void setDisplayDevice(IDisplayDevice* display) { mDisplayDevice = display; }
+   IDisplayDevice* getDisplayDevice() const { return mDisplayDevice; }
+   void setDisplayDevice(IDisplayDevice* display) { if (mDisplayDevice) mDisplayDevice->setDrawCanvas(NULL); mDisplayDevice = display; }
    void clearDisplayDevice() { mDisplayDevice = NULL; }
    void clearDisplayDevice() { mDisplayDevice = NULL; }
 
 
    void setControlSchemeParameters(bool absoluteRotation, bool addYawToAbsRot, bool addPitchToAbsRot);
    void setControlSchemeParameters(bool absoluteRotation, bool addYawToAbsRot, bool addPitchToAbsRot);

+ 37 - 12
Engine/source/T3D/gameFunctions.cpp

@@ -349,8 +349,13 @@ bool GameProcessCameraQuery(CameraQuery *query)
 
 
       // Provide some default values
       // Provide some default values
       query->projectionOffset = Point2F::Zero;
       query->projectionOffset = Point2F::Zero;
-      query->eyeOffset = Point3F::Zero;
-
+      query->stereoTargets[0] = 0;
+      query->stereoTargets[1] = 0;
+      query->eyeOffset[0] = Point3F::Zero;
+      query->eyeOffset[1] = Point3F::Zero;
+      query->hasFovPort = false;
+      query->hasStereoTargets = false;
+      
       F32 cameraFov = 0.0f;
       F32 cameraFov = 0.0f;
       bool fovSet = false;
       bool fovSet = false;
 
 
@@ -358,14 +363,14 @@ bool GameProcessCameraQuery(CameraQuery *query)
       // is not open
       // is not open
       if(!gEditingMission && connection->hasDisplayDevice())
       if(!gEditingMission && connection->hasDisplayDevice())
       {
       {
-         const IDisplayDevice* display = connection->getDisplayDevice();
+         IDisplayDevice* display = connection->getDisplayDevice();
+         // Note: all eye values are invalid until this is called
+         display->setDrawCanvas(query->drawCanvas);
 
 
-         // The connection's display device may want to set the FOV
-         if(display->providesYFOV())
-         {
-            cameraFov = mRadToDeg(display->getYFOV());
-            fovSet = true;
-         }
+         display->setCurrentConnection(connection);
+
+         // Display may activate AFTER so we need to call this again just in case
+         display->onStartFrame();
 
 
          // The connection's display device may want to set the projection offset
          // The connection's display device may want to set the projection offset
          if(display->providesProjectionOffset())
          if(display->providesProjectionOffset())
@@ -374,14 +379,34 @@ bool GameProcessCameraQuery(CameraQuery *query)
          }
          }
 
 
          // The connection's display device may want to set the eye offset
          // The connection's display device may want to set the eye offset
-         if(display->providesEyeOffset())
+         if(display->providesEyeOffsets())
          {
          {
-            query->eyeOffset = display->getEyeOffset();
+            display->getEyeOffsets(query->eyeOffset);
          }
          }
+
+         // Grab field of view for both eyes
+         if (display->providesFovPorts())
+         {
+            display->getFovPorts(query->fovPort);
+            fovSet = true;
+            query->hasFovPort = true;
+         }
+         
+         // Grab the latest overriding render view transforms
+         connection->getControlCameraEyeTransforms(display, query->eyeTransforms);
+
+         display->getStereoViewports(query->stereoViewports);
+         display->getStereoTargets(query->stereoTargets);
+         query->hasStereoTargets = true;
+      }
+      else
+      {
+         query->eyeTransforms[0] = query->cameraMatrix;
+         query->eyeTransforms[1] = query->cameraMatrix;
       }
       }
 
 
       // Use the connection's FOV settings if requried
       // Use the connection's FOV settings if requried
-      if(!fovSet && !connection->getControlCameraFov(&cameraFov))
+      if(!connection->getControlCameraFov(&cameraFov))
       {
       {
          return false;
          return false;
       }
       }

+ 0 - 8
Engine/source/T3D/gameTSCtrl.cpp

@@ -55,10 +55,6 @@ bool GameTSCtrl::onAdd()
    if ( !Parent::onAdd() )
    if ( !Parent::onAdd() )
       return false;
       return false;
 
 
-#ifdef TORQUE_DEMO_WATERMARK
-   mWatermark.init();
-#endif
-
    return true;
    return true;
 }
 }
 
 
@@ -172,10 +168,6 @@ void GameTSCtrl::onRender(Point2I offset, const RectI &updateRect)
 
 
    if(!skipRender || true)
    if(!skipRender || true)
       Parent::onRender(offset, updateRect);
       Parent::onRender(offset, updateRect);
-
-#ifdef TORQUE_DEMO_WATERMARK
-   mWatermark.render(getExtent());
-#endif
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------

+ 0 - 10
Engine/source/T3D/gameTSCtrl.h

@@ -30,12 +30,6 @@
 #include "gui/3d/guiTSControl.h"
 #include "gui/3d/guiTSControl.h"
 #endif
 #endif
 
 
-#ifdef TORQUE_DEMO_WATERMARK
-#ifndef _WATERMARK_H_
-#include "demo/watermark/watermark.h"
-#endif
-#endif
-
 class ProjectileData;
 class ProjectileData;
 class GameBase;
 class GameBase;
 
 
@@ -45,10 +39,6 @@ class GameTSCtrl : public GuiTSCtrl
 private:
 private:
    typedef GuiTSCtrl Parent;
    typedef GuiTSCtrl Parent;
 
 
-#ifdef TORQUE_DEMO_WATERMARK
-   Watermark mWatermark;
-#endif
-
    void makeScriptCall(const char *func, const GuiEvent &evt) const;
    void makeScriptCall(const char *func, const GuiEvent &evt) const;
 
 
 public:
 public:

+ 3 - 2
Engine/source/T3D/lightAnimData.cpp

@@ -195,6 +195,7 @@ bool LightAnimData::AnimValue<COUNT>::animate( F32 time, F32 *output )
    F32 scaledTime, lerpFactor, valueRange, keyFrameLerp;
    F32 scaledTime, lerpFactor, valueRange, keyFrameLerp;
    U32 posFrom, posTo;
    U32 posFrom, posTo;
    S32 keyFrameFrom, keyFrameTo;
    S32 keyFrameFrom, keyFrameTo;
+   F32 initialValue = *output;
    
    
    bool wasAnimated = false;
    bool wasAnimated = false;
 
 
@@ -215,13 +216,13 @@ bool LightAnimData::AnimValue<COUNT>::animate( F32 time, F32 *output )
 	   valueRange = ( value2[i] - value1[i] ) / 25.0f;
 	   valueRange = ( value2[i] - value1[i] ) / 25.0f;
 
 
       if ( !smooth[i] )
       if ( !smooth[i] )
-   	   output[i] = value1[i] + ( keyFrameFrom * valueRange );
+         output[i] = (value1[i] + (keyFrameFrom * valueRange)) * initialValue;
       else
       else
       {
       {
          lerpFactor = scaledTime - posFrom;
          lerpFactor = scaledTime - posFrom;
    	   keyFrameLerp = ( keyFrameTo - keyFrameFrom ) * lerpFactor;
    	   keyFrameLerp = ( keyFrameTo - keyFrameFrom ) * lerpFactor;
 
 
-         output[i] = value1[i] + ( ( keyFrameFrom + keyFrameLerp ) * valueRange );
+         output[i] = (value1[i] + ((keyFrameFrom + keyFrameLerp) * valueRange)) * initialValue;
       }
       }
    }
    }
 
 

+ 5 - 5
Engine/source/T3D/physics/bullet/btPlayer.cpp

@@ -290,8 +290,9 @@ bool BtPlayer::_sweep( btVector3 *inOutCurrPos, const btVector3 &disp, Collision
    BtPlayerSweepCallback callback( mGhostObject, disp.normalized() );
    BtPlayerSweepCallback callback( mGhostObject, disp.normalized() );
 	callback.m_collisionFilterGroup = mGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
 	callback.m_collisionFilterGroup = mGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
 	callback.m_collisionFilterMask = mGhostObject->getBroadphaseHandle()->m_collisionFilterMask;
 	callback.m_collisionFilterMask = mGhostObject->getBroadphaseHandle()->m_collisionFilterMask;
-	
-	mGhostObject->convexSweepTest( mColShape, start, end, callback, 0.0f );
+
+   if (disp.length()>0.0001)
+      mGhostObject->convexSweepTest( mColShape, start, end, callback, 0.0f );
 
 
 	inOutCurrPos->setInterpolate3( start.getOrigin(), end.getOrigin(), callback.m_closestHitFraction );
 	inOutCurrPos->setInterpolate3( start.getOrigin(), end.getOrigin(), callback.m_closestHitFraction );
    if ( callback.hasHit() )
    if ( callback.hasHit() )
@@ -434,9 +435,8 @@ void BtPlayer::findContact(   SceneObject **contactObject,
       if ( other == mGhostObject )
       if ( other == mGhostObject )
          other = (btCollisionObject*)pair.m_pProxy1->m_clientObject;
          other = (btCollisionObject*)pair.m_pProxy1->m_clientObject;
 
 
-      AssertFatal( !outOverlapObjects->contains( PhysicsUserData::getObject( other->getUserPointer() ) ),
-         "Got multiple pairs of the same object!" );
-      outOverlapObjects->push_back( PhysicsUserData::getObject( other->getUserPointer() ) );
+      if (!outOverlapObjects->contains(PhysicsUserData::getObject(other->getUserPointer())))
+         outOverlapObjects->push_back( PhysicsUserData::getObject( other->getUserPointer() ) );
 
 
       if ( other->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE )
       if ( other->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE )
          continue;
          continue;

+ 53 - 0
Engine/source/T3D/player.cpp

@@ -1650,6 +1650,7 @@ Player::Player()
 
 
    mLastAbsoluteYaw = 0.0f;
    mLastAbsoluteYaw = 0.0f;
    mLastAbsolutePitch = 0.0f;
    mLastAbsolutePitch = 0.0f;
+   mLastAbsoluteRoll = 0.0f;
 }
 }
 
 
 Player::~Player()
 Player::~Player()
@@ -2608,6 +2609,7 @@ void Player::updateMove(const Move* move)
             }
             }
             mLastAbsoluteYaw = emove->rotZ[emoveIndex];
             mLastAbsoluteYaw = emove->rotZ[emoveIndex];
             mLastAbsolutePitch = emove->rotX[emoveIndex];
             mLastAbsolutePitch = emove->rotX[emoveIndex];
+            mLastAbsoluteRoll = emove->rotY[emoveIndex];
 
 
             // Head bank
             // Head bank
             mHead.y = emove->rotY[emoveIndex];
             mHead.y = emove->rotY[emoveIndex];
@@ -5584,6 +5586,57 @@ void Player::getMuzzleTransform(U32 imageSlot,MatrixF* mat)
    *mat = nmat;
    *mat = nmat;
 }
 }
 
 
+DisplayPose Player::calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose)
+{
+   // NOTE: this is intended to be similar to updateMove
+   DisplayPose outPose;
+   outPose.orientation = getRenderTransform().toEuler();
+   outPose.position = inPose.position;
+
+   if (con && con->getControlSchemeAbsoluteRotation())
+   {
+      // Pitch
+      outPose.orientation.x = (inPose.orientation.x - mLastAbsolutePitch);
+
+      // Constrain the range of mRot.x
+      while (outPose.orientation.x  < -M_PI_F) 
+         outPose.orientation.x += M_2PI_F;
+      while (outPose.orientation.x  > M_PI_F) 
+         outPose.orientation.x -= M_2PI_F;
+
+      // Yaw
+
+      // Rotate (heading) head or body?
+      if ((isMounted() && getMountNode() == 0) || (con && !con->isFirstPerson()))
+      {
+         // Rotate head
+         outPose.orientation.z = (inPose.orientation.z - mLastAbsoluteYaw);
+      }
+      else
+      {
+         // Rotate body
+         outPose.orientation.z = (inPose.orientation.z - mLastAbsoluteYaw);
+      }
+
+      // Constrain the range of mRot.z
+      while (outPose.orientation.z < 0.0f)
+         outPose.orientation.z += M_2PI_F;
+      while (outPose.orientation.z > M_2PI_F)
+         outPose.orientation.z -= M_2PI_F;
+
+      // Bank
+      if (mDataBlock->cameraCanBank)
+      {
+         outPose.orientation.y = (inPose.orientation.y - mLastAbsoluteRoll);
+      }
+
+      // Constrain the range of mRot.y
+      while (outPose.orientation.y > M_PI_F) 
+         outPose.orientation.y -= M_2PI_F;
+   }
+
+   return outPose;
+}
 
 
 void Player::getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat)
 void Player::getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat)
 {
 {

+ 2 - 0
Engine/source/T3D/player.h

@@ -439,6 +439,7 @@ protected:
 
 
    F32 mLastAbsoluteYaw;            ///< Stores that last absolute yaw value as passed in by ExtendedMove
    F32 mLastAbsoluteYaw;            ///< Stores that last absolute yaw value as passed in by ExtendedMove
    F32 mLastAbsolutePitch;          ///< Stores that last absolute pitch value as passed in by ExtendedMove
    F32 mLastAbsolutePitch;          ///< Stores that last absolute pitch value as passed in by ExtendedMove
+   F32 mLastAbsoluteRoll;           ///< Stores that last absolute roll value as passed in by ExtendedMove
 
 
    S32 mMountPending;               ///< mMountPending suppresses tickDelay countdown so players will sit until
    S32 mMountPending;               ///< mMountPending suppresses tickDelay countdown so players will sit until
                                     ///< their mount, or another animation, comes through (or 13 seconds elapses).
                                     ///< their mount, or another animation, comes through (or 13 seconds elapses).
@@ -683,6 +684,7 @@ public:
    void getEyeBaseTransform(MatrixF* mat, bool includeBank);
    void getEyeBaseTransform(MatrixF* mat, bool includeBank);
    void getRenderEyeTransform(MatrixF* mat);
    void getRenderEyeTransform(MatrixF* mat);
    void getRenderEyeBaseTransform(MatrixF* mat, bool includeBank);
    void getRenderEyeBaseTransform(MatrixF* mat, bool includeBank);
+   virtual DisplayPose calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose);
    void getCameraParameters(F32 *min, F32 *max, Point3F *offset, MatrixF *rot);
    void getCameraParameters(F32 *min, F32 *max, Point3F *offset, MatrixF *rot);
    void getMuzzleTransform(U32 imageSlot,MatrixF* mat);
    void getMuzzleTransform(U32 imageSlot,MatrixF* mat);
    void getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat);   
    void getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat);   

+ 1 - 1
Engine/source/T3D/projectile.cpp

@@ -1018,7 +1018,7 @@ void Projectile::explode( const Point3F &p, const Point3F &n, const U32 collideT
 
 
       // Client (impact) decal.
       // Client (impact) decal.
       if ( mDataBlock->decal )     
       if ( mDataBlock->decal )     
-         gDecalManager->addDecal(p, n, mRandF(0.0f, M_2PI_F), mDataBlock->decal);
+         gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal);
 
 
       // Client object
       // Client object
       updateSound();
       updateSound();

+ 111 - 44
Engine/source/T3D/shapeBase.cpp

@@ -40,7 +40,6 @@
 #include "scene/sceneRenderState.h"
 #include "scene/sceneRenderState.h"
 #include "scene/sceneObjectLightingPlugin.h"
 #include "scene/sceneObjectLightingPlugin.h"
 #include "T3D/fx/explosion.h"
 #include "T3D/fx/explosion.h"
-#include "T3D/fx/particleEmitter.h"
 #include "T3D/fx/cameraFXMgr.h"
 #include "T3D/fx/cameraFXMgr.h"
 #include "environment/waterBlock.h"
 #include "environment/waterBlock.h"
 #include "T3D/debris.h"
 #include "T3D/debris.h"
@@ -154,19 +153,26 @@ ShapeBaseData::ShapeBaseData()
    shadowSphereAdjust( 1.0f ),
    shadowSphereAdjust( 1.0f ),
    shapeName( StringTable->insert("") ),
    shapeName( StringTable->insert("") ),
    cloakTexName( StringTable->insert("") ),
    cloakTexName( StringTable->insert("") ),
+   cubeDescId( 0 ),
+   reflectorDesc( NULL ),
+   debris( NULL ),
+   debrisID( 0 ),
+   debrisShapeName( StringTable->insert("") ),
+   explosion( NULL ),
+   explosionID( 0 ),
+   underwaterExplosion( NULL ),
+   underwaterExplosionID( 0 ),
    mass( 1.0f ),
    mass( 1.0f ),
    drag( 0.0f ),
    drag( 0.0f ),
    density( 1.0f ),
    density( 1.0f ),
    maxEnergy( 0.0f ),
    maxEnergy( 0.0f ),
    maxDamage( 1.0f ),
    maxDamage( 1.0f ),
-   disabledLevel( 1.0f ),
    destroyedLevel( 1.0f ),
    destroyedLevel( 1.0f ),
+   disabledLevel( 1.0f ),
    repairRate( 0.0033f ),
    repairRate( 0.0033f ),
    eyeNode( -1 ),
    eyeNode( -1 ),
    earNode( -1 ),
    earNode( -1 ),
    cameraNode( -1 ),
    cameraNode( -1 ),
-   damageSequence( -1 ),
-   hulkSequence( -1 ),
    cameraMaxDist( 0.0f ),
    cameraMaxDist( 0.0f ),
    cameraMinDist( 0.2f ),
    cameraMinDist( 0.2f ),
    cameraDefaultFov( 75.0f ),
    cameraDefaultFov( 75.0f ),
@@ -174,24 +180,17 @@ ShapeBaseData::ShapeBaseData()
    cameraMaxFov( 120.f ),
    cameraMaxFov( 120.f ),
    cameraCanBank( false ),
    cameraCanBank( false ),
    mountedImagesBank( false ),
    mountedImagesBank( false ),
-   isInvincible( false ),
-   renderWhenDestroyed( true ),
-   debris( NULL ),
-   debrisID( 0 ),
-   debrisShapeName( StringTable->insert("") ),
-   explosion( NULL ),
-   explosionID( 0 ),
-   underwaterExplosion( NULL ),
-   underwaterExplosionID( 0 ),
+   debrisDetail( -1 ),
+   damageSequence( -1 ),
+   hulkSequence( -1 ),
+   observeThroughObject( false ),
    firstPersonOnly( false ),
    firstPersonOnly( false ),
    useEyePoint( false ),
    useEyePoint( false ),
-   cubeDescId( 0 ),
-   reflectorDesc( NULL ),
-   observeThroughObject( false ),
+   isInvincible( false ),
+   renderWhenDestroyed( true ),
    computeCRC( false ),
    computeCRC( false ),
    inheritEnergyFromMount( false ),
    inheritEnergyFromMount( false ),
-   mCRC( 0 ),
-   debrisDetail( -1 )
+   mCRC( 0 )
 {      
 {      
    dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
    dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
 }
 }
@@ -878,46 +877,46 @@ IMPLEMENT_CALLBACK( ShapeBase, validateCameraFov, F32, (F32 fov), (fov),
    "@see ShapeBaseData\n\n");
    "@see ShapeBaseData\n\n");
 
 
 ShapeBase::ShapeBase()
 ShapeBase::ShapeBase()
- : mDrag( 0.0f ),
-   mBuoyancy( 0.0f ),
-   mWaterCoverage( 0.0f ),
-   mLiquidHeight( 0.0f ),
+ : mDataBlock( NULL ),
+   mIsAiControlled( false ),
    mControllingObject( NULL ),
    mControllingObject( NULL ),
-   mGravityMod( 1.0f ),
-   mAppliedForce( Point3F::Zero ),
-   mTimeoutList( NULL ),
-   mDataBlock( NULL ),
+   mMoveMotion( false ),
+   mShapeBaseMount( NULL ),
    mShapeInstance( NULL ),
    mShapeInstance( NULL ),
+   mConvexList( new Convex ),
    mEnergy( 0.0f ),
    mEnergy( 0.0f ),
    mRechargeRate( 0.0f ),
    mRechargeRate( 0.0f ),
+   mMass( 1.0f ),
+   mOneOverMass( 1.0f ),
+   mDrag( 0.0f ),
+   mBuoyancy( 0.0f ),
+   mLiquidHeight( 0.0f ),
+   mWaterCoverage( 0.0f ),
+   mAppliedForce( Point3F::Zero ),
+   mGravityMod( 1.0f ),
+   mDamageFlash( 0.0f ),
+   mWhiteOut( 0.0f ),
+   mFlipFadeVal( false ),
+   mTimeoutList( NULL ),
    mDamage( 0.0f ),
    mDamage( 0.0f ),
    mRepairRate( 0.0f ),
    mRepairRate( 0.0f ),
    mRepairReserve( 0.0f ),
    mRepairReserve( 0.0f ),
    mDamageState( Enabled ),
    mDamageState( Enabled ),
    mDamageThread( NULL ),
    mDamageThread( NULL ),
    mHulkThread( NULL ),
    mHulkThread( NULL ),
-   mLastRenderFrame( 0 ),
-   mLastRenderDistance( 0.0f ),
+   damageDir( 0.0f, 0.0f, 1.0f ),
    mCloaked( false ),
    mCloaked( false ),
    mCloakLevel( 0.0f ),
    mCloakLevel( 0.0f ),
-   mDamageFlash( 0.0f ),
-   mWhiteOut( 0.0f ),
-   mIsControlled( false ),
-   mConvexList( new Convex ),
-   mCameraFov( 90.0f ),
    mFadeOut( true ),
    mFadeOut( true ),
    mFading( false ),
    mFading( false ),
    mFadeVal( 1.0f ),
    mFadeVal( 1.0f ),
-   mFadeTime( 1.0f ),
    mFadeElapsedTime( 0.0f ),
    mFadeElapsedTime( 0.0f ),
+   mFadeTime( 1.0f ),
    mFadeDelay( 0.0f ),
    mFadeDelay( 0.0f ),
-   mFlipFadeVal( false ),
-   damageDir( 0.0f, 0.0f, 1.0f ),
-   mShapeBaseMount( NULL ),
-   mMass( 1.0f ),
-   mOneOverMass( 1.0f ),
-   mMoveMotion( false ),
-   mIsAiControlled( false )
+   mCameraFov( 90.0f ),
+   mIsControlled( false ),
+   mLastRenderFrame( 0 ),
+   mLastRenderDistance( 0.0f )
 {
 {
    mTypeMask |= ShapeBaseObjectType | LightObjectType;   
    mTypeMask |= ShapeBaseObjectType | LightObjectType;   
 
 
@@ -1192,13 +1191,13 @@ void ShapeBase::onDeleteNotify( SimObject *obj )
    Parent::onDeleteNotify( obj );      
    Parent::onDeleteNotify( obj );      
 }
 }
 
 
-void ShapeBase::onImpact(SceneObject* obj, VectorF vec)
+void ShapeBase::onImpact(SceneObject* obj, const VectorF& vec)
 {
 {
    if (!isGhost())
    if (!isGhost())
       mDataBlock->onImpact_callback( this, obj, vec, vec.len() );
       mDataBlock->onImpact_callback( this, obj, vec, vec.len() );
 }
 }
 
 
-void ShapeBase::onImpact(VectorF vec)
+void ShapeBase::onImpact(const VectorF& vec)
 {
 {
    if (!isGhost())
    if (!isGhost())
       mDataBlock->onImpact_callback( this, NULL, vec, vec.len() );
       mDataBlock->onImpact_callback( this, NULL, vec, vec.len() );
@@ -1969,6 +1968,75 @@ void ShapeBase::getCameraTransform(F32* pos,MatrixF* mat)
    mat->mul( gCamFXMgr.getTrans() );
    mat->mul( gCamFXMgr.getTrans() );
 }
 }
 
 
+void ShapeBase::getEyeCameraTransform(IDisplayDevice *displayDevice, U32 eyeId, MatrixF *outMat)
+{
+   MatrixF temp(1);
+   Point3F eyePos;
+   Point3F rotEyePos;
+
+   DisplayPose inPose;
+   displayDevice->getFrameEyePose(&inPose, eyeId);
+   DisplayPose newPose = calcCameraDeltaPose(displayDevice->getCurrentConnection(), inPose);
+
+   // Ok, basically we just need to add on newPose to the camera transform
+   // NOTE: currently we dont support third-person camera in this mode
+   MatrixF cameraTransform(1);
+   F32 fakePos = 0;
+   getCameraTransform(&fakePos, &cameraTransform);
+
+   QuatF baserot = cameraTransform;
+   QuatF qrot = QuatF(newPose.orientation);
+   QuatF concatRot;
+   concatRot.mul(baserot, qrot);
+   concatRot.setMatrix(&temp);
+   temp.setPosition(cameraTransform.getPosition() + concatRot.mulP(newPose.position, &rotEyePos));
+
+   *outMat = temp;
+}
+
+DisplayPose ShapeBase::calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose)
+{
+   // NOTE: this is intended to be similar to updateMove
+   // WARNING: does not take into account any move values
+
+   DisplayPose outPose;
+   outPose.orientation = getRenderTransform().toEuler();
+   outPose.position = inPose.position;
+
+   if (con && con->getControlSchemeAbsoluteRotation())
+   {
+      // Pitch
+      outPose.orientation.x = inPose.orientation.x;
+
+      // Constrain the range of mRot.x
+      while (outPose.orientation.x < -M_PI_F) 
+         outPose.orientation.x += M_2PI_F;
+      while (outPose.orientation.x > M_PI_F) 
+         outPose.orientation.x -= M_2PI_F;
+
+      // Yaw
+      outPose.orientation.z = inPose.orientation.z;
+
+      // Constrain the range of mRot.z
+      while (outPose.orientation.z < -M_PI_F) 
+         outPose.orientation.z += M_2PI_F;
+      while (outPose.orientation.z > M_PI_F) 
+         outPose.orientation.z -= M_2PI_F;
+
+      // Bank
+      if (mDataBlock->cameraCanBank)
+      {
+         outPose.orientation.y = inPose.orientation.y;
+      }
+
+      // Constrain the range of mRot.y
+      while (outPose.orientation.y > M_PI_F) 
+         outPose.orientation.y -= M_2PI_F;
+   }
+
+   return outPose;
+}
+
 void ShapeBase::getCameraParameters(F32 *min,F32* max,Point3F* off,MatrixF* rot)
 void ShapeBase::getCameraParameters(F32 *min,F32* max,Point3F* off,MatrixF* rot)
 {
 {
    *min = mDataBlock->cameraMinDist;
    *min = mDataBlock->cameraMinDist;
@@ -1977,7 +2045,6 @@ void ShapeBase::getCameraParameters(F32 *min,F32* max,Point3F* off,MatrixF* rot)
    rot->identity();
    rot->identity();
 }
 }
 
 
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 F32 ShapeBase::getDamageFlash() const
 F32 ShapeBase::getDamageFlash() const
 {
 {

+ 11 - 4
Engine/source/T3D/shapeBase.h

@@ -63,6 +63,8 @@
    #include "console/dynamicTypes.h"
    #include "console/dynamicTypes.h"
 #endif
 #endif
 
 
+// Need full definition visible for SimObjectPtr<ParticleEmitter>
+#include "T3D/fx/particleEmitter.h"
 
 
 class GFXCubemap;
 class GFXCubemap;
 class TSShapeInstance;
 class TSShapeInstance;
@@ -70,8 +72,6 @@ class SceneRenderState;
 class TSThread;
 class TSThread;
 class GameConnection;
 class GameConnection;
 struct CameraScopeQuery;
 struct CameraScopeQuery;
-class ParticleEmitter;
-class ParticleEmitterData;
 class ProjectileData;
 class ProjectileData;
 class ExplosionData;
 class ExplosionData;
 struct DebrisData;
 struct DebrisData;
@@ -1104,8 +1104,8 @@ protected:
    virtual void shakeCamera( U32 imageSlot );
    virtual void shakeCamera( U32 imageSlot );
    virtual void updateDamageLevel();
    virtual void updateDamageLevel();
    virtual void updateDamageState();
    virtual void updateDamageState();
-   virtual void onImpact(SceneObject* obj, VectorF vec);
-   virtual void onImpact(VectorF vec);
+   virtual void onImpact(SceneObject* obj, const VectorF& vec);
+   virtual void onImpact(const VectorF& vec);
    /// @}
    /// @}
 
 
    /// The inner prep render function that does the 
    /// The inner prep render function that does the 
@@ -1583,6 +1583,13 @@ public:
    /// @param   mat   Camera transform (out)
    /// @param   mat   Camera transform (out)
    virtual void getCameraTransform(F32* pos,MatrixF* mat);
    virtual void getCameraTransform(F32* pos,MatrixF* mat);
 
 
+   /// Gets the view transform for a particular eye, taking into account the current absolute 
+   /// orient and position values of the display device.
+   virtual void getEyeCameraTransform( IDisplayDevice *display, U32 eyeId, MatrixF *outMat );
+
+   /// Calculates a delta camera angle and view position based on inPose
+   virtual DisplayPose calcCameraDeltaPose(GameConnection *con, const DisplayPose& inPose);
+
    /// Gets the index of a node inside a mounted image given the name
    /// Gets the index of a node inside a mounted image given the name
    /// @param   imageSlot   Image slot
    /// @param   imageSlot   Image slot
    /// @param   nodeName    Node name
    /// @param   nodeName    Node name

+ 7 - 5
Engine/source/T3D/tsStatic.cpp

@@ -102,7 +102,7 @@ TSStatic::TSStatic()
    mPlayAmbient      = true;
    mPlayAmbient      = true;
    mAmbientThread    = NULL;
    mAmbientThread    = NULL;
 
 
-   mAllowPlayerStep = true;
+   mAllowPlayerStep = false;
 
 
    mConvexList = new Convex;
    mConvexList = new Convex;
 
 
@@ -1171,8 +1171,10 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia
       return;
       return;
    }
    }
 
 
+   TSMaterialList* shapeMaterialList = object->getShape()->materialList;
+
    // Check the mapTo name exists for this shape
    // Check the mapTo name exists for this shape
-   S32 matIndex = object->getShape()->materialList->getMaterialNameList().find_next(String(mapTo));
+   S32 matIndex = shapeMaterialList->getMaterialNameList().find_next(String(mapTo));
    if (matIndex < 0)
    if (matIndex < 0)
    {
    {
       Con::errorf("TSShape::changeMaterial failed: Invalid mapTo name '%s'", mapTo);
       Con::errorf("TSShape::changeMaterial failed: Invalid mapTo name '%s'", mapTo);
@@ -1190,13 +1192,13 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia
 
 
    // Replace instances with the new material being traded in. Lets make sure that we only
    // Replace instances with the new material being traded in. Lets make sure that we only
    // target the specific targets per inst, this is actually doing more than we thought
    // target the specific targets per inst, this is actually doing more than we thought
-   delete object->getShape()->materialList->mMatInstList[matIndex];
-   object->getShape()->materialList->mMatInstList[matIndex] = newMat->createMatInstance();
+   delete shapeMaterialList->mMatInstList[matIndex];
+   shapeMaterialList->mMatInstList[matIndex] = newMat->createMatInstance();
 
 
    // Finish up preparing the material instances for rendering
    // Finish up preparing the material instances for rendering
    const GFXVertexFormat *flags = getGFXVertexFormat<GFXVertexPNTTB>();
    const GFXVertexFormat *flags = getGFXVertexFormat<GFXVertexPNTTB>();
    FeatureSet features = MATMGR->getDefaultFeatures();
    FeatureSet features = MATMGR->getDefaultFeatures();
-   object->getShape()->materialList->getMaterialInst(matIndex)->init( features, flags );
+   shapeMaterialList->getMaterialInst(matIndex)->init(features, flags);
 }
 }
 
 
 DefineEngineMethod( TSStatic, getModelFile, const char *, (),,
 DefineEngineMethod( TSStatic, getModelFile, const char *, (),,

+ 9 - 10
Engine/source/T3D/turret/turretShape.cpp

@@ -1059,9 +1059,9 @@ void TurretShape::writePacketData(GameConnection *connection, BitStream *stream)
 {
 {
    // Update client regardless of status flags.
    // Update client regardless of status flags.
    Parent::writePacketData(connection, stream);
    Parent::writePacketData(connection, stream);
-
-   stream->write(mRot.x);
-   stream->write(mRot.z);
+   
+   stream->writeSignedFloat(mRot.x / M_2PI_F, 7);
+   stream->writeSignedFloat(mRot.z / M_2PI_F, 7);
 }
 }
 
 
 void TurretShape::readPacketData(GameConnection *connection, BitStream *stream)
 void TurretShape::readPacketData(GameConnection *connection, BitStream *stream)
@@ -1069,9 +1069,8 @@ void TurretShape::readPacketData(GameConnection *connection, BitStream *stream)
    Parent::readPacketData(connection, stream);
    Parent::readPacketData(connection, stream);
 
 
    Point3F rot(0.0f, 0.0f, 0.0f);
    Point3F rot(0.0f, 0.0f, 0.0f);
-   stream->read(&rot.x);
-   stream->read(&rot.z);
-
+   rot.x = stream->readSignedFloat(7) * M_2PI_F;
+   rot.z = stream->readSignedFloat(7) * M_2PI_F;
    _setRotation(rot);
    _setRotation(rot);
 
 
    mTurretDelta.rot = rot;
    mTurretDelta.rot = rot;
@@ -1100,8 +1099,8 @@ U32 TurretShape::packUpdate(NetConnection *connection, U32 mask, BitStream *stre
 
 
    if (stream->writeFlag(mask & TurretUpdateMask))
    if (stream->writeFlag(mask & TurretUpdateMask))
    {
    {
-      stream->write(mRot.x);
-      stream->write(mRot.z);
+      stream->writeSignedFloat(mRot.x / M_2PI_F, 7);
+      stream->writeSignedFloat(mRot.z / M_2PI_F, 7);
       stream->write(allowManualRotation);
       stream->write(allowManualRotation);
       stream->write(allowManualFire);
       stream->write(allowManualFire);
    }
    }
@@ -1137,8 +1136,8 @@ void TurretShape::unpackUpdate(NetConnection *connection, BitStream *stream)
    if (stream->readFlag())
    if (stream->readFlag())
    {
    {
       Point3F rot(0.0f, 0.0f, 0.0f);
       Point3F rot(0.0f, 0.0f, 0.0f);
-      stream->read(&rot.x);
-      stream->read(&rot.z);
+      rot.x = stream->readSignedFloat(7) * M_2PI_F;
+      rot.z = stream->readSignedFloat(7) * M_2PI_F;
       _setRotation(rot);
       _setRotation(rot);
 
 
       // New delta for client side interpolation
       // New delta for client side interpolation

+ 3 - 0
Engine/source/T3D/vehicles/wheeledVehicle.cpp

@@ -1086,6 +1086,9 @@ void WheeledVehicle::updateForces(F32 dt)
    if (mJetting)
    if (mJetting)
       mRigid.force += by * mDataBlock->jetForce;
       mRigid.force += by * mDataBlock->jetForce;
 
 
+   // Add in force from physical zones...
+   mRigid.force += mAppliedForce;
+
    // Container drag & buoyancy
    // Container drag & buoyancy
    mRigid.force  += Point3F(0, 0, -mBuoyancy * sWheeledVehicleGravity * mRigid.mass);
    mRigid.force  += Point3F(0, 0, -mBuoyancy * sWheeledVehicleGravity * mRigid.mass);
    mRigid.force  -= mRigid.linVelocity * mDrag;
    mRigid.force  -= mRigid.linVelocity * mDrag;

+ 0 - 13
Engine/source/app/mainLoop.cpp

@@ -61,10 +61,6 @@
 // For the TickMs define... fix this for T2D...
 // For the TickMs define... fix this for T2D...
 #include "T3D/gameBase/processList.h"
 #include "T3D/gameBase/processList.h"
 
 
-#ifdef TORQUE_DEMO_PURCHASE
-#include "demo/pestTimer/pestTimer.h"
-#endif
-
 #ifdef TORQUE_ENABLE_VFS
 #ifdef TORQUE_ENABLE_VFS
 #include "platform/platformVFS.h"
 #include "platform/platformVFS.h"
 #endif
 #endif
@@ -309,10 +305,6 @@ void StandardMainLoop::init()
    // Hook in for UDP notification
    // Hook in for UDP notification
    Net::smPacketReceive.notify(GNet, &NetInterface::processPacketReceiveEvent);
    Net::smPacketReceive.notify(GNet, &NetInterface::processPacketReceiveEvent);
 
 
-   #ifdef TORQUE_DEMO_PURCHASE
-   PestTimerinit();
-   #endif
-
    #ifdef TORQUE_DEBUG_GUARD
    #ifdef TORQUE_DEBUG_GUARD
       Memory::flagCurrentAllocs( Memory::FLAG_Static );
       Memory::flagCurrentAllocs( Memory::FLAG_Static );
    #endif
    #endif
@@ -613,11 +605,6 @@ bool StandardMainLoop::doMainLoop()
       ThreadPool::processMainThreadWorkItems();
       ThreadPool::processMainThreadWorkItems();
       Sampler::endFrame();
       Sampler::endFrame();
       PROFILE_END_NAMED(MainLoop);
       PROFILE_END_NAMED(MainLoop);
-
-	  #ifdef TORQUE_DEMO_PURCHASE
-	  CheckTimer();
-	  CheckBlocker();
-	  #endif
    }
    }
    
    
    return keepRunning;
    return keepRunning;

+ 1 - 19
Engine/source/app/version.cpp

@@ -139,22 +139,4 @@ DefineConsoleFunction( getBuildString, const char*, (), , "Get the type of build
 #endif
 #endif
 }
 }
 
 
-ConsoleFunctionGroupEnd( CompileInformation );
-
-DefineConsoleFunction( isDemo, bool, (), , "")
-{
-#ifdef TORQUE_DEMO
-   return true;
-#else
-   return false;
-#endif
-}
-
-DefineConsoleFunction( isWebDemo, bool, (), , "")
-{
-#ifdef TORQUE_DEMO
-   return Platform::getWebDeployment();
-#else
-   return false;
-#endif
-}
+ConsoleFunctionGroupEnd( CompileInformation );

+ 1 - 1
Engine/source/collision/boxConvex.cpp

@@ -76,7 +76,7 @@ Point3F BoxConvex::getVertex(S32 v)
    return p;
    return p;
 }
 }
 
 
-inline bool isOnPlane(Point3F p,PlaneF& plane)
+inline bool isOnPlane(const Point3F& p,PlaneF& plane)
 {
 {
    F32 dist = mDot(plane,p) + plane.d;
    F32 dist = mDot(plane,p) + plane.d;
    return dist < 0.1 && dist > -0.1;
    return dist < 0.1 && dist > -0.1;

+ 1 - 1
Engine/source/console/arrayObject.cpp

@@ -103,7 +103,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void*
    ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
    ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
    ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
    ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
    
    
-   S32 result = dAtoi( Con::executef( (const char*)smCompareFunction, ea->value, eb->key ) );
+   S32 result = dAtoi(Con::executef((const char*)smCompareFunction, ea->key, eb->key));
    S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
    S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
    return ( smDecreasing ? -res : res );
    return ( smDecreasing ? -res : res );
 }
 }

+ 0 - 4
Engine/source/console/astNodes.cpp

@@ -258,7 +258,6 @@ void IfStmtNode::propagateSwitchExpr(ExprNode *left, bool string)
 
 
 U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
 U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
 {
 {
-   U32 start = ip;
    U32 endifIp, elseIp;
    U32 endifIp, elseIp;
    addBreakLine(codeStream);
    addBreakLine(codeStream);
    
    
@@ -340,7 +339,6 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
    addBreakLine(codeStream);
    addBreakLine(codeStream);
    codeStream.pushFixScope(true);
    codeStream.pushFixScope(true);
    
    
-   U32 start = ip;
    if(initExpr)
    if(initExpr)
       ip = initExpr->compile(codeStream, ip, TypeReqNone);
       ip = initExpr->compile(codeStream, ip, TypeReqNone);
 
 
@@ -1565,8 +1563,6 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
    
    
    CodeBlock::smInFunction = false;
    CodeBlock::smInFunction = false;
    
    
-   
-   U32 start = ip;
    codeStream.emit(OP_FUNC_DECL);
    codeStream.emit(OP_FUNC_DECL);
    codeStream.emitSTE(fnName);
    codeStream.emitSTE(fnName);
    codeStream.emitSTE(nameSpace);
    codeStream.emitSTE(nameSpace);

+ 5 - 4
Engine/source/console/compiledEval.cpp

@@ -435,7 +435,8 @@ static void setFieldComponent( SimObject* object, StringTableEntry field, const
 
 
 ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
 ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
 {
 {
-#ifdef TORQUE_DEBUG
+
+#ifdef TORQUE_VALIDATE_STACK
    U32 stackStart = STR.mStartStackSize;
    U32 stackStart = STR.mStartStackSize;
    U32 consoleStackStart = CSTK.mStackPos;
    U32 consoleStackStart = CSTK.mStackPos;
 #endif
 #endif
@@ -2245,9 +2246,9 @@ execFinished:
 
 
    decRefCount();
    decRefCount();
 
 
-#ifdef TORQUE_DEBUG
-   //AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
-   //AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
+#ifdef TORQUE_VALIDATE_STACK
+   AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
+   AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
 #endif
 #endif
 
 
    return returnValue;
    return returnValue;

+ 1 - 1
Engine/source/console/compiler.h

@@ -310,7 +310,7 @@ protected:
       U8 *data;       ///< Allocated data (size is BlockSize)
       U8 *data;       ///< Allocated data (size is BlockSize)
       U32 size;       ///< Bytes used in data
       U32 size;       ///< Bytes used in data
       CodeData *next; ///< Next block
       CodeData *next; ///< Next block
-   };
+   } CodeData;
    
    
    /// @name Emitted code
    /// @name Emitted code
    /// {
    /// {

+ 5 - 3
Engine/source/console/console.h

@@ -191,7 +191,7 @@ public:
    
    
    void cleanup()
    void cleanup()
    {
    {
-      if (bufferLen > 0)
+      if ((type <= TypeInternalString) && (bufferLen > 0))
       {
       {
          dFree(sval);
          dFree(sval);
          bufferLen = 0;
          bufferLen = 0;
@@ -201,6 +201,8 @@ public:
       ival = 0;
       ival = 0;
       fval = 0;
       fval = 0;
    }
    }
+   ConsoleValue(){ init(); };
+   ~ConsoleValue(){ cleanup(); };
 };
 };
 
 
 // Proxy class for console variables
 // Proxy class for console variables
@@ -1098,9 +1100,9 @@ struct ConsoleDocFragment
    static ConsoleDocFragment* smFirst;
    static ConsoleDocFragment* smFirst;
    
    
    ConsoleDocFragment( const char* text, const char* inClass = NULL, const char* definition = NULL )
    ConsoleDocFragment( const char* text, const char* inClass = NULL, const char* definition = NULL )
-      : mText( text ),
-        mClass( inClass ),
+      : mClass( inClass ),
         mDefinition( definition ),
         mDefinition( definition ),
+        mText( text ),
         mNext( smFirst )
         mNext( smFirst )
    {
    {
       smFirst = this;
       smFirst = this;

+ 2 - 5
Engine/source/console/consoleFunctions.cpp

@@ -34,10 +34,6 @@
 #include "core/util/journal/journal.h"
 #include "core/util/journal/journal.h"
 #include "core/util/uuid.h"
 #include "core/util/uuid.h"
 
 
-#ifdef TORQUE_DEMO_PURCHASE
-#include "gui/core/guiCanvas.h"
-#endif
-
 // This is a temporary hack to get tools using the library to
 // This is a temporary hack to get tools using the library to
 // link in this module which contains no other references.
 // link in this module which contains no other references.
 bool LinkConsoleFunctions = false;
 bool LinkConsoleFunctions = false;
@@ -480,7 +476,7 @@ DefineConsoleFunction( strreplace, const char*, ( const char* source, const char
       if(!scan)
       if(!scan)
       {
       {
          dStrcpy(ret + dstp, source + scanp);
          dStrcpy(ret + dstp, source + scanp);
-         break;
+         return ret;
       }
       }
       U32 len = scan - (source + scanp);
       U32 len = scan - (source + scanp);
       dStrncpy(ret + dstp, source + scanp, len);
       dStrncpy(ret + dstp, source + scanp, len);
@@ -1598,6 +1594,7 @@ DefineEngineFunction( gotoWebPage, void, ( const char* address ),,
 DefineEngineFunction( displaySplashWindow, bool, (const char* path), ("art/gui/splash.bmp"),
 DefineEngineFunction( displaySplashWindow, bool, (const char* path), ("art/gui/splash.bmp"),
    "Display a startup splash window suitable for showing while the engine still starts up.\n\n"
    "Display a startup splash window suitable for showing while the engine still starts up.\n\n"
    "@note This is currently only implemented on Windows.\n\n"
    "@note This is currently only implemented on Windows.\n\n"
+   "@param path	relative path to splash screen image to display.\n"
    "@return True if the splash window could be successfully initialized.\n\n"
    "@return True if the splash window could be successfully initialized.\n\n"
    "@ingroup Platform" )
    "@ingroup Platform" )
 {
 {

+ 2 - 1
Engine/source/console/consoleObject.cpp

@@ -847,12 +847,13 @@ DefineEngineFunction(linkNamespaces, bool, ( String childNSName, String parentNS
    
    
    Namespace *childNS = Namespace::find(childNSSTE);
    Namespace *childNS = Namespace::find(childNSSTE);
    Namespace *parentNS = Namespace::find(parentNSSTE);
    Namespace *parentNS = Namespace::find(parentNSSTE);
-   Namespace *currentParent = childNS->getParent();
    
    
    if (!childNS)
    if (!childNS)
    {
    {
       return false;
       return false;
    }
    }
+
+   Namespace *currentParent = childNS->getParent();
    
    
    // Link to new NS if applicable
    // Link to new NS if applicable
    
    

+ 12 - 15
Engine/source/console/consoleParser.cpp

@@ -50,24 +50,21 @@ bool addConsoleParser(char *ext, fnGetCurrentFile gcf, fnGetCurrentLine gcl, fnP
 	AssertFatal(ext && gcf && gcl && p && r, "AddConsoleParser called with one or more NULL arguments");
 	AssertFatal(ext && gcf && gcl && p && r, "AddConsoleParser called with one or more NULL arguments");
 
 
 	ConsoleParser * pParser = new ConsoleParser;
 	ConsoleParser * pParser = new ConsoleParser;
-	if(pParser != NULL)
-	{
-		pParser->ext = ext;
-		pParser->getCurrentFile = gcf;
-		pParser->getCurrentLine = gcl;
-		pParser->parse = p;
-		pParser->restart = r;
-		pParser->setScanBuffer = ssb;
 
 
-		if(def)
-			gDefaultParser = pParser;
+   pParser->ext = ext;
+   pParser->getCurrentFile = gcf;
+   pParser->getCurrentLine = gcl;
+   pParser->parse = p;
+   pParser->restart = r;
+   pParser->setScanBuffer = ssb;
 
 
-		pParser->next = gParserList;
-		gParserList = pParser;
+   if (def)
+      gDefaultParser = pParser;
 
 
-		return true;
-	}
-	return false;
+   pParser->next = gParserList;
+   gParserList = pParser;
+
+   return true;
 }
 }
 
 
 ConsoleParser * getParserForFile(const char *filename)
 ConsoleParser * getParserForFile(const char *filename)

+ 1 - 5
Engine/source/console/consoleTypes.h

@@ -48,11 +48,7 @@
 /// @{
 /// @{
 
 
 #ifndef Offset
 #ifndef Offset
-#if defined(TORQUE_COMPILER_GCC) && (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
-#define Offset(m,T) ((int)(&((T *)1)->m) - 1)
-#else
-#define Offset(x, cls) ((dsize_t)((const char *)&(((cls *)0)->x)-(const char *)0))
-#endif
+#define Offset(x, cls) offsetof(cls, x)
 #endif
 #endif
 
 
 class GFXShader;
 class GFXShader;

+ 8 - 0
Engine/source/console/dynamicTypes.h

@@ -318,6 +318,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
    DECLARE_ENUM( type ); \
    DECLARE_ENUM( type ); \
    DefineConsoleType( Type ## type, type );
    DefineConsoleType( Type ## type, type );
 
 
+#define DefineEnumType_R( type ) \
+   DECLARE_ENUM_R( type ); \
+   DefineConsoleType( Type ## type, type );
+
 #define _ConsoleEnumType( typeName, type, nativeType ) \
 #define _ConsoleEnumType( typeName, type, nativeType ) \
    S32 type; \
    S32 type; \
    ImplementConsoleTypeCasters( type, nativeType ) \
    ImplementConsoleTypeCasters( type, nativeType ) \
@@ -347,6 +351,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
    DECLARE_BITFIELD( type ); \
    DECLARE_BITFIELD( type ); \
    DefineConsoleType( Type ## type, type );
    DefineConsoleType( Type ## type, type );
 
 
+#define DefineBitfieldType_R( type ) \
+   DECLARE_BITFIELD_R( type ); \
+   DefineConsoleType( Type ## type, type );
+
 #define _ConsoleBitfieldType( typeName, type, nativeType ) \
 #define _ConsoleBitfieldType( typeName, type, nativeType ) \
    S32 type; \
    S32 type; \
    ImplementConsoleTypeCasters( type, nativeType ) \
    ImplementConsoleTypeCasters( type, nativeType ) \

+ 1 - 1
Engine/source/console/engineDoc.cpp

@@ -706,7 +706,7 @@ static bool dumpEngineDocs( const char *outputFile )
    // Dump pre-declarations for any groups we encountered
    // Dump pre-declarations for any groups we encountered
    // so that we don't have to explicitly define them.
    // so that we don't have to explicitly define them.
    HashTable<String,U32>::Iterator iter = smDocGroups.begin();
    HashTable<String,U32>::Iterator iter = smDocGroups.begin();
-   for ( ; iter != smDocGroups.end(); iter++ )
+   for (; iter != smDocGroups.end(); ++iter)
       stream.writeText( String::ToString( "/*! @addtogroup %s */\r\n\r\n", iter->key.c_str() ) );
       stream.writeText( String::ToString( "/*! @addtogroup %s */\r\n\r\n", iter->key.c_str() ) );
 
 
    return true;
    return true;

+ 4 - 0
Engine/source/console/engineFunctions.h

@@ -77,7 +77,11 @@ struct EngineFunctionDefaultArguments
 
 
 
 
 // Need byte-aligned packing for the default argument structures.
 // Need byte-aligned packing for the default argument structures.
+#ifdef _WIN64
+#pragma pack( push, 4 )
+#else
 #pragma pack( push, 1 )
 #pragma pack( push, 1 )
+#endif
    
    
 
 
 // Structure encapsulating default arguments to an engine API function.
 // Structure encapsulating default arguments to an engine API function.

+ 9 - 9
Engine/source/console/enginePrimitives.h

@@ -34,14 +34,14 @@
 
 
 
 
 
 
-DECLARE_PRIMITIVE( bool );
-DECLARE_PRIMITIVE( S8 );
-DECLARE_PRIMITIVE( U8 );
-DECLARE_PRIMITIVE( S32 );
-DECLARE_PRIMITIVE( U32 );
-DECLARE_PRIMITIVE( F32 );
-DECLARE_PRIMITIVE( F64 );
-DECLARE_PRIMITIVE( void* );
+DECLARE_PRIMITIVE_R( bool );
+DECLARE_PRIMITIVE_R(S8);
+DECLARE_PRIMITIVE_R(U8);
+DECLARE_PRIMITIVE_R(S32);
+DECLARE_PRIMITIVE_R(U32);
+DECLARE_PRIMITIVE_R(F32);
+DECLARE_PRIMITIVE_R(F64);
+DECLARE_PRIMITIVE_R(void*);
 
 
 
 
 //FIXME: this allows String to be used as a struct field type
 //FIXME: this allows String to be used as a struct field type
@@ -52,7 +52,7 @@ DECLARE_PRIMITIVE( void* );
 // are considered to be owned by the API layer itself.  The rule here is that such
 // are considered to be owned by the API layer itself.  The rule here is that such
 // a string is only valid until the next API call is made.  Usually, control layers
 // a string is only valid until the next API call is made.  Usually, control layers
 // will immediately copy and convert strings to their own string type.
 // will immediately copy and convert strings to their own string type.
-_DECLARE_TYPE( String );
+_DECLARE_TYPE_R(String);
 template<>
 template<>
 struct EngineTypeTraits< String > : public _EnginePrimitiveTypeTraits< String >
 struct EngineTypeTraits< String > : public _EnginePrimitiveTypeTraits< String >
 {
 {

+ 6 - 6
Engine/source/console/engineStructs.h

@@ -41,11 +41,11 @@ class ColorI;
 class ColorF;
 class ColorF;
 
 
 
 
-DECLARE_STRUCT( Vector< bool > );
-DECLARE_STRUCT( Vector< S32 > );
-DECLARE_STRUCT( Vector< F32 > );
-DECLARE_STRUCT( Torque::UUID );
-DECLARE_STRUCT( ColorI );
-DECLARE_STRUCT( ColorF );
+DECLARE_STRUCT_R(Vector< bool >);
+DECLARE_STRUCT_R(Vector< S32 >);
+DECLARE_STRUCT_R(Vector< F32 >);
+DECLARE_STRUCT_R(Torque::UUID);
+DECLARE_STRUCT_R(ColorI);
+DECLARE_STRUCT_R(ColorF);
 
 
 #endif // !_ENGINESTRUCTS_H_
 #endif // !_ENGINESTRUCTS_H_

+ 3 - 3
Engine/source/console/engineTypeInfo.h

@@ -44,7 +44,7 @@ enum EngineTypeKind
    EngineTypeKindClass           ///< Pointer to opaque EngineObject.
    EngineTypeKindClass           ///< Pointer to opaque EngineObject.
 };
 };
 
 
-DECLARE_ENUM( EngineTypeKind );
+DECLARE_ENUM_R( EngineTypeKind );
 
 
 /// Flags for an EngineTypeInfo.
 /// Flags for an EngineTypeInfo.
 enum EngineTypeFlags
 enum EngineTypeFlags
@@ -173,8 +173,8 @@ class EngineFieldTable
       /// Construct a field table from a NULL-terminated array of Field
       /// Construct a field table from a NULL-terminated array of Field
       /// records.
       /// records.
       EngineFieldTable( const Field* fields )
       EngineFieldTable( const Field* fields )
-         : mFields( fields ),
-           mNumFields( 0 )
+         : mNumFields( 0 ),
+           mFields( fields )
       {
       {
          while( fields[ mNumFields ].getName() )
          while( fields[ mNumFields ].getName() )
             mNumFields ++;
             mNumFields ++;

+ 47 - 1
Engine/source/console/engineTypes.h

@@ -416,6 +416,16 @@ namespace _Private {
 
 
 
 
 #define _DECLARE_TYPE( type )                                                                \
 #define _DECLARE_TYPE( type )                                                                \
+   template<> const EngineTypeInfo* TYPE< type >();                                          \
+   template<> struct _SCOPE< type > {                                                        \
+      EngineExportScope& operator()() const {                                                \
+         return *static_cast< EngineExportScope* >(                                          \
+            const_cast< EngineTypeInfo* >( ( TYPE< type >() ) )                              \
+         );                                                                                  \
+      }                                                                                      \
+   };
+
+#define _DECLARE_TYPE_R( type )                                                              \
    template<> const EngineTypeInfo* TYPE< type >();                                          \
    template<> const EngineTypeInfo* TYPE< type >();                                          \
    template<> struct _SCOPE< type > {                                                        \
    template<> struct _SCOPE< type > {                                                        \
       EngineExportScope& operator()() const {                                                \
       EngineExportScope& operator()() const {                                                \
@@ -432,22 +442,42 @@ namespace _Private {
    _DECLARE_TYPE( type )                                                                     \
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    template<>                                                                                \
    struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
    struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
+
+#define _DECLARE_PRIMITIVE_R( type )                                                         \
+   _DECLARE_TYPE_R( type )                                                                   \
+   template<>                                                                                \
+   struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
    
    
 #define _DECLARE_ENUM( type )                                                                \
 #define _DECLARE_ENUM( type )                                                                \
    _DECLARE_TYPE( type )                                                                     \
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    template<>                                                                                \
    struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
    struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
-   
+
+#define _DECLARE_ENUM_R( type )                                                              \
+   _DECLARE_TYPE_R( type )                                                                   \
+   template<>                                                                                \
+   struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
+
 #define _DECLARE_BITFIELD( type )                                                            \
 #define _DECLARE_BITFIELD( type )                                                            \
    _DECLARE_TYPE( type )                                                                     \
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    template<>                                                                                \
    struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
    struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
 
 
+#define _DECLARE_BITFIELD_R( type )                                                            \
+   _DECLARE_TYPE_R( type )                                                                     \
+   template<>                                                                                \
+   struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
+
+
 #define _DECLARE_STRUCT( type )                                                              \
 #define _DECLARE_STRUCT( type )                                                              \
    _DECLARE_TYPE( type )                                                                     \
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    template<>                                                                                \
    struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
    struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
 
 
+#define _DECLARE_STRUCT_R( type )                                                            \
+   _DECLARE_TYPE_R( type )                                                                   \
+   template<>                                                                                \
+   struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
 
 
 #define _IMPLEMENT_TYPE( type, exportName )        \
 #define _IMPLEMENT_TYPE( type, exportName )        \
    template<>                                      \
    template<>                                      \
@@ -524,6 +554,10 @@ namespace _Private {
 #define DECLARE_PRIMITIVE( type ) \
 #define DECLARE_PRIMITIVE( type ) \
    _DECLARE_PRIMITIVE( type )
    _DECLARE_PRIMITIVE( type )
 
 
+///
+#define DECLARE_PRIMITIVE_R( type ) \
+   _DECLARE_PRIMITIVE_R( type )
+
 ///
 ///
 #define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \
 #define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \
    _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc )
    _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc )
@@ -531,11 +565,19 @@ namespace _Private {
 ///
 ///
 #define DECLARE_ENUM( type ) \
 #define DECLARE_ENUM( type ) \
    _DECLARE_ENUM( type )
    _DECLARE_ENUM( type )
+
+///
+#define DECLARE_ENUM_R( type ) \
+   _DECLARE_ENUM_R( type )
    
    
 ///
 ///
 #define DECLARE_BITFIELD( type ) \
 #define DECLARE_BITFIELD( type ) \
    _DECLARE_BITFIELD( type )
    _DECLARE_BITFIELD( type )
 
 
+///
+#define DECLARE_BITFIELD_R( type ) \
+   _DECLARE_BITFIELD_R( type )
+
 ///
 ///
 #define IMPLEMENT_ENUM( type, exportName, scope, doc ) \
 #define IMPLEMENT_ENUM( type, exportName, scope, doc ) \
    _IMPLEMENT_ENUM( type, exportName, scope, doc )
    _IMPLEMENT_ENUM( type, exportName, scope, doc )
@@ -556,6 +598,10 @@ namespace _Private {
 #define DECLARE_STRUCT( type ) \
 #define DECLARE_STRUCT( type ) \
    _DECLARE_STRUCT( type )
    _DECLARE_STRUCT( type )
 
 
+///
+#define DECLARE_STRUCT_R( type ) \
+   _DECLARE_STRUCT_R( type )
+
 ///
 ///
 #define IMPLEMENT_STRUCT( type, exportName, scope, doc ) \
 #define IMPLEMENT_STRUCT( type, exportName, scope, doc ) \
    _IMPLEMENT_STRUCT( type, exportName, scope, doc )
    _IMPLEMENT_STRUCT( type, exportName, scope, doc )

+ 1 - 1
Engine/source/console/sim.h

@@ -64,7 +64,7 @@ typedef U32 SimObjectId;
 enum SimObjectsConstants
 enum SimObjectsConstants
 {
 {
    DataBlockObjectIdFirst = 3,
    DataBlockObjectIdFirst = 3,
-   DataBlockObjectIdBitSize = 10,
+   DataBlockObjectIdBitSize = 14,
    DataBlockObjectIdLast = DataBlockObjectIdFirst + (1 << DataBlockObjectIdBitSize) - 1,
    DataBlockObjectIdLast = DataBlockObjectIdFirst + (1 << DataBlockObjectIdBitSize) - 1,
 
 
    MessageObjectIdFirst = DataBlockObjectIdLast + 1,
    MessageObjectIdFirst = DataBlockObjectIdLast + 1,

+ 4 - 4
Engine/source/console/simObjectRef.h

@@ -44,9 +44,9 @@ public:
    static S32 _smTypeId;
    static S32 _smTypeId;
 
 
    SimObjectRef()
    SimObjectRef()
-      : mId( 0 ),
-        mObject( NULL ),
-        mName( "" )
+      : mName( "" ),
+        mId( 0 ),
+        mObject( NULL )
    {
    {
    }
    }
    
    
@@ -178,4 +178,4 @@ public:
 };
 };
 
 
 
 
-#endif // _SIMOBJECTREF_H_
+#endif // _SIMOBJECTREF_H_

+ 1 - 1
Engine/source/console/typeValidators.cpp

@@ -101,7 +101,7 @@ void Point3NormalizeValidator::validateType(SimObject *object, void *typePtr)
 namespace CommonValidators
 namespace CommonValidators
 {
 {
    FRangeValidator PositiveFloat(0.0f, F32_MAX);
    FRangeValidator PositiveFloat(0.0f, F32_MAX);
-   FRangeValidator PositiveNonZeroFloat(F32( POINT_EPSILON ) , F32_MAX);
+   FRangeValidator PositiveNonZeroFloat((F32)POINT_EPSILON, F32_MAX);
    FRangeValidator NormalizedFloat(0.0f, 1.0f);
    FRangeValidator NormalizedFloat(0.0f, 1.0f);
    Point3NormalizeValidator NormalizedPoint3(1.0f);
    Point3NormalizeValidator NormalizedPoint3(1.0f);
 };
 };

+ 6 - 5
Engine/source/core/module.h

@@ -79,9 +79,9 @@ class Module
          
          
          Dependency( Mode mode, DependencyType type, Module* parentModule, const char* moduleName )
          Dependency( Mode mode, DependencyType type, Module* parentModule, const char* moduleName )
             : mType( type ),
             : mType( type ),
-              mNext( mode == ModeInitialize ? parentModule->mInitDependencies : parentModule->mShutdownDependencies ),
               mModuleName( moduleName ),
               mModuleName( moduleName ),
-              mModule( NULL )
+              mModule( NULL ),
+              mNext( mode == ModeInitialize ? parentModule->mInitDependencies : parentModule->mShutdownDependencies )
          {
          {
             if( mode == ModeInitialize )
             if( mode == ModeInitialize )
                parentModule->mInitDependencies = this;
                parentModule->mInitDependencies = this;
@@ -141,11 +141,12 @@ class Module
       }
       }
             
             
       Module()
       Module()
-         : mNext( smFirst ),
+         : mIsInitialized( false ),
+           mNext( smFirst ),
            mInitDependencies( NULL ),
            mInitDependencies( NULL ),
            mShutdownDependencies( NULL ),
            mShutdownDependencies( NULL ),
-           mOverrides( NULL ),
-           mIsInitialized( false )
+           mOverrides( NULL )
+
       {
       {
          smFirst = this;
          smFirst = this;
       }
       }

+ 1 - 1
Engine/source/core/stream/bitStream.cpp

@@ -336,7 +336,7 @@ S32 BitStream::readInt(S32 bitCount)
 
 
 void BitStream::writeInt(S32 val, S32 bitCount)
 void BitStream::writeInt(S32 val, S32 bitCount)
 {
 {
-   AssertWarn((bitCount == 32) || ((val >> bitCount) == 0), "BitStream::writeInt: value out of range");
+   AssertFatal((bitCount == 32) || ((val >> bitCount) == 0), avar("BitStream::writeInt: value out of range: %i/%i (%i bits)", val, 1 << bitCount, bitCount));
 
 
    val = convertHostToLEndian(val);
    val = convertHostToLEndian(val);
    writeBits(bitCount, &val);
    writeBits(bitCount, &val);

+ 5 - 8
Engine/source/core/stream/fileStream.cpp

@@ -39,15 +39,12 @@ FileStream *FileStream::createAndOpen(const String &inFileName, Torque::FS::File
 {
 {
    FileStream  *newStream = new FileStream;
    FileStream  *newStream = new FileStream;
 
 
-   if ( newStream )
-   {
-      bool success = newStream->open( inFileName, inMode );
+   bool success = newStream->open( inFileName, inMode );
 
 
-      if ( !success )
-      {
-         delete newStream;
-         newStream = NULL;
-      }
+   if ( !success )
+   {
+      delete newStream;
+      newStream = NULL;
    }
    }
 
 
    return newStream;
    return newStream;

+ 5 - 3
Engine/source/core/strings/stringFunctions.h

@@ -36,10 +36,12 @@
 // These standard functions are not defined on Win32 and other Microsoft platforms...
 // These standard functions are not defined on Win32 and other Microsoft platforms...
 #define strcasecmp   _stricmp
 #define strcasecmp   _stricmp
 #define strncasecmp  _strnicmp
 #define strncasecmp  _strnicmp
-#endif
-#if (_MSC_VER < 1800) && (defined(TORQUE_OS_WIN) || defined(TORQUE_OS_XBOX) || defined(TORQUE_OS_XENON))
+
+#if _MSC_VER < 1800
 #define strtof       (float)strtod
 #define strtof       (float)strtod
-#endif
+#endif // _MSC_VER < 1800
+
+#endif // defined(TORQUE_OS_WIN) || defined(TORQUE_OS_XBOX) || defined(TORQUE_OS_XENON)
 
 
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------

+ 2 - 3
Engine/source/core/util/FastDelegate.h

@@ -47,10 +47,9 @@
 
 
 #ifndef FASTDELEGATE_H
 #ifndef FASTDELEGATE_H
 #define FASTDELEGATE_H
 #define FASTDELEGATE_H
-#if _MSC_VER > 1000
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
 #pragma once
 #pragma once
-#endif // _MSC_VER > 1000
-
+#endif // defined(_MSC_VER) && (_MSC_VER > 1000)
 
 
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 //						Configuration options
 //						Configuration options

+ 1 - 1
Engine/source/core/util/rawData.h

@@ -58,7 +58,7 @@ class RawDataT
       }
       }
 
 
       RawDataT( T* data, U32 size, bool ownMemory = false )
       RawDataT( T* data, U32 size, bool ownMemory = false )
-         : data( data ), size( size ), ownMemory( ownMemory ) {}
+         : ownMemory( ownMemory ), data( data ), size( size ) {}
 
 
       RawDataT(const ThisType& rd)
       RawDataT(const ThisType& rd)
       {
       {

+ 5 - 1
Engine/source/core/util/str.cpp

@@ -567,7 +567,6 @@ String::String(const StringChar *str, SizeType len)
    PROFILE_SCOPE(String_char_len_constructor);
    PROFILE_SCOPE(String_char_len_constructor);
    if (str && *str && len!=0)
    if (str && *str && len!=0)
    {
    {
-      AssertFatal(len<=dStrlen(str), "String::String: string too short");
       _string = new ( len ) StringData( str );
       _string = new ( len ) StringData( str );
    }
    }
    else
    else
@@ -657,6 +656,11 @@ bool String::isEmpty() const
    return ( _string == StringData::Empty() );
    return ( _string == StringData::Empty() );
 }
 }
 
 
+bool String::isEmpty(const char* str)
+{
+	return str == 0 || str[0] == '\0';
+}
+
 bool String::isShared() const
 bool String::isShared() const
 {
 {
    return _string->isShared();
    return _string->isShared();

+ 3 - 3
Engine/source/core/util/str.h

@@ -62,7 +62,7 @@ public:
    String();
    String();
    String(const String &str);
    String(const String &str);
    String(const StringChar *str);
    String(const StringChar *str);
-   String(const StringChar *str, SizeType size);
+   String(const StringChar *str, SizeType size); ///< Copy from raw data
    String(const UTF16 *str);
    String(const UTF16 *str);
    ~String();
    ~String();
 
 
@@ -74,6 +74,7 @@ public:
    SizeType size() const;     ///< Returns the length of the string in bytes including the NULL terminator.
    SizeType size() const;     ///< Returns the length of the string in bytes including the NULL terminator.
    SizeType numChars() const; ///< Returns the length of the string in characters.
    SizeType numChars() const; ///< Returns the length of the string in characters.
    bool     isEmpty() const;  ///< Is this an empty string [""]?
    bool     isEmpty() const;  ///< Is this an empty string [""]?
+   static bool isEmpty(const char*); // is the input empty?
    bool     isNotEmpty() const { return !isEmpty(); }  ///< Is this not an empty string [""]?
    bool     isNotEmpty() const { return !isEmpty(); }  ///< Is this not an empty string [""]?
 
 
    /// Erases all characters in a string.
    /// Erases all characters in a string.
@@ -292,11 +293,10 @@ private:
    // causes an ambiguous cast compile error.  Making it private is simply
    // causes an ambiguous cast compile error.  Making it private is simply
    // more insurance that it isn't used on different compilers.
    // more insurance that it isn't used on different compilers.
    // NOTE: disable on GCC since it causes hyper casting to U32 on gcc.
    // NOTE: disable on GCC since it causes hyper casting to U32 on gcc.
-#ifndef TORQUE_COMPILER_GCC
+#if !defined(TORQUE_COMPILER_GCC) && !defined(__clang__)
    operator const bool() const { return false; }
    operator const bool() const { return false; }
 #endif
 #endif
 
 
-
    static void copy(StringChar *dst, const StringChar *src, U32 size);
    static void copy(StringChar *dst, const StringChar *src, U32 size);
 
 
    StringData   *_string;
    StringData   *_string;

+ 1 - 1
Engine/source/core/util/tUnmanagedVector.h

@@ -45,7 +45,7 @@ class UnmanagedVector
       UnmanagedVector()
       UnmanagedVector()
          : mCount( 0 ), mArray( NULL ) {}
          : mCount( 0 ), mArray( NULL ) {}
       UnmanagedVector( T* array, U32 count )
       UnmanagedVector( T* array, U32 count )
-         : mArray( array ), mCount( count ) {}
+         : mCount( count ), mArray( array ) {}
 
 
       U32 size() const { return mCount; }
       U32 size() const { return mCount; }
       bool empty() const { return ( mCount == 0 ); }
       bool empty() const { return ( mCount == 0 ); }

+ 2 - 2
Engine/source/core/util/tVector.h

@@ -684,13 +684,13 @@ template<class T> inline void Vector<T>::pop_back()
 
 
 template<class T> inline T& Vector<T>::operator[](U32 index)
 template<class T> inline T& Vector<T>::operator[](U32 index)
 {
 {
-   AssertFatal(index < mElementCount, "Vector<T>::operator[] - out of bounds array access!");
+   AssertFatal(index < mElementCount, avar("Vector<T>::operator[%i/%i] - out of bounds array access!", index, mElementCount));
    return mArray[index];
    return mArray[index];
 }
 }
 
 
 template<class T> inline const T& Vector<T>::operator[](U32 index) const
 template<class T> inline const T& Vector<T>::operator[](U32 index) const
 {
 {
-   AssertFatal(index < mElementCount, "Vector<T>::operator[] - out of bounds array access!");
+   AssertFatal(index < mElementCount, avar("Vector<T>::operator[%i/%i] - out of bounds array access!", index, mElementCount));
    return mArray[index];
    return mArray[index];
 }
 }
 
 

+ 1 - 1
Engine/source/environment/editors/guiMeshRoadEditorCtrl.cpp

@@ -1091,7 +1091,7 @@ F32 GuiMeshRoadEditorCtrl::getNodeDepth()
    return 0.0f;
    return 0.0f;
 }
 }
 
 
-void GuiMeshRoadEditorCtrl::setNodePosition( Point3F pos )
+void GuiMeshRoadEditorCtrl::setNodePosition(const Point3F& pos)
 {
 {
    if ( mSelRoad && mSelNode != -1 )
    if ( mSelRoad && mSelNode != -1 )
    {
    {

+ 1 - 1
Engine/source/environment/editors/guiMeshRoadEditorCtrl.h

@@ -100,7 +100,7 @@ class GuiMeshRoadEditorCtrl : public EditTSCtrl
       void setNodeDepth( F32 depth );
       void setNodeDepth( F32 depth );
 		
 		
 		Point3F getNodePosition();
 		Point3F getNodePosition();
-		void setNodePosition( Point3F pos );
+      void setNodePosition(const Point3F& pos);
 
 
       VectorF getNodeNormal();
       VectorF getNodeNormal();
       void setNodeNormal( const VectorF &normal );
       void setNodeNormal( const VectorF &normal );

+ 1 - 1
Engine/source/environment/editors/guiRiverEditorCtrl.cpp

@@ -1235,7 +1235,7 @@ F32 GuiRiverEditorCtrl::getNodeDepth()
    return 0.0f;
    return 0.0f;
 }
 }
 
 
-void GuiRiverEditorCtrl::setNodePosition( Point3F pos )
+void GuiRiverEditorCtrl::setNodePosition(const Point3F& pos)
 {
 {
    if ( mSelRiver && mSelNode != -1 )
    if ( mSelRiver && mSelNode != -1 )
    {
    {

+ 1 - 1
Engine/source/environment/editors/guiRiverEditorCtrl.h

@@ -110,7 +110,7 @@ class GuiRiverEditorCtrl : public EditTSCtrl
       void setNodeDepth( F32 depth );
       void setNodeDepth( F32 depth );
 
 
 		Point3F getNodePosition();
 		Point3F getNodePosition();
-		void setNodePosition( Point3F pos );
+      void setNodePosition(const Point3F& pos);
 
 
 		VectorF getNodeNormal();
 		VectorF getNodeNormal();
       void setNodeNormal( const VectorF &normal );
       void setNodeNormal( const VectorF &normal );

+ 1 - 1
Engine/source/environment/editors/guiRoadEditorCtrl.cpp

@@ -979,7 +979,7 @@ F32 GuiRoadEditorCtrl::getNodeWidth()
    return 0.0f;   
    return 0.0f;   
 }
 }
 
 
-void GuiRoadEditorCtrl::setNodePosition( Point3F pos )
+void GuiRoadEditorCtrl::setNodePosition(const Point3F& pos)
 {
 {
    if ( mSelRoad && mSelNode != -1 )
    if ( mSelRoad && mSelNode != -1 )
    {
    {

+ 1 - 1
Engine/source/environment/editors/guiRoadEditorCtrl.h

@@ -97,7 +97,7 @@ class GuiRoadEditorCtrl : public EditTSCtrl
       void setNodeWidth( F32 width );
       void setNodeWidth( F32 width );
 
 
 		Point3F getNodePosition();
 		Point3F getNodePosition();
-		void setNodePosition( Point3F pos );
+      void setNodePosition(const Point3F& pos);
 
 
       void setTextureFile( StringTableEntry file );
       void setTextureFile( StringTableEntry file );
 	
 	

+ 5 - 4
Engine/source/environment/scatterSky.cpp

@@ -637,12 +637,13 @@ void ScatterSky::prepRenderImage( SceneRenderState *state )
       return;
       return;
 
 
    // Regular sky render instance.
    // Regular sky render instance.
-   ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
+   RenderPassManager* renderPass = state->getRenderPass();
+   ObjectRenderInst *ri = renderPass->allocInst<ObjectRenderInst>();
    ri->renderDelegate.bind( this, &ScatterSky::_render );
    ri->renderDelegate.bind( this, &ScatterSky::_render );
    ri->type = RenderPassManager::RIT_Sky;
    ri->type = RenderPassManager::RIT_Sky;
    ri->defaultKey = 10;
    ri->defaultKey = 10;
    ri->defaultKey2 = 0;
    ri->defaultKey2 = 0;
-   state->getRenderPass()->addInst( ri );
+   renderPass->addInst(ri);
 
 
    // Debug render instance.
    // Debug render instance.
    /*
    /*
@@ -685,13 +686,13 @@ void ScatterSky::prepRenderImage( SceneRenderState *state )
       mMatrixSet->setSceneProjection(GFX->getProjectionMatrix());
       mMatrixSet->setSceneProjection(GFX->getProjectionMatrix());
       mMatrixSet->setWorld(GFX->getWorldMatrix());
       mMatrixSet->setWorld(GFX->getWorldMatrix());
 
 
-      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
+      ObjectRenderInst *ri = renderPass->allocInst<ObjectRenderInst>();
       ri->renderDelegate.bind( this, &ScatterSky::_renderMoon );
       ri->renderDelegate.bind( this, &ScatterSky::_renderMoon );
       ri->type = RenderPassManager::RIT_Sky;
       ri->type = RenderPassManager::RIT_Sky;
       // Render after sky objects and before CloudLayer!
       // Render after sky objects and before CloudLayer!
       ri->defaultKey = 5;
       ri->defaultKey = 5;
       ri->defaultKey2 = 0;
       ri->defaultKey2 = 0;
-      state->getRenderPass()->addInst( ri );
+      renderPass->addInst(ri);
    }
    }
 }
 }
 
 

+ 6 - 5
Engine/source/forest/editor/forestSelectionTool.cpp

@@ -56,7 +56,7 @@ Point3F Selection<ForestItem>::getOrigin()
 
 
    Selection<ForestItem>::iterator itr = begin();
    Selection<ForestItem>::iterator itr = begin();
 
 
-   for ( ; itr != end(); itr++ )
+   for (; itr != end(); ++itr)
    {
    {
       const MatrixF &mat = itr->getTransform();
       const MatrixF &mat = itr->getTransform();
       Point3F wPos;
       Point3F wPos;
@@ -450,10 +450,11 @@ void ForestSelectionTool::onRender2D()
       F32 hscale = wwidth * 2 / F32(mEditor->getWidth());
       F32 hscale = wwidth * 2 / F32(mEditor->getWidth());
       F32 vscale = wheight * 2 / F32(mEditor->getHeight());
       F32 vscale = wheight * 2 / F32(mEditor->getHeight());
 
 
-      F32 left = (mDragRect.point.x - mEditor->getPosition().x) * hscale - wwidth;
-      F32 right = (mDragRect.point.x - mEditor->getPosition().x + mDragRect.extent.x) * hscale - wwidth;
-      F32 top = wheight - vscale * (mDragRect.point.y - mEditor->getPosition().y);
-      F32 bottom = wheight - vscale * (mDragRect.point.y - mEditor->getPosition().y + mDragRect.extent.y);
+      Point2I editorPosition = mEditor->getPosition();
+      F32 left = (mDragRect.point.x - editorPosition.x) * hscale - wwidth;
+      F32 right = (mDragRect.point.x - editorPosition.x + mDragRect.extent.x) * hscale - wwidth;
+      F32 top = wheight - vscale * (mDragRect.point.y - editorPosition.y);
+      F32 bottom = wheight - vscale * (mDragRect.point.y - editorPosition.y + mDragRect.extent.y);
       gDragFrustum.set(lastCameraQuery.ortho, left, right, top, bottom, lastCameraQuery.nearPlane, lastCameraQuery.farPlane, lastCameraQuery.cameraMatrix );
       gDragFrustum.set(lastCameraQuery.ortho, left, right, top, bottom, lastCameraQuery.nearPlane, lastCameraQuery.farPlane, lastCameraQuery.cameraMatrix );
 
 
       mForest->getData()->getItems( gDragFrustum, &mDragSelection );      
       mForest->getData()->getItems( gDragFrustum, &mDragSelection );      

+ 1 - 1
Engine/source/forest/forest.cpp

@@ -354,7 +354,7 @@ void Forest::createNewFile()
 
 
 void Forest::saveDataFile( const char *path )
 void Forest::saveDataFile( const char *path )
 {
 {
-   if ( path )
+   if ( path && !String::isEmpty(path))
       mDataFileName = StringTable->insert( path );
       mDataFileName = StringTable->insert( path );
 
 
    if ( mData )
    if ( mData )

+ 1 - 1
Engine/source/forest/forestCollision.cpp

@@ -355,7 +355,7 @@ bool ForestData::castRay( const Point3F &start, const Point3F &end, RayInfo *out
    shortest.t = F32_MAX;
    shortest.t = F32_MAX;
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
    {
    {
       if ( iter->value->castRay( start, end, outInfo, rendered ) )
       if ( iter->value->castRay( start, end, outInfo, rendered ) )
       {
       {

+ 12 - 12
Engine/source/forest/forestDataFile.cpp

@@ -77,7 +77,7 @@ void ForestData::clear()
    // clean up its sub-cells in its destructor.   
    // clean up its sub-cells in its destructor.   
 
 
    BucketTable::Iterator iter = mBuckets.begin();
    BucketTable::Iterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ ) delete iter->value;
+   for (; iter != mBuckets.end(); ++iter) delete iter->value;
    mBuckets.clear();
    mBuckets.clear();
 
 
    mIsDirty = true;
    mIsDirty = true;
@@ -408,7 +408,7 @@ const ForestItem& ForestData::findItem( ForestItemKey key ) const
 
 
    Vector<const ForestCell*> stack;
    Vector<const ForestCell*> stack;
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
       stack.push_back( iter->value );
 
 
    // Now loop till we run out of cells.
    // Now loop till we run out of cells.
@@ -444,7 +444,7 @@ U32 ForestData::getItems( Vector<ForestItem> *outItems ) const
    U32 count = 0;
    U32 count = 0;
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
       stack.push_back( iter->value );
 
 
    // Now loop till we run out of cells.
    // Now loop till we run out of cells.
@@ -520,7 +520,7 @@ U32 ForestData::getItems( const Box3F &box, Vector<ForestItem> *outItems ) const
    U32 count = 0;
    U32 count = 0;
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
       stack.push_back( iter->value );
 
 
    // Now loop till we run out of cells.
    // Now loop till we run out of cells.
@@ -571,7 +571,7 @@ U32 ForestData::getItems( const Point3F &point, F32 radius, Vector<ForestItem> *
    U32 count = 0;
    U32 count = 0;
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
          stack.push_back( iter->value );
          stack.push_back( iter->value );
 
 
    const F32 radiusSq = radius * radius;
    const F32 radiusSq = radius * radius;
@@ -629,7 +629,7 @@ U32 ForestData::getItems( const Point2F &point, F32 radius, Vector<ForestItem> *
    U32 count = 0;
    U32 count = 0;
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
          stack.push_back( iter->value );
          stack.push_back( iter->value );
 
 
    const F32 radiusSq = radius * radius;
    const F32 radiusSq = radius * radius;
@@ -686,7 +686,7 @@ U32 ForestData::getItems( const ForestItemData *data, Vector<ForestItem> *outIte
    U32 count = 0;
    U32 count = 0;
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
       stack.push_back( iter->value );
 
 
    // Now loop till we run out of cells.
    // Now loop till we run out of cells.
@@ -724,7 +724,7 @@ void ForestData::getCells( const Frustum &frustum, Vector<ForestCell*> *outCells
    PROFILE_SCOPE( ForestData_getCells_frustum );
    PROFILE_SCOPE( ForestData_getCells_frustum );
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
    {
    {
       if ( !frustum.isCulled( iter->value->getBounds() ) )
       if ( !frustum.isCulled( iter->value->getBounds() ) )
          outCells->push_back( iter->value );
          outCells->push_back( iter->value );
@@ -736,7 +736,7 @@ void ForestData::getCells( Vector<ForestCell*> *outCells ) const
    PROFILE_SCOPE( ForestData_getCells_nofrustum );
    PROFILE_SCOPE( ForestData_getCells_nofrustum );
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )         
+   for (; iter != mBuckets.end(); ++iter)
       outCells->push_back( iter->value );
       outCells->push_back( iter->value );
 }
 }
 
 
@@ -746,7 +746,7 @@ U32 ForestData::getDatablocks( Vector<ForestItemData*> *outVector ) const
    U32 count = 0;
    U32 count = 0;
 
 
    BucketTable::ConstIterator iter = mBuckets.begin();
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
       stack.push_back( iter->value );
 
 
    // Now loop till we run out of cells.
    // Now loop till we run out of cells.
@@ -786,7 +786,7 @@ void ForestData::clearPhysicsRep( Forest *forest )
    Vector<ForestCell*> stack;
    Vector<ForestCell*> stack;
 
 
    BucketTable::Iterator iter = mBuckets.begin();
    BucketTable::Iterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
       stack.push_back( iter->value );
 
 
    // Now loop till we run out of cells.
    // Now loop till we run out of cells.
@@ -812,7 +812,7 @@ void ForestData::buildPhysicsRep( Forest *forest )
    Vector<ForestCell*> stack;
    Vector<ForestCell*> stack;
 
 
    BucketTable::Iterator iter = mBuckets.begin();
    BucketTable::Iterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
       stack.push_back( iter->value );
 
 
    // Now loop till we run out of cells.
    // Now loop till we run out of cells.

+ 2 - 2
Engine/source/forest/forestWindEmitter.cpp

@@ -521,8 +521,8 @@ void ForestWindEmitter::_renderEmitterInfo( ObjectRenderInst *ri, SceneRenderSta
    {
    {
       // If the camera is close to the sphere, shrink the sphere so it remains visible.
       // If the camera is close to the sphere, shrink the sphere so it remains visible.
       GameConnection* gc = GameConnection::getConnectionToServer();
       GameConnection* gc = GameConnection::getConnectionToServer();
-      GameBase* gb;
-      if ( gc && (gb = gc->getCameraObject()) )
+      GameBase *gb = gc ? gc->getCameraObject() : NULL;
+      if (gb)
       {
       {
          F32 camDist = (gb->getPosition() - getPosition()).len();
          F32 camDist = (gb->getPosition() - getPosition()).len();
          if ( camDist < mWindRadius )
          if ( camDist < mWindRadius )

+ 2 - 2
Engine/source/forest/forestWindMgr.cpp

@@ -65,7 +65,7 @@ ForestWindMgr::ForestWindMgr()
 ForestWindMgr::~ForestWindMgr()
 ForestWindMgr::~ForestWindMgr()
 {
 {
    IdToWindMap::Iterator sourceIter = mSources->begin();
    IdToWindMap::Iterator sourceIter = mSources->begin();
-   for( ; sourceIter != mSources->end(); sourceIter++ )      
+   for (; sourceIter != mSources->end(); ++sourceIter)
       delete (*sourceIter).value;
       delete (*sourceIter).value;
 
 
    delete mSources;
    delete mSources;
@@ -185,7 +185,7 @@ void ForestWindMgr::processTick()
       PROFILE_SCOPE( ForestWindMgr_AdvanceTime_Cleanup );
       PROFILE_SCOPE( ForestWindMgr_AdvanceTime_Cleanup );
 
 
       IdToWindMap::Iterator sourceIter = mPrevSources->begin();
       IdToWindMap::Iterator sourceIter = mPrevSources->begin();
-      for( ; sourceIter != mPrevSources->end(); sourceIter++ )
+      for (; sourceIter != mPrevSources->end(); ++sourceIter)
       {
       {
          ForestWindAccumulator *accum = (*sourceIter).value;
          ForestWindAccumulator *accum = (*sourceIter).value;
 
 

+ 5 - 6
Engine/source/gfx/D3D9/gfxD3D9Device.cpp

@@ -695,9 +695,9 @@ GFXShader* GFXD3D9Device::createShader()
    return shader;
    return shader;
 }
 }
 
 
-void GFXD3D9Device::disableShaders()
+void GFXD3D9Device::disableShaders(bool force)
 {
 {
-   setShader( NULL );
+   setShader( NULL, force );
    setShaderConstBuffer( NULL );
    setShaderConstBuffer( NULL );
 }
 }
 
 
@@ -706,25 +706,24 @@ void GFXD3D9Device::disableShaders()
 //              and to make sure redundant shader states are not being
 //              and to make sure redundant shader states are not being
 //              sent to the card.
 //              sent to the card.
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void GFXD3D9Device::setShader( GFXShader *shader )
+void GFXD3D9Device::setShader( GFXShader *shader, bool force )
 {
 {
    GFXD3D9Shader *d3dShader = static_cast<GFXD3D9Shader*>( shader );
    GFXD3D9Shader *d3dShader = static_cast<GFXD3D9Shader*>( shader );
 
 
    IDirect3DPixelShader9 *pixShader = ( d3dShader != NULL ? d3dShader->mPixShader : NULL );
    IDirect3DPixelShader9 *pixShader = ( d3dShader != NULL ? d3dShader->mPixShader : NULL );
    IDirect3DVertexShader9 *vertShader = ( d3dShader ? d3dShader->mVertShader : NULL );
    IDirect3DVertexShader9 *vertShader = ( d3dShader ? d3dShader->mVertShader : NULL );
 
 
-   if( pixShader != mLastPixShader )
+   if( pixShader != mLastPixShader || force )
    {
    {
       mD3DDevice->SetPixelShader( pixShader );
       mD3DDevice->SetPixelShader( pixShader );
       mLastPixShader = pixShader;
       mLastPixShader = pixShader;
    }
    }
 
 
-   if( vertShader != mLastVertShader )
+   if( vertShader != mLastVertShader || force )
    {
    {
       mD3DDevice->SetVertexShader( vertShader );
       mD3DDevice->SetVertexShader( vertShader );
       mLastVertShader = vertShader;
       mLastVertShader = vertShader;
    }
    }
-
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------

+ 3 - 3
Engine/source/gfx/D3D9/gfxD3D9Device.h

@@ -76,7 +76,7 @@ inline void D3D9Assert( HRESULT hr, const char *info )
 
 
 // Typedefs
 // Typedefs
 #define D3DX_FUNCTION(fn_name, fn_return, fn_args) \
 #define D3DX_FUNCTION(fn_name, fn_return, fn_args) \
-   typedef fn_return (WINAPI *D3DXFNPTR##fn_name##)##fn_args##;
+   typedef fn_return (WINAPI *D3DXFNPTR##fn_name)fn_args;
 #include "gfx/D3D9/d3dx9Functions.h"
 #include "gfx/D3D9/d3dx9Functions.h"
 #undef D3DX_FUNCTION
 #undef D3DX_FUNCTION
 
 
@@ -238,7 +238,7 @@ protected:
    // }
    // }
 
 
    virtual GFXShader* createShader();
    virtual GFXShader* createShader();
-   void disableShaders();
+   void disableShaders(bool force = false);
 
 
    /// Device helper function
    /// Device helper function
    virtual D3DPRESENT_PARAMETERS setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd ) const = 0;
    virtual D3DPRESENT_PARAMETERS setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd ) const = 0;
@@ -272,7 +272,7 @@ public:
 
 
    virtual F32  getPixelShaderVersion() const { return mPixVersion; }
    virtual F32  getPixelShaderVersion() const { return mPixVersion; }
    virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version; }
    virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version; }
-   virtual void setShader( GFXShader *shader );
+   virtual void setShader( GFXShader *shader, bool force = false );
    virtual U32  getNumSamplers() const { return mNumSamplers; }
    virtual U32  getNumSamplers() const { return mNumSamplers; }
    virtual U32  getNumRenderTargets() const { return mNumRenderTargets; }
    virtual U32  getNumRenderTargets() const { return mNumRenderTargets; }
    // }
    // }

+ 1 - 1
Engine/source/gfx/D3D9/gfxD3D9EnumTranslate.h

@@ -55,7 +55,7 @@ extern _D3DDECLTYPE GFXD3D9DeclType[GFXDeclType_COUNT];
 
 
 #define GFXREVERSE_LOOKUP( tablearray, enumprefix, val ) \
 #define GFXREVERSE_LOOKUP( tablearray, enumprefix, val ) \
    for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
    for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
-      if( (S32)tablearray##[i] == val ) \
+      if( (S32)tablearray[i] == val ) \
       { \
       { \
          val = i; \
          val = i; \
          break; \
          break; \

+ 3 - 3
Engine/source/gfx/D3D9/pc/gfxD3D9EnumTranslate.pc.cpp

@@ -47,13 +47,13 @@ _D3DDECLTYPE GFXD3D9DeclType[GFXDeclType_COUNT];
 
 
 #define INIT_LOOKUPTABLE( tablearray, enumprefix, type ) \
 #define INIT_LOOKUPTABLE( tablearray, enumprefix, type ) \
    for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
    for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
-      tablearray##[i] = (##type##)GFX_UNINIT_VAL;
+      tablearray[i] = (type)GFX_UNINIT_VAL;
 
 
 #define VALIDATE_LOOKUPTABLE( tablearray, enumprefix ) \
 #define VALIDATE_LOOKUPTABLE( tablearray, enumprefix ) \
    for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
    for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
-      if( (S32)tablearray##[i] == GFX_UNINIT_VAL ) \
+      if( (S32)tablearray[i] == GFX_UNINIT_VAL ) \
          Con::warnf( "GFXD3D9EnumTranslate: Unassigned value in " #tablearray ": %i", i ); \
          Con::warnf( "GFXD3D9EnumTranslate: Unassigned value in " #tablearray ": %i", i ); \
-      else if( (S32)tablearray##[i] == GFX_UNSUPPORTED_VAL ) \
+      else if( (S32)tablearray[i] == GFX_UNSUPPORTED_VAL ) \
          Con::warnf( "GFXD3D9EnumTranslate: Unsupported value in " #tablearray ": %i", i );
          Con::warnf( "GFXD3D9EnumTranslate: Unsupported value in " #tablearray ": %i", i );
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------

+ 1 - 1
Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.cpp

@@ -66,7 +66,7 @@ void GFXPCD3D9Device::createDirect3D9(LPDIRECT3D9 &d3d9, LPDIRECT3D9EX &d3d9ex)
       
       
       if (pfnCreate9Ex)
       if (pfnCreate9Ex)
       {
       {
-         if (!FAILED(pfnCreate9Ex(D3D_SDK_VERSION, &d3d9ex)) && d3d9ex)
+		  if (d3d9ex && !FAILED(pfnCreate9Ex(D3D_SDK_VERSION, &d3d9ex)))
             d3d9ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&d3d9));
             d3d9ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&d3d9));
       }
       }
 
 

+ 14 - 8
Engine/source/gfx/gFont.cpp

@@ -568,6 +568,7 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
 
 
    for (U32 i = 0; i < len;)
    for (U32 i = 0; i < len;)
    {
    {
+      U32 wide = 0; 
       startLine = i;
       startLine = i;
       startLineOffset.push_back(startLine);
       startLineOffset.push_back(startLine);
 
 
@@ -584,6 +585,10 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
          else if(isValidChar(txt[i]))
          else if(isValidChar(txt[i]))
          {
          {
             lineStrWidth += getCharInfo(txt[i]).xIncrement;
             lineStrWidth += getCharInfo(txt[i]).xIncrement;
+            if(txt[i] < 0) // symbols which code > 127
+            {  
+               wide++; i++;
+            }
             if( lineStrWidth > lineWidth )
             if( lineStrWidth > lineWidth )
             {
             {
                needsNewLine = true;
                needsNewLine = true;
@@ -595,7 +600,7 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
       if (!needsNewLine)
       if (!needsNewLine)
       {
       {
          // we are done!
          // we are done!
-         lineLen.push_back(i - startLine);
+         lineLen.push_back(i - startLine - wide);
          return;
          return;
       }
       }
 
 
@@ -628,7 +633,7 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
          }
          }
       }
       }
 
 
-      lineLen.push_back(j - startLine);
+      lineLen.push_back(j - startLine - wide);
       i = j;
       i = j;
 
 
       // Now we need to increment through any space characters at the
       // Now we need to increment through any space characters at the
@@ -918,17 +923,18 @@ void GFont::importStrip(const char *fileName, U32 padding, U32 kerning)
 
 
       // Allocate a new bitmap for this glyph, taking into account kerning and padding.
       // Allocate a new bitmap for this glyph, taking into account kerning and padding.
       glyphList.increment();
       glyphList.increment();
-      glyphList.last().bitmap = new GBitmap(mCharInfoList[i].width + kerning + 2*padding, mCharInfoList[i].height + 2*padding, false, strip->getFormat());
-      glyphList.last().charId = i;
+      GlyphMap& lastGlyphMap = glyphList.last();
+      lastGlyphMap.bitmap = new GBitmap(mCharInfoList[i].width + kerning + 2 * padding, mCharInfoList[i].height + 2 * padding, false, strip->getFormat());
+      lastGlyphMap.charId = i;
 
 
       // Copy the rect.
       // Copy the rect.
-      RectI ri(curWidth, getBaseline() - mCharInfoList[i].yOrigin, glyphList.last().bitmap->getWidth(), glyphList.last().bitmap->getHeight());
+      RectI ri(curWidth, getBaseline() - mCharInfoList[i].yOrigin, lastGlyphMap.bitmap->getWidth(), lastGlyphMap.bitmap->getHeight());
       Point2I outRi(0,0);
       Point2I outRi(0,0);
-      glyphList.last().bitmap->copyRect(strip, ri, outRi); 
+      lastGlyphMap.bitmap->copyRect(strip, ri, outRi);
 
 
       // Update glyph attributes.
       // Update glyph attributes.
-      mCharInfoList[i].width = glyphList.last().bitmap->getWidth();
-      mCharInfoList[i].height = glyphList.last().bitmap->getHeight();
+      mCharInfoList[i].width = lastGlyphMap.bitmap->getWidth();
+      mCharInfoList[i].height = lastGlyphMap.bitmap->getHeight();
       mCharInfoList[i].xOffset -= kerning + padding;
       mCharInfoList[i].xOffset -= kerning + padding;
       mCharInfoList[i].xIncrement += kerning;
       mCharInfoList[i].xIncrement += kerning;
       mCharInfoList[i].yOffset -= padding;
       mCharInfoList[i].yOffset -= padding;

+ 5 - 3
Engine/source/gfx/gfxDevice.cpp

@@ -161,7 +161,6 @@ GFXDevice::GFXDevice()
    mAllowRender = true;
    mAllowRender = true;
    mCurrentRenderStyle = RS_Standard;
    mCurrentRenderStyle = RS_Standard;
    mCurrentProjectionOffset = Point2F::Zero;
    mCurrentProjectionOffset = Point2F::Zero;
-   mStereoEyeOffset = Point3F::Zero;
    mCanCurrentlyRender = false;
    mCanCurrentlyRender = false;
    mInitialized = false;
    mInitialized = false;
    
    
@@ -197,6 +196,9 @@ GFXDevice::GFXDevice()
    #elif defined TORQUE_OS_PS3
    #elif defined TORQUE_OS_PS3
       GFXShader::addGlobalMacro( "TORQUE_OS_PS3" );            
       GFXShader::addGlobalMacro( "TORQUE_OS_PS3" );            
    #endif
    #endif
+
+   mStereoTargets[0] = NULL;
+   mStereoTargets[1] = NULL;
 }
 }
 
 
 GFXDrawUtil* GFXDevice::getDrawUtil()
 GFXDrawUtil* GFXDevice::getDrawUtil()
@@ -733,14 +735,14 @@ void GFXDevice::setLight(U32 stage, GFXLightInfo* light)
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // Set Light Material
 // Set Light Material
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void GFXDevice::setLightMaterial(GFXLightMaterial mat)
+void GFXDevice::setLightMaterial(const GFXLightMaterial& mat)
 {
 {
    mCurrentLightMaterial = mat;
    mCurrentLightMaterial = mat;
    mLightMaterialDirty = true;
    mLightMaterialDirty = true;
    mStateDirty = true;
    mStateDirty = true;
 }
 }
 
 
-void GFXDevice::setGlobalAmbientColor(ColorF color)
+void GFXDevice::setGlobalAmbientColor(const ColorF& color)
 {
 {
    if(mGlobalAmbientColor != color)
    if(mGlobalAmbientColor != color)
    {
    {

+ 68 - 8
Engine/source/gfx/gfxDevice.h

@@ -213,6 +213,9 @@ public:
       /// The device is about to finish rendering a frame
       /// The device is about to finish rendering a frame
       deEndOfFrame,
       deEndOfFrame,
 
 
+      /// The device has rendered a frame and ended the scene
+      dePostFrame,
+
       /// The device has started rendering a frame's field (such as for side-by-side rendering)
       /// The device has started rendering a frame's field (such as for side-by-side rendering)
       deStartOfField,
       deStartOfField,
 
 
@@ -244,7 +247,12 @@ public:
    enum GFXDeviceRenderStyles
    enum GFXDeviceRenderStyles
    {
    {
       RS_Standard          = 0,
       RS_Standard          = 0,
-      RS_StereoSideBySide  = (1<<0),
+      RS_StereoSideBySide  = (1<<0),     // Render into current Render Target side-by-side
+   };
+
+   enum GFXDeviceLimits
+   {
+      NumStereoPorts = 2
    };
    };
 
 
 private:
 private:
@@ -277,7 +285,19 @@ protected:
    Point2F mCurrentProjectionOffset;
    Point2F mCurrentProjectionOffset;
 
 
    /// Eye offset used when using a stereo rendering style
    /// Eye offset used when using a stereo rendering style
-   Point3F mStereoEyeOffset;
+   Point3F mStereoEyeOffset[NumStereoPorts];
+
+   MatrixF mStereoEyeTransforms[NumStereoPorts];
+   MatrixF mInverseStereoEyeTransforms[NumStereoPorts];
+
+   /// Fov port settings
+   FovPort mFovPorts[NumStereoPorts];
+
+   /// Destination viewports for stereo rendering
+   RectI mStereoViewports[NumStereoPorts];
+
+   /// Destination targets for stereo rendering
+   GFXTextureTarget* mStereoTargets[NumStereoPorts];
 
 
    /// This will allow querying to see if a device is initialized and ready to
    /// This will allow querying to see if a device is initialized and ready to
    /// have operations performed on it.
    /// have operations performed on it.
@@ -323,10 +343,50 @@ public:
    void setCurrentProjectionOffset(const Point2F& offset) { mCurrentProjectionOffset = offset; }
    void setCurrentProjectionOffset(const Point2F& offset) { mCurrentProjectionOffset = offset; }
 
 
    /// Get the current eye offset used during stereo rendering
    /// Get the current eye offset used during stereo rendering
-   const Point3F& getStereoEyeOffset() { return mStereoEyeOffset; }
+   const Point3F* getStereoEyeOffsets() { return mStereoEyeOffset; }
+
+   const MatrixF* getStereoEyeTransforms() { return mStereoEyeTransforms; }
+   const MatrixF* getInverseStereoEyeTransforms() { return mInverseStereoEyeTransforms; }
 
 
    /// Set the current eye offset used during stereo rendering
    /// Set the current eye offset used during stereo rendering
-   void setStereoEyeOffset(const Point3F& offset) { mStereoEyeOffset = offset; }
+   void setStereoEyeOffsets(Point3F *offsets) { dMemcpy(mStereoEyeOffset, offsets, sizeof(Point3F) * NumStereoPorts); }
+
+   void setStereoEyeTransforms(MatrixF *transforms) { dMemcpy(mStereoEyeTransforms, transforms, sizeof(mStereoEyeTransforms)); dMemcpy(mInverseStereoEyeTransforms, transforms, sizeof(mInverseStereoEyeTransforms)); mInverseStereoEyeTransforms[0].inverse(); mInverseStereoEyeTransforms[1].inverse();  }
+
+   /// Set the current eye offset used during stereo rendering. Assumes NumStereoPorts are available.
+   void setStereoFovPort(const FovPort *ports) { dMemcpy(mFovPorts, ports, sizeof(mFovPorts)); }
+
+   /// Get the current eye offset used during stereo rendering
+   const FovPort* getStereoFovPort() { return mFovPorts; }
+
+   /// Sets stereo viewports
+   void setSteroViewports(const RectI *ports) { dMemcpy(mStereoViewports, ports, sizeof(RectI) * NumStereoPorts); }
+
+   /// Sets stereo render targets
+   void setStereoTargets(GFXTextureTarget **targets) { mStereoTargets[0] = targets[0]; mStereoTargets[1] = targets[1]; }
+
+   RectI* getStereoViewports() { return mStereoViewports; }
+
+   /// Activates a stereo render target, setting the correct viewport to render eye contents.
+   /// If eyeId is -1, set a viewport encompassing the entire size of the render targets.
+   void activateStereoTarget(S32 eyeId)
+   {
+      if (eyeId == -1)
+      {
+         if (mStereoTargets[0])
+         {
+            setActiveRenderTarget(mStereoTargets[0], true);
+         }
+      }
+      else
+      {
+         if (mStereoTargets[eyeId])
+         {
+            setActiveRenderTarget(mStereoTargets[eyeId], false);
+         }
+         setViewport(mStereoViewports[eyeId]);
+      }
+   }
 
 
    GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
    GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
 
 
@@ -722,8 +782,8 @@ public:
    /// Returns the number of simultaneous render targets supported by the device.
    /// Returns the number of simultaneous render targets supported by the device.
    virtual U32 getNumRenderTargets() const = 0;
    virtual U32 getNumRenderTargets() const = 0;
 
 
-   virtual void setShader( GFXShader *shader ) {}
-   virtual void disableShaders() {} // TODO Remove when T3D 4.0
+   virtual void setShader( GFXShader *shader, bool force = false ) {}
+   virtual void disableShaders( bool force = false ) {} // TODO Remove when T3D 4.0
 
 
    /// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
    /// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
    void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
    void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
@@ -841,8 +901,8 @@ public:
    /// because of the state caching stuff.
    /// because of the state caching stuff.
    /// @{
    /// @{
    void setLight(U32 stage, GFXLightInfo* light);
    void setLight(U32 stage, GFXLightInfo* light);
-   void setLightMaterial(GFXLightMaterial mat);
-   void setGlobalAmbientColor(ColorF color);
+   void setLightMaterial(const GFXLightMaterial& mat);
+   void setGlobalAmbientColor(const ColorF& color);
 
 
    /// @}
    /// @}
    
    

+ 7 - 6
Engine/source/gfx/gfxTextureManager.cpp

@@ -192,13 +192,13 @@ void GFXTextureManager::cleanupPool()
          // This texture is unreferenced, so take the time
          // This texture is unreferenced, so take the time
          // now to completely remove it from the pool.
          // now to completely remove it from the pool.
          TexturePoolMap::Iterator unref = iter;
          TexturePoolMap::Iterator unref = iter;
-         iter++;
+         ++iter;
          unref->value = NULL;
          unref->value = NULL;
          mTexturePool.erase( unref );
          mTexturePool.erase( unref );
          continue;
          continue;
       }
       }
 
 
-      iter++;
+      ++iter;
    }
    }
 }
 }
 
 
@@ -1041,7 +1041,8 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height,
    }
    }
 
 
    // inOutFormat is not modified by this method
    // inOutFormat is not modified by this method
-   bool chekFmt = GFX->getCardProfiler()->checkFormat( testingFormat, profile, autoGenSupp ); 
+   GFXCardProfiler* cardProfiler = GFX->getCardProfiler();
+   bool chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);
    
    
    if( !chekFmt )
    if( !chekFmt )
    {
    {
@@ -1057,16 +1058,16 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height,
       {
       {
          case GFXFormatR8G8B8:
          case GFXFormatR8G8B8:
             testingFormat = GFXFormatR8G8B8X8;
             testingFormat = GFXFormatR8G8B8X8;
-            chekFmt = GFX->getCardProfiler()->checkFormat( testingFormat, profile, autoGenSupp );
+            chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);
             break;
             break;
 
 
          case GFXFormatA8:
          case GFXFormatA8:
             testingFormat = GFXFormatR8G8B8A8;
             testingFormat = GFXFormatR8G8B8A8;
-            chekFmt = GFX->getCardProfiler()->checkFormat( testingFormat, profile, autoGenSupp );
+            chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);
             break;
             break;
          
          
          default:
          default:
-            chekFmt = GFX->getCardProfiler()->checkFormat( testingFormat, profile, autoGenSupp );
+            chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);
             break;
             break;
       }
       }
    }
    }

+ 4 - 4
Engine/source/gfx/gfxVertexBuffer.h

@@ -64,11 +64,11 @@ public:
                      const GFXVertexFormat *vertexFormat, 
                      const GFXVertexFormat *vertexFormat, 
                      U32 vertexSize, 
                      U32 vertexSize, 
                      GFXBufferType bufferType )
                      GFXBufferType bufferType )
-      :  mDevice( device ),
-         mVolatileStart( 0 ),         
-         mNumVerts( numVerts ),
+      :  mNumVerts( numVerts ),
          mVertexSize( vertexSize ),
          mVertexSize( vertexSize ),
-         mBufferType( bufferType )      
+         mBufferType( bufferType ),
+         mDevice( device ),
+         mVolatileStart( 0 )
    {
    {
       if ( vertexFormat )
       if ( vertexFormat )
       {
       {

+ 5 - 4
Engine/source/gfx/gfxVertexFormat.cpp

@@ -114,10 +114,11 @@ void GFXVertexFormat::addElement( const String& semantic, GFXDeclType type, U32
 { 
 { 
    mDirty = true;
    mDirty = true;
    mElements.increment();
    mElements.increment();
-   mElements.last().mStreamIndex = stream; 
-   mElements.last().mSemantic = semantic.intern();
-   mElements.last().mSemanticIndex = index;
-   mElements.last().mType = type;      
+   GFXVertexElement& lastElement = mElements.last();
+   lastElement.mStreamIndex = stream;
+   lastElement.mSemantic = semantic.intern();
+   lastElement.mSemanticIndex = index;
+   lastElement.mType = type;
 }
 }
 
 
 const String& GFXVertexFormat::getDescription() const
 const String& GFXVertexFormat::getDescription() const

+ 6 - 2
Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h

@@ -14,7 +14,9 @@ public:
 
 
    ~GLFenceRange()
    ~GLFenceRange()
    {
    {
-      AssertFatal( mSync == 0, "");
+      //the order of creation/destruction of static variables is indetermined... depends on detail of the build
+      //looks like for some reason on windows + sdl + opengl the order make invalid / wrong the process TODO: Refactor -LAR
+      //AssertFatal( mSync == 0, "");
    }
    }
 
 
    void init(U32 start, U32 end)
    void init(U32 start, U32 end)
@@ -87,7 +89,9 @@ public:
 
 
    ~GLOrderedFenceRangeManager( )
    ~GLOrderedFenceRangeManager( )
    {
    {
-      waitAllRanges( );
+      //the order of creation/destruction of static variables is indetermined... depends on detail of the build
+      //looks like for some reason on windows + sdl + opengl the order make invalid / wrong the process TODO: Refactor -LAR
+      //waitAllRanges( );
    }
    }
 
 
    void protectOrderedRange( U32 start, U32 end )
    void protectOrderedRange( U32 start, U32 end )

+ 266 - 41
Engine/source/gui/3d/guiTSControl.cpp

@@ -22,6 +22,7 @@
 
 
 #include "platform/platform.h"
 #include "platform/platform.h"
 #include "gui/3d/guiTSControl.h"
 #include "gui/3d/guiTSControl.h"
+#include "gui/core/guiOffscreenCanvas.h"
 
 
 #include "console/engineAPI.h"
 #include "console/engineAPI.h"
 #include "scene/sceneManager.h"
 #include "scene/sceneManager.h"
@@ -34,7 +35,12 @@
 #include "scene/reflectionManager.h"
 #include "scene/reflectionManager.h"
 #include "postFx/postEffectManager.h"
 #include "postFx/postEffectManager.h"
 #include "gfx/gfxTransformSaver.h"
 #include "gfx/gfxTransformSaver.h"
+#include "gfx/gfxDrawUtil.h"
+#include "gfx/gfxDebugEvent.h"
 
 
+GFXTextureObject *gLastStereoTexture = NULL;
+
+#define TS_OVERLAY_SCREEN_WIDTH 0.75
 
 
 IMPLEMENT_CONOBJECT( GuiTSCtrl );
 IMPLEMENT_CONOBJECT( GuiTSCtrl );
 
 
@@ -51,6 +57,7 @@ ConsoleDocClass( GuiTSCtrl,
 );
 );
 
 
 U32 GuiTSCtrl::smFrameCount = 0;
 U32 GuiTSCtrl::smFrameCount = 0;
+bool GuiTSCtrl::smUseLatestDisplayTransform = true;
 Vector<GuiTSCtrl*> GuiTSCtrl::smAwakeTSCtrls;
 Vector<GuiTSCtrl*> GuiTSCtrl::smAwakeTSCtrls;
 
 
 ImplementEnumType( GuiTSRenderStyles,
 ImplementEnumType( GuiTSRenderStyles,
@@ -60,7 +67,6 @@ ImplementEnumType( GuiTSRenderStyles,
 	{ GuiTSCtrl::RenderStyleStereoSideBySide, "stereo side by side"   },
 	{ GuiTSCtrl::RenderStyleStereoSideBySide, "stereo side by side"   },
 EndImplementEnumType;
 EndImplementEnumType;
 
 
-
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
 namespace 
 namespace 
@@ -153,7 +159,8 @@ GuiTSCtrl::GuiTSCtrl()
    mLastCameraQuery.nearPlane = 0.01f;
    mLastCameraQuery.nearPlane = 0.01f;
 
 
    mLastCameraQuery.projectionOffset = Point2F::Zero;
    mLastCameraQuery.projectionOffset = Point2F::Zero;
-   mLastCameraQuery.eyeOffset = Point3F::Zero;
+   mLastCameraQuery.hasFovPort = false;
+   mLastCameraQuery.hasStereoTargets = false;
 
 
    mLastCameraQuery.ortho = false;
    mLastCameraQuery.ortho = false;
 }
 }
@@ -192,6 +199,8 @@ void GuiTSCtrl::consoleInit()
 {
 {
    Con::addVariable("$TSControl::frameCount", TypeS32, &smFrameCount, "The number of frames that have been rendered since this control was created.\n"
    Con::addVariable("$TSControl::frameCount", TypeS32, &smFrameCount, "The number of frames that have been rendered since this control was created.\n"
 	   "@ingroup Rendering\n");
 	   "@ingroup Rendering\n");
+   Con::addVariable("$TSControl::useLatestDisplayTransform", TypeBool, &smUseLatestDisplayTransform, "Use the latest view transform when rendering stereo instead of the one calculated by the last move.\n"
+	   "@ingroup Rendering\n");
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -206,6 +215,9 @@ bool GuiTSCtrl::onWake()
       "GuiTSCtrl::onWake - This control is already in the awake list!" );
       "GuiTSCtrl::onWake - This control is already in the awake list!" );
    smAwakeTSCtrls.push_back( this );
    smAwakeTSCtrls.push_back( this );
 
 
+   // For VR
+   mLastCameraQuery.drawCanvas = getRoot();
+
    return true;
    return true;
 }
 }
 
 
@@ -302,11 +314,52 @@ F32 GuiTSCtrl::calculateViewDistance(F32 radius)
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+static FovPort CalculateFovPortForCanvas(const RectI viewport, const CameraQuery &cameraQuery)
+{
+   F32 wwidth;
+   F32 wheight;
+   F32 renderWidth = viewport.extent.x;
+   F32 renderHeight = viewport.extent.y;
+   F32 aspectRatio = renderWidth / renderHeight;
+
+   // Use the FOV to calculate the viewport height scale
+   // then generate the width scale from the aspect ratio.
+   if(!cameraQuery.ortho)
+   {
+      wheight = /*cameraQuery.nearPlane * */ mTan(cameraQuery.fov / 2.0f);
+      wwidth = aspectRatio * wheight;
+   }
+   else
+   {
+      wheight = cameraQuery.fov;
+      wwidth = aspectRatio * wheight;
+   }
+
+   F32 hscale = wwidth * 2.0f / renderWidth;
+   F32 vscale = wheight * 2.0f / renderHeight;
+
+   F32 left = 0.0f * hscale - wwidth;
+   F32 right = renderWidth * hscale - wwidth;
+   F32 top = wheight - vscale * 0.0f;
+   F32 bottom = wheight - vscale * renderHeight;
+
+   FovPort fovPort;
+   fovPort.upTan = top;
+   fovPort.downTan = -bottom;
+   fovPort.leftTan = -left;
+   fovPort.rightTan = right;
+
+   return fovPort;
+}
+
+//-----------------------------------------------------------------------------
+
 void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
 void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
 {
 {
 	// Save the current transforms so we can restore
 	// Save the current transforms so we can restore
    // it for child control rendering below.
    // it for child control rendering below.
    GFXTransformSaver saver;
    GFXTransformSaver saver;
+   bool renderingToTarget = false;
 
 
    if(!processCameraQuery(&mLastCameraQuery))
    if(!processCameraQuery(&mLastCameraQuery))
    {
    {
@@ -317,15 +370,70 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
       return;
       return;
    }
    }
 
 
+   GFXTargetRef origTarget = GFX->getActiveRenderTarget();
+
    // Set up the appropriate render style
    // Set up the appropriate render style
    U32 prevRenderStyle = GFX->getCurrentRenderStyle();
    U32 prevRenderStyle = GFX->getCurrentRenderStyle();
    Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
    Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
-   Point3F prevEyeOffset = GFX->getStereoEyeOffset();
+   Point2I renderSize = getExtent();
+
    if(mRenderStyle == RenderStyleStereoSideBySide)
    if(mRenderStyle == RenderStyleStereoSideBySide)
    {
    {
       GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
       GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
       GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
       GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
-      GFX->setStereoEyeOffset(mLastCameraQuery.eyeOffset);
+      GFX->setStereoEyeOffsets(mLastCameraQuery.eyeOffset);
+
+      if (!mLastCameraQuery.hasStereoTargets)
+      {
+         // Need to calculate our current viewport here
+         mLastCameraQuery.stereoViewports[0] = updateRect;
+         mLastCameraQuery.stereoViewports[0].extent.x /= 2;
+         mLastCameraQuery.stereoViewports[1] = mLastCameraQuery.stereoViewports[0];
+         mLastCameraQuery.stereoViewports[1].point.x += mLastCameraQuery.stereoViewports[1].extent.x;
+      }
+
+      if (!mLastCameraQuery.hasFovPort)
+      {
+         // Need to make our own fovPort
+         mLastCameraQuery.fovPort[0] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[0], mLastCameraQuery);
+         mLastCameraQuery.fovPort[1] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[1], mLastCameraQuery);
+      }
+         
+      GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
+
+      GFX->setSteroViewports(mLastCameraQuery.stereoViewports);
+      GFX->setStereoTargets(mLastCameraQuery.stereoTargets);
+
+      MatrixF myTransforms[2];
+
+      if (smUseLatestDisplayTransform)
+      {
+         // Use the view matrix determined from the display device
+         myTransforms[0] = mLastCameraQuery.eyeTransforms[0];
+         myTransforms[1] = mLastCameraQuery.eyeTransforms[1];
+      }
+      else
+      {
+         // Use the view matrix determined from the control object
+         myTransforms[0] = mLastCameraQuery.cameraMatrix;
+         myTransforms[1] = mLastCameraQuery.cameraMatrix;
+
+         QuatF qrot = mLastCameraQuery.cameraMatrix;
+         Point3F pos = mLastCameraQuery.cameraMatrix.getPosition();
+         Point3F rotEyePos;
+
+         myTransforms[0].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[0], &rotEyePos));
+         myTransforms[1].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[1], &rotEyePos));
+      }
+
+      GFX->setStereoEyeTransforms(myTransforms);
+
+      // Allow render size to originate from the render target
+      if (mLastCameraQuery.stereoTargets[0])
+      {
+         renderSize = mLastCameraQuery.stereoViewports[0].extent;
+         renderingToTarget = true;
+      }
    }
    }
    else
    else
    {
    {
@@ -354,41 +462,37 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
       mLastCameraQuery.cameraMatrix.mul(rotMat);
       mLastCameraQuery.cameraMatrix.mul(rotMat);
    }
    }
 
 
-   // set up the camera and viewport stuff:
-   F32 wwidth;
-   F32 wheight;
-   F32 renderWidth = (mRenderStyle == RenderStyleStereoSideBySide) ? F32(getWidth())*0.5f : F32(getWidth());
-   F32 renderHeight = F32(getHeight());
-   F32 aspectRatio = renderWidth / renderHeight;
-   
-   // Use the FOV to calculate the viewport height scale
-   // then generate the width scale from the aspect ratio.
-   if(!mLastCameraQuery.ortho)
-   {
-      wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
-      wwidth = aspectRatio * wheight;
-   }
-   else
-   {
-      wheight = mLastCameraQuery.fov;
-      wwidth = aspectRatio * wheight;
-   }
-
-   F32 hscale = wwidth * 2.0f / renderWidth;
-   F32 vscale = wheight * 2.0f / renderHeight;
-
    Frustum frustum;
    Frustum frustum;
    if(mRenderStyle == RenderStyleStereoSideBySide)
    if(mRenderStyle == RenderStyleStereoSideBySide)
    {
    {
-      F32 left = 0.0f * hscale - wwidth;
-      F32 right = renderWidth * hscale - wwidth;
-      F32 top = wheight - vscale * 0.0f;
-      F32 bottom = wheight - vscale * renderHeight;
-
-      frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane );
+      // NOTE: these calculations are essentially overridden later by the fov port settings when rendering each eye.
+      MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho,  mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
    }
    }
    else
    else
    {
    {
+      // set up the camera and viewport stuff:
+      F32 wwidth;
+      F32 wheight;
+      F32 renderWidth = F32(renderSize.x);
+      F32 renderHeight = F32(renderSize.y);
+      F32 aspectRatio = renderWidth / renderHeight;
+   
+      // Use the FOV to calculate the viewport height scale
+      // then generate the width scale from the aspect ratio.
+      if(!mLastCameraQuery.ortho)
+      {
+         wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
+         wwidth = aspectRatio * wheight;
+      }
+      else
+      {
+         wheight = mLastCameraQuery.fov;
+         wwidth = aspectRatio * wheight;
+      }
+
+      F32 hscale = wwidth * 2.0f / renderWidth;
+      F32 vscale = wheight * 2.0f / renderHeight;
+
       F32 left = (updateRect.point.x - offset.x) * hscale - wwidth;
       F32 left = (updateRect.point.x - offset.x) * hscale - wwidth;
       F32 right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth;
       F32 right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth;
       F32 top = wheight - vscale * (updateRect.point.y - offset.y);
       F32 top = wheight - vscale * (updateRect.point.y - offset.y);
@@ -407,15 +511,24 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
       
       
    RectI tempRect = updateRect;
    RectI tempRect = updateRect;
    
    
-#ifdef TORQUE_OS_MAC
-   Point2I screensize = getRoot()->getWindowSize();
-   tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
-#endif
+   if (!renderingToTarget)
+   {
+   #ifdef TORQUE_OS_MAC
+      Point2I screensize = getRoot()->getWindowSize();
+      tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
+   #endif
 
 
-   GFX->setViewport( tempRect );
+      GFX->setViewport( tempRect );
+   }
+   else
+   {
+      // Activate stereo RT
+      GFX->activateStereoTarget(-1);
+   }
 
 
    // Clear the zBuffer so GUI doesn't hose object rendering accidentally
    // Clear the zBuffer so GUI doesn't hose object rendering accidentally
    GFX->clear( GFXClearZBuffer , ColorI(20,20,20), 1.0f, 0 );
    GFX->clear( GFXClearZBuffer , ColorI(20,20,20), 1.0f, 0 );
+   //GFX->clear( GFXClearTarget, ColorI(255,0,0), 1.0f, 0);
 
 
    GFX->setFrustum( frustum );
    GFX->setFrustum( frustum );
    if(mLastCameraQuery.ortho)
    if(mLastCameraQuery.ortho)
@@ -427,7 +540,7 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
    // We're going to be displaying this render at size of this control in
    // We're going to be displaying this render at size of this control in
    // pixels - let the scene know so that it can calculate e.g. reflections
    // pixels - let the scene know so that it can calculate e.g. reflections
    // correctly for that final display result.
    // correctly for that final display result.
-   gClientSceneGraph->setDisplayTargetResolution(getExtent());
+   gClientSceneGraph->setDisplayTargetResolution(renderSize);
 
 
    // Set the GFX world matrix to the world-to-camera transform, but don't 
    // Set the GFX world matrix to the world-to-camera transform, but don't 
    // change the cameraMatrix in mLastCameraQuery. This is because 
    // change the cameraMatrix in mLastCameraQuery. This is because 
@@ -455,20 +568,119 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
    renderWorld(updateRect);
    renderWorld(updateRect);
    DebugDrawer::get()->render();
    DebugDrawer::get()->render();
 
 
+   // Render the canvas overlay if its available
+   if (mRenderStyle == RenderStyleStereoSideBySide && mStereoGuiTarget.getPointer())
+   {
+      GFXDEBUGEVENT_SCOPE( StereoGui_Render, ColorI( 255, 0, 0 ) );
+      MatrixF proj(1);
+      
+      Frustum originalFrustum = GFX->getFrustum();
+      GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
+      const FovPort *currentFovPort = GFX->getStereoFovPort();
+      const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
+      const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
+      Frustum gfxFrustum = originalFrustum;
+
+      for (U32 i=0; i<2; i++)
+      {
+         GFX->activateStereoTarget(i);
+         MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]);
+         GFX->setFrustum(gfxFrustum);
+
+         MatrixF eyeWorldTrans(1);
+         eyeWorldTrans.setPosition(Point3F(eyeOffset[i].x,eyeOffset[i].y,eyeOffset[i].z));
+         MatrixF eyeWorld(1);
+         eyeWorld.mul(eyeWorldTrans);
+         eyeWorld.inverse();
+         
+         GFX->setWorldMatrix(eyeWorld);
+         GFX->setViewMatrix(MatrixF::Identity);
+
+         if (!mStereoOverlayVB.getPointer())
+         {
+            mStereoOverlayVB.set(GFX, 4, GFXBufferTypeStatic);
+            GFXVertexPCT *verts = mStereoOverlayVB.lock(0, 4);
+
+            F32 texLeft   = 0.0f;
+            F32 texRight  = 1.0f;
+            F32 texTop    = 1.0f;
+            F32 texBottom = 0.0f;
+
+            F32 rectRatio = gfxFrustum.getWidth() / gfxFrustum.getHeight();
+            F32 rectWidth = gfxFrustum.getWidth() * TS_OVERLAY_SCREEN_WIDTH;
+            F32 rectHeight = rectWidth * rectRatio;
+
+            F32 screenLeft   = -rectWidth * 0.5;
+            F32 screenRight  = rectWidth * 0.5;
+            F32 screenTop    = -rectHeight * 0.5;
+            F32 screenBottom = rectHeight * 0.5;
+
+            const F32 fillConv = 0.0f;
+            const F32 frustumDepthAdjusted = gfxFrustum.getNearDist() + 0.012;
+            verts[0].point.set( screenLeft  - fillConv, frustumDepthAdjusted, screenTop    - fillConv );
+            verts[1].point.set( screenRight - fillConv, frustumDepthAdjusted, screenTop    - fillConv );
+            verts[2].point.set( screenLeft  - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
+            verts[3].point.set( screenRight - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
+
+            verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255);
+
+            verts[0].texCoord.set( texLeft,  texTop );
+            verts[1].texCoord.set( texRight, texTop );
+            verts[2].texCoord.set( texLeft,  texBottom );
+            verts[3].texCoord.set( texRight, texBottom );
+
+            mStereoOverlayVB.unlock();
+         }
+
+         if (!mStereoGuiSB.getPointer())
+         {
+            // DrawBitmapStretchSR
+            GFXStateBlockDesc bitmapStretchSR;
+            bitmapStretchSR.setCullMode(GFXCullNone);
+            bitmapStretchSR.setZReadWrite(false, false);
+            bitmapStretchSR.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
+            bitmapStretchSR.samplersDefined = true;
+
+            bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
+            bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
+            bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
+            bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;
+
+            mStereoGuiSB = GFX->createStateBlock(bitmapStretchSR);
+         }
+
+         GFX->setVertexBuffer(mStereoOverlayVB);
+         GFX->setStateBlock(mStereoGuiSB);
+         GFX->setTexture( 0, texObject );
+         GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
+         GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
+      }
+   }
+
 	// Restore the previous matrix state before
 	// Restore the previous matrix state before
    // we begin rendering the child controls.
    // we begin rendering the child controls.
    saver.restore();
    saver.restore();
 
 
    // Restore the render style and any stereo parameters
    // Restore the render style and any stereo parameters
+   GFX->setActiveRenderTarget(origTarget);
    GFX->setCurrentRenderStyle(prevRenderStyle);
    GFX->setCurrentRenderStyle(prevRenderStyle);
    GFX->setCurrentProjectionOffset(prevProjectionOffset);
    GFX->setCurrentProjectionOffset(prevProjectionOffset);
-   GFX->setStereoEyeOffset(prevEyeOffset);
+
+   
+   if(mRenderStyle == RenderStyleStereoSideBySide && gLastStereoTexture)
+   {
+      GFX->setClipRect(updateRect);
+      GFX->getDrawUtil()->drawBitmapStretch(gLastStereoTexture, updateRect);
+   }
 
 
    // Allow subclasses to render 2D elements.
    // Allow subclasses to render 2D elements.
    GFX->setClipRect(updateRect);
    GFX->setClipRect(updateRect);
    renderGui( offset, updateRect );
    renderGui( offset, updateRect );
 
 
-   renderChildControls(offset, updateRect);
+   if (shouldRenderChildControls())
+   {
+      renderChildControls(offset, updateRect);
+   }
    smFrameCount++;
    smFrameCount++;
 }
 }
 
 
@@ -499,6 +711,12 @@ void GuiTSCtrl::drawLineList( const Vector<Point3F> &points, const ColorI color,
       drawLine( points[i], points[i+1], color, width );
       drawLine( points[i], points[i+1], color, width );
 }
 }
 
 
+
+void GuiTSCtrl::setStereoGui(GuiOffscreenCanvas *canvas)
+{
+   mStereoGuiTarget = canvas ? canvas->getTarget() : NULL;
+}
+
 //=============================================================================
 //=============================================================================
 //    Console Methods.
 //    Console Methods.
 //=============================================================================
 //=============================================================================
@@ -547,3 +765,10 @@ DefineEngineMethod( GuiTSCtrl, calculateViewDistance, F32, ( F32 radius ),,
 {
 {
    return object->calculateViewDistance( radius );
    return object->calculateViewDistance( radius );
 }
 }
+
+DefineEngineMethod( GuiTSCtrl, setStereoGui, void, ( GuiOffscreenCanvas* canvas ),,
+   "Sets the current stereo texture to an offscreen canvas\n"
+   "@param canvas The desired canvas." )
+{
+   object->setStereoGui(canvas);
+}

+ 27 - 3
Engine/source/gui/3d/guiTSControl.h

@@ -30,16 +30,31 @@
 #include "math/mMath.h"
 #include "math/mMath.h"
 #endif
 #endif
 
 
+
+#ifndef _MATTEXTURETARGET_H_
+#include "materials/matTextureTarget.h"
+#endif
+
+class IDisplayDevice;
+class GuiOffscreenCanvas;
+
 struct CameraQuery
 struct CameraQuery
 {
 {
    SimObject*  object;
    SimObject*  object;
    F32         nearPlane;
    F32         nearPlane;
    F32         farPlane;
    F32         farPlane;
    F32         fov;
    F32         fov;
+   FovPort     fovPort[2]; // fov for each eye
    Point2F     projectionOffset;
    Point2F     projectionOffset;
-   Point3F     eyeOffset;
+   Point3F     eyeOffset[2];
+   MatrixF     eyeTransforms[2];
    bool        ortho;
    bool        ortho;
+   bool        hasFovPort;
+   bool        hasStereoTargets;
    MatrixF     cameraMatrix;
    MatrixF     cameraMatrix;
+   RectI       stereoViewports[2]; // destination viewports
+   GFXTextureTarget* stereoTargets[2];
+   GuiCanvas* drawCanvas; // Canvas we are drawing to. Needed for VR
 };
 };
 
 
 /// Abstract base class for 3D viewport GUIs.
 /// Abstract base class for 3D viewport GUIs.
@@ -50,11 +65,12 @@ class GuiTSCtrl : public GuiContainer
 public:
 public:
    enum RenderStyles {
    enum RenderStyles {
       RenderStyleStandard           = 0,
       RenderStyleStandard           = 0,
-      RenderStyleStereoSideBySide   = (1<<0),
+      RenderStyleStereoSideBySide   = (1<<0)
    };
    };
 
 
 protected:
 protected:
    static U32     smFrameCount;
    static U32     smFrameCount;
+   static bool    smUseLatestDisplayTransform;
    F32            mCameraZRot;
    F32            mCameraZRot;
    F32            mForceFOV;
    F32            mForceFOV;
 
 
@@ -83,7 +99,11 @@ protected:
 
 
    /// The last camera query set in onRender.
    /// The last camera query set in onRender.
    /// @see getLastCameraQuery
    /// @see getLastCameraQuery
-   CameraQuery mLastCameraQuery;	
+   CameraQuery mLastCameraQuery;
+
+   NamedTexTargetRef mStereoGuiTarget;
+   GFXVertexBufferHandle<GFXVertexPCT> mStereoOverlayVB;
+   GFXStateBlockRef mStereoGuiSB;
    
    
 public:
 public:
    
    
@@ -155,6 +175,10 @@ public:
 
 
    static const U32& getFrameCount() { return smFrameCount; }
    static const U32& getFrameCount() { return smFrameCount; }
 
 
+   bool shouldRenderChildControls() { return mRenderStyle == RenderStyleStandard; }
+
+   void setStereoGui(GuiOffscreenCanvas *canvas);
+
    DECLARE_CONOBJECT(GuiTSCtrl);
    DECLARE_CONOBJECT(GuiTSCtrl);
    DECLARE_CATEGORY( "Gui 3D" );
    DECLARE_CATEGORY( "Gui 3D" );
    DECLARE_DESCRIPTION( "Abstract base class for controls that render a 3D viewport." );
    DECLARE_DESCRIPTION( "Abstract base class for controls that render a 3D viewport." );

+ 0 - 3
Engine/source/gui/containers/guiContainer.cpp

@@ -128,9 +128,6 @@ bool GuiContainer::reOrder(SimObject* obj, SimObject* target)
 
 
 bool GuiContainer::resize( const Point2I &newPosition, const Point2I &newExtent )
 bool GuiContainer::resize( const Point2I &newPosition, const Point2I &newExtent )
 {
 {
-   RectI oldBounds = getBounds();
-   Point2I minExtent = getMinExtent();
-
    if( !Parent::resize( newPosition, newExtent ) )
    if( !Parent::resize( newPosition, newExtent ) )
       return false;
       return false;
    
    

+ 1 - 1
Engine/source/gui/containers/guiContainer.h

@@ -91,7 +91,7 @@ class  GuiContainer : public GuiControl
       inline void setAnchorRight(bool val) { mSizingOptions.mAnchorRight = val; }
       inline void setAnchorRight(bool val) { mSizingOptions.mAnchorRight = val; }
 
 
       ControlSizing getSizingOptions() const { return mSizingOptions; }
       ControlSizing getSizingOptions() const { return mSizingOptions; }
-      void setSizingOptions(ControlSizing val) { mSizingOptions = val; }
+      void setSizingOptions(const ControlSizing& val) { mSizingOptions = val; }
 
 
       /// @}   
       /// @}   
 
 

+ 1 - 1
Engine/source/gui/containers/guiRolloutCtrl.h

@@ -118,6 +118,7 @@ class GuiRolloutCtrl : public GuiTickCtrl
 
 
       DECLARE_CALLBACK( void, onCollapsed, () );
       DECLARE_CALLBACK( void, onCollapsed, () );
       /// @}
       /// @}
+      virtual void processTick();
 
 
    public:
    public:
    
    
@@ -152,7 +153,6 @@ class GuiRolloutCtrl : public GuiTickCtrl
 
 
       // Sizing Animation Functions
       // Sizing Animation Functions
       void animateTo( S32 height );
       void animateTo( S32 height );
-      virtual void processTick();
 
 
       void collapse() { animateTo( mHeader.extent.y ); }
       void collapse() { animateTo( mHeader.extent.y ); }
       void expand() { animateTo( mExpanded.extent.y ); }
       void expand() { animateTo( mExpanded.extent.y ); }

+ 28 - 24
Engine/source/gui/containers/guiScrollCtrl.cpp

@@ -493,6 +493,8 @@ void GuiScrollCtrl::calcThumbs()
 void GuiScrollCtrl::scrollDelta(S32 deltaX, S32 deltaY)
 void GuiScrollCtrl::scrollDelta(S32 deltaX, S32 deltaY)
 {
 {
    scrollTo(mChildRelPos.x + deltaX, mChildRelPos.y + deltaY);
    scrollTo(mChildRelPos.x + deltaX, mChildRelPos.y + deltaY);
+
+   onScroll_callback();
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -1091,8 +1093,9 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     }
     }
 
 
     // Render Up Arrow.
     // Render Up Arrow.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[upArrowBitmap] );
+    GFXDrawUtil* drawUtil = GFX->getDrawUtil();
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[upArrowBitmap]);
 
 
     // Update Pos.
     // Update Pos.
     pos.y += mBitmapBounds[upArrowBitmap].extent.y;
     pos.y += mBitmapBounds[upArrowBitmap].extent.y;
@@ -1118,8 +1121,8 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     if ( trackRect.extent.y > 0 )
     if ( trackRect.extent.y > 0 )
     {
     {
         // Render Track.
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, trackRect, mBitmapBounds[trackBitmap] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, trackRect, mBitmapBounds[trackBitmap]);
     }
     }
 
 
     // Update Pos.
     // Update Pos.
@@ -1137,8 +1140,8 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     }
     }
 
 
     // Render Down Arrow.
     // Render Down Arrow.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[downArrowBitmap] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[downArrowBitmap]);
 
 
     // Render the Thumb?
     // Render the Thumb?
     if ( !mVBarEnabled )
     if ( !mVBarEnabled )
@@ -1163,8 +1166,8 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     }
     }
 
 
     // Render Thumb Top.
     // Render Thumb Top.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[thumbBitmapTop] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapTop]);
 
 
     // Update Pos.
     // Update Pos.
     pos.y += mBitmapBounds[thumbBitmapTop].extent.y;
     pos.y += mBitmapBounds[thumbBitmapTop].extent.y;
@@ -1179,16 +1182,16 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     if ( thumbRect.extent.y > 0 )
     if ( thumbRect.extent.y > 0 )
     {
     {
         // Render Track.
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle]);
     }
     }
 
 
     // Update Pos.
     // Update Pos.
     pos.y += thumbRect.extent.y;
     pos.y += thumbRect.extent.y;
 
 
     // Render the Thumb Bottom.
     // Render the Thumb Bottom.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[thumbBitmapBottom] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapBottom]);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -1215,8 +1218,9 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     }
     }
 
 
     // Render Up Arrow.
     // Render Up Arrow.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[leftArrowBitmap] );
+    GFXDrawUtil* drawUtil = GFX->getDrawUtil();
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[leftArrowBitmap]);
 
 
     // Update Pos.
     // Update Pos.
     pos.x += mBitmapBounds[leftArrowBitmap].extent.x;
     pos.x += mBitmapBounds[leftArrowBitmap].extent.x;
@@ -1242,8 +1246,8 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     if ( trackRect.extent.x > 0 )
     if ( trackRect.extent.x > 0 )
     {
     {
         // Render Track.
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, trackRect, mBitmapBounds[trackBitmap] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, trackRect, mBitmapBounds[trackBitmap]);
     }
     }
 
 
     // Update Pos.
     // Update Pos.
@@ -1261,8 +1265,8 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     }
     }
 
 
     // Render Right Arrow.
     // Render Right Arrow.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[rightArrowBitmap] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[rightArrowBitmap]);
 
 
     // Render the Thumb?
     // Render the Thumb?
     if ( !mHBarEnabled )
     if ( !mHBarEnabled )
@@ -1287,8 +1291,8 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     }
     }
 
 
     // Render Thumb Left.
     // Render Thumb Left.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[thumbBitmapLeft] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapLeft]);
 
 
     // Update Pos.
     // Update Pos.
     pos.x += mBitmapBounds[thumbBitmapLeft].extent.x;
     pos.x += mBitmapBounds[thumbBitmapLeft].extent.x;
@@ -1303,16 +1307,16 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     if ( thumbRect.extent.x > 0 )
     if ( thumbRect.extent.x > 0 )
     {
     {
         // Render Track.
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle]);
     }
     }
 
 
     // Update Pos.
     // Update Pos.
     pos.x += thumbRect.extent.x;
     pos.x += thumbRect.extent.x;
 
 
     // Render the Thumb Bottom.
     // Render the Thumb Bottom.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[thumbBitmapRight] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapRight]);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------

+ 1 - 1
Engine/source/gui/containers/guiSplitContainer.cpp

@@ -444,7 +444,7 @@ bool GuiSplitContainer::layoutControls( RectI &clientRect )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-void GuiSplitContainer::solvePanelConstraints( Point2I newDragPos, GuiContainer * firstPanel, GuiContainer * secondPanel, RectI clientRect )
+void GuiSplitContainer::solvePanelConstraints(Point2I newDragPos, GuiContainer * firstPanel, GuiContainer * secondPanel, const RectI& clientRect)
 {
 {
    if( !firstPanel || !secondPanel )
    if( !firstPanel || !secondPanel )
       return;
       return;

+ 1 - 1
Engine/source/gui/containers/guiSplitContainer.h

@@ -84,7 +84,7 @@ public:
    virtual inline Point2I getSplitPoint() { return mSplitPoint; };
    virtual inline Point2I getSplitPoint() { return mSplitPoint; };
    /// The Splitters entire Client Rectangle, this takes into account padding of this control
    /// The Splitters entire Client Rectangle, this takes into account padding of this control
    virtual inline RectI getSplitRect() { return mSplitRect; };
    virtual inline RectI getSplitRect() { return mSplitRect; };
-   virtual void solvePanelConstraints( Point2I newDragPos, GuiContainer * firstPanel, GuiContainer * secondPanel, RectI clientRect );   
+   virtual void solvePanelConstraints(Point2I newDragPos, GuiContainer * firstPanel, GuiContainer * secondPanel, const RectI& clientRect);
    virtual Point2I getMinExtent() const;   
    virtual Point2I getMinExtent() const;   
 
 
 protected:
 protected:

+ 2 - 2
Engine/source/gui/containers/guiTabBookCtrl.cpp

@@ -548,7 +548,7 @@ void GuiTabBookCtrl::renderTabs( const Point2I &offset, const RectI &tabRect )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-void GuiTabBookCtrl::renderTab( RectI tabRect, GuiTabPageCtrl *tab )
+void GuiTabBookCtrl::renderTab(const RectI& tabRect, GuiTabPageCtrl *tab)
 {
 {
    StringTableEntry text = tab->getText();
    StringTableEntry text = tab->getText();
    ColorI oldColor;
    ColorI oldColor;
@@ -622,7 +622,7 @@ S32 GuiTabBookCtrl::calculatePageTabWidth( GuiTabPageCtrl *page )
 
 
    const char* text = page->getText();
    const char* text = page->getText();
 
 
-   if( !text || dStrlen(text) == 0 || mProfile->mFont == NULL )
+   if( !text || dStrlen(text) == 0 || mProfile == NULL || mProfile->mFont == NULL )
       return mMinTabWidth;
       return mMinTabWidth;
 
 
    GFont *font = mProfile->mFont;
    GFont *font = mProfile->mFont;

Some files were not shown because too many files changed in this diff