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(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/temp" CACHE PATH "default install path" FORCE )
+
 if("${TORQUE_APP_NAME}" STREQUAL "")
 	message(FATAL_ERROR "Please set TORQUE_APP_NAME first")
 endif()

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

@@ -58,7 +58,7 @@ void daeStringTable::clear()
 {
 	unsigned int i;
 	for (i=0;i<_stringBuffersList.getCount();i++)
-#if _MSC_VER <= 1200
+#if defined(_MSC_VER) && (_MSC_VER <= 1200)
 		delete [] (char *) _stringBuffersList[i];
 #else
 		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>
 #ifdef __APPLE__
    #include <ext/hash_map>
-#else
+#elif LINUX
    #include <hash_map>
+#elif _MSC_VER < 1500
+   #include <hash_map>
+#elif _MSC_VER > 1800
+   #include <unordered_map>
 #endif
 #include "NvUserMemAlloc.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 double				NxF64;
 		
-#elif LINUX
+#elif defined(LINUX)
 	typedef long long			NxI64;
 	typedef signed int			NxI32;
 	typedef signed short		NxI16;
@@ -101,7 +101,7 @@ NvSimpleTypes.h : Defines basic data types for integers and floats.
 	typedef float				NxF32;
 	typedef double				NxF64;
 
-#elif __APPLE__
+#elif defined(__APPLE__)
 	typedef long long			NxI64;
 	typedef signed int			NxI32;
 	typedef signed short		NxI16;
@@ -115,7 +115,7 @@ NvSimpleTypes.h : Defines basic data types for integers and floats.
 	typedef float				NxF32;
 	typedef double				NxF64;
 
-#elif __CELLOS_LV2__
+#elif defined(__CELLOS_LV2__)
 	typedef long long			NxI64;
 	typedef signed int			NxI32;
 	typedef signed short		NxI16;
@@ -129,7 +129,7 @@ NvSimpleTypes.h : Defines basic data types for integers and floats.
 	typedef float				NxF32;
 	typedef double				NxF64;
 
-#elif _XBOX
+#elif defined(_XBOX)
 	typedef __int64				NxI64;
 	typedef signed int			NxI32;
 	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{
-    int i,j;
+    int i;
 
     for(i=0;i<n;){
       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 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;
    mTargetInLOS = false;
@@ -725,24 +725,20 @@ bool AIPlayer::setPathDestination(const Point3F &pos)
 
    // Create a new path.
    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;
+   }
 
    if(path->success())
    {
@@ -831,11 +827,15 @@ void AIPlayer::followObject(SceneObject *obj, F32 radius)
    if(!isServerObject())
       return;
 
+   if ((mFollowData.lastPos - obj->getPosition()).len()<mMoveTolerance)
+      return;
+
    if(setPathDestination(obj->getPosition()))
    {
       clearCover();
       mFollowData.object = obj;
       mFollowData.radius = radius;
+      mFollowData.lastPos = obj->getPosition();
    }
 }
 

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

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

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

@@ -279,6 +279,7 @@ Camera::Camera()
 
    mLastAbsoluteYaw = 0.0f;
    mLastAbsolutePitch = 0.0f;
+   mLastAbsoluteRoll = 0.0f;
 
    // For NewtonFlyMode
    mNewtonRotation = false;
@@ -379,6 +380,57 @@ void Camera::getCameraTransform(F32* pos, MatrixF* mat)
    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()
@@ -547,6 +599,7 @@ void Camera::processTick(const Move* move)
 
                mLastAbsoluteYaw = emove->rotZ[emoveIndex];
                mLastAbsolutePitch = emove->rotX[emoveIndex];
+               mLastAbsoluteRoll = emove->rotY[emoveIndex];
 
                // Bank
                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 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
       /// @{
@@ -235,6 +236,8 @@ class Camera: public ShapeBase
       virtual void processTick( const Move* move );
       virtual void interpolateTick( F32 delta);
       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 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;
 
    // 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->startDecal = i;
          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->matInst = decal->mDataBlock->getMaterialInstance();
          currentBatch->priority = decal->getRenderPriority();         
@@ -1299,15 +1321,21 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
       {
          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;            
          }
 
-         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!
          if ( (dinst->mFlags & CustomDecal) && dinst->mCustomTex != NULL )
@@ -1357,8 +1385,10 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
       pb->lock( &pbPtr );
 
       // 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();
       vb->unlock();

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

@@ -269,7 +269,7 @@ void RenderMeshExample::prepRenderImage( SceneRenderState *state )
       createGeometry();
 
    // If we have no material then skip out.
-   if ( !mMaterialInst )
+   if ( !mMaterialInst || !state)
       return;
 
    // 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)
 {
+   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
+
    // Background first
    if (mShowFill)
-      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
+      drawUtil->drawRectFill(updateRect, mFillColor);
 
    // Convert ms time into hours, minutes and seconds.
    S32 time = S32(getTime());
@@ -129,13 +131,13 @@ void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
    // Center the text
    offset.x += (getWidth() - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 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
    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  
          mValue = 100 - (100 * control->getDamageValue());    
    }  
+
+   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
   
    // If enabled draw background first  
    if (mShowFill)  
-      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);  
+      drawUtil->drawRectFill(updateRect, mFillColor);  
   
    // Prepare text and center it  
    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 (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
    // don't want to collide with the control object.
-   static U32 losMask = TerrainObjectType | ShapeBaseObjectType;
+   static U32 losMask = TerrainObjectType | ShapeBaseObjectType | StaticObjectType;
    control->disableCollision();
 
    // 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.y -= height / 2;
 
+   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
+
    // Background fill first
    if (mShowLabelFill)
-      GFX->getDrawUtil()->drawRectFill(RectI(offset, extent), mLabelFillColor);
+      drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor);
 
    // Deal with opacity and draw.
    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
    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.
    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;
 

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

@@ -86,7 +86,7 @@ public:
    fxFoliageCulledList(Box3F SearchBox, fxFoliageCulledList* InVec);
    ~fxFoliageCulledList() {};
 
-   void FindCandidates(Box3F SearchBox, fxFoliageCulledList* InVec);
+   void FindCandidates(const Box3F& SearchBox, fxFoliageCulledList* InVec);
 
    U32 GetListCount(void) { return mCulledObjectSet.size(); };
    fxFoliageItem* GetElement(U32 index) { return mCulledObjectSet[index]; };
@@ -157,7 +157,7 @@ protected:
 
    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 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 *)
 {
    //nothing to do on the server
-   if (isServerObject() || mDataBlock == NULL)
+   if (isServerObject() || mDataBlock == NULL || isHidden())
       return;
 
    const U32 currTime = Platform::getVirtualMilliseconds();

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

@@ -39,6 +39,9 @@
 #include "scene/sceneManager.h"    
 #define __SCENEMANAGER_H__  
 #endif
+#ifndef _IDISPLAYDEVICE_H_
+#include "platform/output/IDisplayDevice.h"
+#endif
 
 class NetConnection;
 class ProcessList;
@@ -418,6 +421,7 @@ public:
    
    // Not implemented here, but should return the Camera to world transformation matrix
    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
    /// classes to actually set this object.

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

@@ -235,6 +235,7 @@ GameConnection::GameConnection()
 
 GameConnection::~GameConnection()
 {
+   setDisplayDevice(NULL);
    delete mAuthInfo;
    for(U32 i = 0; i < mConnectArgc; i++)
       dFree(mConnectArgv[i]);
@@ -673,6 +674,30 @@ bool GameConnection::getControlCameraTransform(F32 dt, MatrixF* mat)
    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)
 {
    //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 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 getControlCameraFov(F32 *fov);
    bool setControlCameraFov(F32 fov);
@@ -280,8 +284,8 @@ public:
    void setFirstPerson(bool firstPerson);
    
    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 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
       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;
       bool fovSet = false;
 
@@ -358,14 +363,14 @@ bool GameProcessCameraQuery(CameraQuery *query)
       // is not open
       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
          if(display->providesProjectionOffset())
@@ -374,14 +379,34 @@ bool GameProcessCameraQuery(CameraQuery *query)
          }
 
          // 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
-      if(!fovSet && !connection->getControlCameraFov(&cameraFov))
+      if(!connection->getControlCameraFov(&cameraFov))
       {
          return false;
       }

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

@@ -55,10 +55,6 @@ bool GameTSCtrl::onAdd()
    if ( !Parent::onAdd() )
       return false;
 
-#ifdef TORQUE_DEMO_WATERMARK
-   mWatermark.init();
-#endif
-
    return true;
 }
 
@@ -172,10 +168,6 @@ void GameTSCtrl::onRender(Point2I offset, const RectI &updateRect)
 
    if(!skipRender || true)
       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"
 #endif
 
-#ifdef TORQUE_DEMO_WATERMARK
-#ifndef _WATERMARK_H_
-#include "demo/watermark/watermark.h"
-#endif
-#endif
-
 class ProjectileData;
 class GameBase;
 
@@ -45,10 +39,6 @@ class GameTSCtrl : public GuiTSCtrl
 private:
    typedef GuiTSCtrl Parent;
 
-#ifdef TORQUE_DEMO_WATERMARK
-   Watermark mWatermark;
-#endif
-
    void makeScriptCall(const char *func, const GuiEvent &evt) const;
 
 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;
    U32 posFrom, posTo;
    S32 keyFrameFrom, keyFrameTo;
+   F32 initialValue = *output;
    
    bool wasAnimated = false;
 
@@ -215,13 +216,13 @@ bool LightAnimData::AnimValue<COUNT>::animate( F32 time, F32 *output )
 	   valueRange = ( value2[i] - value1[i] ) / 25.0f;
 
       if ( !smooth[i] )
-   	   output[i] = value1[i] + ( keyFrameFrom * valueRange );
+         output[i] = (value1[i] + (keyFrameFrom * valueRange)) * initialValue;
       else
       {
          lerpFactor = scaledTime - posFrom;
    	   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() );
 	callback.m_collisionFilterGroup = mGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
 	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 );
    if ( callback.hasHit() )
@@ -434,9 +435,8 @@ void BtPlayer::findContact(   SceneObject **contactObject,
       if ( other == mGhostObject )
          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 )
          continue;

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

@@ -1650,6 +1650,7 @@ Player::Player()
 
    mLastAbsoluteYaw = 0.0f;
    mLastAbsolutePitch = 0.0f;
+   mLastAbsoluteRoll = 0.0f;
 }
 
 Player::~Player()
@@ -2608,6 +2609,7 @@ void Player::updateMove(const Move* move)
             }
             mLastAbsoluteYaw = emove->rotZ[emoveIndex];
             mLastAbsolutePitch = emove->rotX[emoveIndex];
+            mLastAbsoluteRoll = emove->rotY[emoveIndex];
 
             // Head bank
             mHead.y = emove->rotY[emoveIndex];
@@ -5584,6 +5586,57 @@ void Player::getMuzzleTransform(U32 imageSlot,MatrixF* mat)
    *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)
 {

+ 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 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
                                     ///< their mount, or another animation, comes through (or 13 seconds elapses).
@@ -683,6 +684,7 @@ public:
    void getEyeBaseTransform(MatrixF* mat, bool includeBank);
    void getRenderEyeTransform(MatrixF* mat);
    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 getMuzzleTransform(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.
       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
       updateSound();

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

@@ -40,7 +40,6 @@
 #include "scene/sceneRenderState.h"
 #include "scene/sceneObjectLightingPlugin.h"
 #include "T3D/fx/explosion.h"
-#include "T3D/fx/particleEmitter.h"
 #include "T3D/fx/cameraFXMgr.h"
 #include "environment/waterBlock.h"
 #include "T3D/debris.h"
@@ -154,19 +153,26 @@ ShapeBaseData::ShapeBaseData()
    shadowSphereAdjust( 1.0f ),
    shapeName( 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 ),
    drag( 0.0f ),
    density( 1.0f ),
    maxEnergy( 0.0f ),
    maxDamage( 1.0f ),
-   disabledLevel( 1.0f ),
    destroyedLevel( 1.0f ),
+   disabledLevel( 1.0f ),
    repairRate( 0.0033f ),
    eyeNode( -1 ),
    earNode( -1 ),
    cameraNode( -1 ),
-   damageSequence( -1 ),
-   hulkSequence( -1 ),
    cameraMaxDist( 0.0f ),
    cameraMinDist( 0.2f ),
    cameraDefaultFov( 75.0f ),
@@ -174,24 +180,17 @@ ShapeBaseData::ShapeBaseData()
    cameraMaxFov( 120.f ),
    cameraCanBank( 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 ),
    useEyePoint( false ),
-   cubeDescId( 0 ),
-   reflectorDesc( NULL ),
-   observeThroughObject( false ),
+   isInvincible( false ),
+   renderWhenDestroyed( true ),
    computeCRC( false ),
    inheritEnergyFromMount( false ),
-   mCRC( 0 ),
-   debrisDetail( -1 )
+   mCRC( 0 )
 {      
    dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
 }
@@ -878,46 +877,46 @@ IMPLEMENT_CALLBACK( ShapeBase, validateCameraFov, F32, (F32 fov), (fov),
    "@see ShapeBaseData\n\n");
 
 ShapeBase::ShapeBase()
- : mDrag( 0.0f ),
-   mBuoyancy( 0.0f ),
-   mWaterCoverage( 0.0f ),
-   mLiquidHeight( 0.0f ),
+ : mDataBlock( NULL ),
+   mIsAiControlled( false ),
    mControllingObject( NULL ),
-   mGravityMod( 1.0f ),
-   mAppliedForce( Point3F::Zero ),
-   mTimeoutList( NULL ),
-   mDataBlock( NULL ),
+   mMoveMotion( false ),
+   mShapeBaseMount( NULL ),
    mShapeInstance( NULL ),
+   mConvexList( new Convex ),
    mEnergy( 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 ),
    mRepairRate( 0.0f ),
    mRepairReserve( 0.0f ),
    mDamageState( Enabled ),
    mDamageThread( NULL ),
    mHulkThread( NULL ),
-   mLastRenderFrame( 0 ),
-   mLastRenderDistance( 0.0f ),
+   damageDir( 0.0f, 0.0f, 1.0f ),
    mCloaked( false ),
    mCloakLevel( 0.0f ),
-   mDamageFlash( 0.0f ),
-   mWhiteOut( 0.0f ),
-   mIsControlled( false ),
-   mConvexList( new Convex ),
-   mCameraFov( 90.0f ),
    mFadeOut( true ),
    mFading( false ),
    mFadeVal( 1.0f ),
-   mFadeTime( 1.0f ),
    mFadeElapsedTime( 0.0f ),
+   mFadeTime( 1.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;   
 
@@ -1192,13 +1191,13 @@ void ShapeBase::onDeleteNotify( SimObject *obj )
    Parent::onDeleteNotify( obj );      
 }
 
-void ShapeBase::onImpact(SceneObject* obj, VectorF vec)
+void ShapeBase::onImpact(SceneObject* obj, const VectorF& vec)
 {
    if (!isGhost())
       mDataBlock->onImpact_callback( this, obj, vec, vec.len() );
 }
 
-void ShapeBase::onImpact(VectorF vec)
+void ShapeBase::onImpact(const VectorF& vec)
 {
    if (!isGhost())
       mDataBlock->onImpact_callback( this, NULL, vec, vec.len() );
@@ -1969,6 +1968,75 @@ void ShapeBase::getCameraTransform(F32* pos,MatrixF* mat)
    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)
 {
    *min = mDataBlock->cameraMinDist;
@@ -1977,7 +2045,6 @@ void ShapeBase::getCameraParameters(F32 *min,F32* max,Point3F* off,MatrixF* rot)
    rot->identity();
 }
 
-
 //----------------------------------------------------------------------------
 F32 ShapeBase::getDamageFlash() const
 {

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

@@ -63,6 +63,8 @@
    #include "console/dynamicTypes.h"
 #endif
 
+// Need full definition visible for SimObjectPtr<ParticleEmitter>
+#include "T3D/fx/particleEmitter.h"
 
 class GFXCubemap;
 class TSShapeInstance;
@@ -70,8 +72,6 @@ class SceneRenderState;
 class TSThread;
 class GameConnection;
 struct CameraScopeQuery;
-class ParticleEmitter;
-class ParticleEmitterData;
 class ProjectileData;
 class ExplosionData;
 struct DebrisData;
@@ -1104,8 +1104,8 @@ protected:
    virtual void shakeCamera( U32 imageSlot );
    virtual void updateDamageLevel();
    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 
@@ -1583,6 +1583,13 @@ public:
    /// @param   mat   Camera transform (out)
    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
    /// @param   imageSlot   Image slot
    /// @param   nodeName    Node name

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

@@ -102,7 +102,7 @@ TSStatic::TSStatic()
    mPlayAmbient      = true;
    mAmbientThread    = NULL;
 
-   mAllowPlayerStep = true;
+   mAllowPlayerStep = false;
 
    mConvexList = new Convex;
 
@@ -1171,8 +1171,10 @@ DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Materia
       return;
    }
 
+   TSMaterialList* shapeMaterialList = object->getShape()->materialList;
+
    // 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)
    {
       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
    // 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
    const GFXVertexFormat *flags = getGFXVertexFormat<GFXVertexPNTTB>();
    FeatureSet features = MATMGR->getDefaultFeatures();
-   object->getShape()->materialList->getMaterialInst(matIndex)->init( features, flags );
+   shapeMaterialList->getMaterialInst(matIndex)->init(features, flags);
 }
 
 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.
    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)
@@ -1069,9 +1069,8 @@ void TurretShape::readPacketData(GameConnection *connection, BitStream *stream)
    Parent::readPacketData(connection, stream);
 
    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);
 
    mTurretDelta.rot = rot;
@@ -1100,8 +1099,8 @@ U32 TurretShape::packUpdate(NetConnection *connection, U32 mask, BitStream *stre
 
    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(allowManualFire);
    }
@@ -1137,8 +1136,8 @@ void TurretShape::unpackUpdate(NetConnection *connection, BitStream *stream)
    if (stream->readFlag())
    {
       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);
 
       // 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)
       mRigid.force += by * mDataBlock->jetForce;
 
+   // Add in force from physical zones...
+   mRigid.force += mAppliedForce;
+
    // Container drag & buoyancy
    mRigid.force  += Point3F(0, 0, -mBuoyancy * sWheeledVehicleGravity * mRigid.mass);
    mRigid.force  -= mRigid.linVelocity * mDrag;

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

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

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

@@ -139,22 +139,4 @@ DefineConsoleFunction( getBuildString, const char*, (), , "Get the type of build
 #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;
 }
 
-inline bool isOnPlane(Point3F p,PlaneF& plane)
+inline bool isOnPlane(const Point3F& p,PlaneF& plane)
 {
    F32 dist = mDot(plane,p) + plane.d;
    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* 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 );
    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 start = ip;
    U32 endifIp, elseIp;
    addBreakLine(codeStream);
    
@@ -340,7 +339,6 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
    addBreakLine(codeStream);
    codeStream.pushFixScope(true);
    
-   U32 start = ip;
    if(initExpr)
       ip = initExpr->compile(codeStream, ip, TypeReqNone);
 
@@ -1565,8 +1563,6 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
    
    CodeBlock::smInFunction = false;
    
-   
-   U32 start = ip;
    codeStream.emit(OP_FUNC_DECL);
    codeStream.emitSTE(fnName);
    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)
 {
-#ifdef TORQUE_DEBUG
+
+#ifdef TORQUE_VALIDATE_STACK
    U32 stackStart = STR.mStartStackSize;
    U32 consoleStackStart = CSTK.mStackPos;
 #endif
@@ -2245,9 +2246,9 @@ execFinished:
 
    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
 
    return returnValue;

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

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

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

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

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

@@ -34,10 +34,6 @@
 #include "core/util/journal/journal.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
 // link in this module which contains no other references.
 bool LinkConsoleFunctions = false;
@@ -480,7 +476,7 @@ DefineConsoleFunction( strreplace, const char*, ( const char* source, const char
       if(!scan)
       {
          dStrcpy(ret + dstp, source + scanp);
-         break;
+         return ret;
       }
       U32 len = scan - (source + scanp);
       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"),
    "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"
+   "@param path	relative path to splash screen image to display.\n"
    "@return True if the splash window could be successfully initialized.\n\n"
    "@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 *parentNS = Namespace::find(parentNSSTE);
-   Namespace *currentParent = childNS->getParent();
    
    if (!childNS)
    {
       return false;
    }
+
+   Namespace *currentParent = childNS->getParent();
    
    // 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");
 
 	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)

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

@@ -48,11 +48,7 @@
 /// @{
 
 #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
 
 class GFXShader;

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

@@ -318,6 +318,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
    DECLARE_ENUM( type ); \
    DefineConsoleType( Type ## type, type );
 
+#define DefineEnumType_R( type ) \
+   DECLARE_ENUM_R( type ); \
+   DefineConsoleType( Type ## type, type );
+
 #define _ConsoleEnumType( typeName, type, nativeType ) \
    S32 type; \
    ImplementConsoleTypeCasters( type, nativeType ) \
@@ -347,6 +351,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
    DECLARE_BITFIELD( type ); \
    DefineConsoleType( Type ## type, type );
 
+#define DefineBitfieldType_R( type ) \
+   DECLARE_BITFIELD_R( type ); \
+   DefineConsoleType( Type ## type, type );
+
 #define _ConsoleBitfieldType( typeName, type, nativeType ) \
    S32 type; \
    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
    // so that we don't have to explicitly define them.
    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() ) );
 
    return true;

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

@@ -77,7 +77,11 @@ struct EngineFunctionDefaultArguments
 
 
 // Need byte-aligned packing for the default argument structures.
+#ifdef _WIN64
+#pragma pack( push, 4 )
+#else
 #pragma pack( push, 1 )
+#endif
    
 
 // 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
@@ -52,7 +52,7 @@ DECLARE_PRIMITIVE( void* );
 // 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
 // will immediately copy and convert strings to their own string type.
-_DECLARE_TYPE( String );
+_DECLARE_TYPE_R(String);
 template<>
 struct EngineTypeTraits< String > : public _EnginePrimitiveTypeTraits< String >
 {

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

@@ -41,11 +41,11 @@ class ColorI;
 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_

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

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

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

@@ -416,6 +416,16 @@ namespace _Private {
 
 
 #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<> struct _SCOPE< type > {                                                        \
       EngineExportScope& operator()() const {                                                \
@@ -432,22 +442,42 @@ namespace _Private {
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    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 )                                                                \
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    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 )                                                            \
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    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 )                                                              \
    _DECLARE_TYPE( type )                                                                     \
    template<>                                                                                \
    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 )        \
    template<>                                      \
@@ -524,6 +554,10 @@ namespace _Private {
 #define DECLARE_PRIMITIVE( type ) \
    _DECLARE_PRIMITIVE( type )
 
+///
+#define DECLARE_PRIMITIVE_R( type ) \
+   _DECLARE_PRIMITIVE_R( type )
+
 ///
 #define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \
    _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc )
@@ -531,11 +565,19 @@ namespace _Private {
 ///
 #define DECLARE_ENUM( type ) \
    _DECLARE_ENUM( type )
+
+///
+#define DECLARE_ENUM_R( type ) \
+   _DECLARE_ENUM_R( type )
    
 ///
 #define DECLARE_BITFIELD( type ) \
    _DECLARE_BITFIELD( type )
 
+///
+#define DECLARE_BITFIELD_R( type ) \
+   _DECLARE_BITFIELD_R( type )
+
 ///
 #define IMPLEMENT_ENUM( type, exportName, scope, doc ) \
    _IMPLEMENT_ENUM( type, exportName, scope, doc )
@@ -556,6 +598,10 @@ namespace _Private {
 #define DECLARE_STRUCT( type ) \
    _DECLARE_STRUCT( type )
 
+///
+#define DECLARE_STRUCT_R( type ) \
+   _DECLARE_STRUCT_R( type )
+
 ///
 #define 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
 {
    DataBlockObjectIdFirst = 3,
-   DataBlockObjectIdBitSize = 10,
+   DataBlockObjectIdBitSize = 14,
    DataBlockObjectIdLast = DataBlockObjectIdFirst + (1 << DataBlockObjectIdBitSize) - 1,
 
    MessageObjectIdFirst = DataBlockObjectIdLast + 1,

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

@@ -44,9 +44,9 @@ public:
    static S32 _smTypeId;
 
    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
 {
    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);
    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 )
             : mType( type ),
-              mNext( mode == ModeInitialize ? parentModule->mInitDependencies : parentModule->mShutdownDependencies ),
               mModuleName( moduleName ),
-              mModule( NULL )
+              mModule( NULL ),
+              mNext( mode == ModeInitialize ? parentModule->mInitDependencies : parentModule->mShutdownDependencies )
          {
             if( mode == ModeInitialize )
                parentModule->mInitDependencies = this;
@@ -141,11 +141,12 @@ class Module
       }
             
       Module()
-         : mNext( smFirst ),
+         : mIsInitialized( false ),
+           mNext( smFirst ),
            mInitDependencies( NULL ),
            mShutdownDependencies( NULL ),
-           mOverrides( NULL ),
-           mIsInitialized( false )
+           mOverrides( NULL )
+
       {
          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)
 {
-   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);
    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;
 
-   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;

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

@@ -36,10 +36,12 @@
 // These standard functions are not defined on Win32 and other Microsoft platforms...
 #define strcasecmp   _stricmp
 #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
-#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
 #define FASTDELEGATE_H
-#if _MSC_VER > 1000
+#if defined(_MSC_VER) && (_MSC_VER > 1000)
 #pragma once
-#endif // _MSC_VER > 1000
-
+#endif // defined(_MSC_VER) && (_MSC_VER > 1000)
 
 ////////////////////////////////////////////////////////////////////////////////
 //						Configuration options

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

@@ -58,7 +58,7 @@ class RawDataT
       }
 
       RawDataT( T* data, U32 size, bool ownMemory = false )
-         : data( data ), size( size ), ownMemory( ownMemory ) {}
+         : ownMemory( ownMemory ), data( data ), size( size ) {}
 
       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);
    if (str && *str && len!=0)
    {
-      AssertFatal(len<=dStrlen(str), "String::String: string too short");
       _string = new ( len ) StringData( str );
    }
    else
@@ -657,6 +656,11 @@ bool String::isEmpty() const
    return ( _string == StringData::Empty() );
 }
 
+bool String::isEmpty(const char* str)
+{
+	return str == 0 || str[0] == '\0';
+}
+
 bool String::isShared() const
 {
    return _string->isShared();

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

@@ -62,7 +62,7 @@ public:
    String();
    String(const String &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();
 
@@ -74,6 +74,7 @@ public:
    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.
    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 [""]?
 
    /// Erases all characters in a string.
@@ -292,11 +293,10 @@ private:
    // causes an ambiguous cast compile error.  Making it private is simply
    // more insurance that it isn't used on different compilers.
    // 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; }
 #endif
 
-
    static void copy(StringChar *dst, const StringChar *src, U32 size);
 
    StringData   *_string;

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

@@ -45,7 +45,7 @@ class UnmanagedVector
       UnmanagedVector()
          : mCount( 0 ), mArray( NULL ) {}
       UnmanagedVector( T* array, U32 count )
-         : mArray( array ), mCount( count ) {}
+         : mCount( count ), mArray( array ) {}
 
       U32 size() const { return mCount; }
       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)
 {
-   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];
 }
 
 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];
 }
 

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -637,12 +637,13 @@ void ScatterSky::prepRenderImage( SceneRenderState *state )
       return;
 
    // 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->type = RenderPassManager::RIT_Sky;
    ri->defaultKey = 10;
    ri->defaultKey2 = 0;
-   state->getRenderPass()->addInst( ri );
+   renderPass->addInst(ri);
 
    // Debug render instance.
    /*
@@ -685,13 +686,13 @@ void ScatterSky::prepRenderImage( SceneRenderState *state )
       mMatrixSet->setSceneProjection(GFX->getProjectionMatrix());
       mMatrixSet->setWorld(GFX->getWorldMatrix());
 
-      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
+      ObjectRenderInst *ri = renderPass->allocInst<ObjectRenderInst>();
       ri->renderDelegate.bind( this, &ScatterSky::_renderMoon );
       ri->type = RenderPassManager::RIT_Sky;
       // Render after sky objects and before CloudLayer!
       ri->defaultKey = 5;
       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();
 
-   for ( ; itr != end(); itr++ )
+   for (; itr != end(); ++itr)
    {
       const MatrixF &mat = itr->getTransform();
       Point3F wPos;
@@ -450,10 +450,11 @@ void ForestSelectionTool::onRender2D()
       F32 hscale = wwidth * 2 / F32(mEditor->getWidth());
       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 );
 
       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 )
 {
-   if ( path )
+   if ( path && !String::isEmpty(path))
       mDataFileName = StringTable->insert( path );
 
    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;
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
    {
       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.   
 
    BucketTable::Iterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ ) delete iter->value;
+   for (; iter != mBuckets.end(); ++iter) delete iter->value;
    mBuckets.clear();
 
    mIsDirty = true;
@@ -408,7 +408,7 @@ const ForestItem& ForestData::findItem( ForestItemKey key ) const
 
    Vector<const ForestCell*> stack;
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
 
    // Now loop till we run out of cells.
@@ -444,7 +444,7 @@ U32 ForestData::getItems( Vector<ForestItem> *outItems ) const
    U32 count = 0;
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
 
    // 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;
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
 
    // 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;
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
          stack.push_back( iter->value );
 
    const F32 radiusSq = radius * radius;
@@ -629,7 +629,7 @@ U32 ForestData::getItems( const Point2F &point, F32 radius, Vector<ForestItem> *
    U32 count = 0;
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
          stack.push_back( iter->value );
 
    const F32 radiusSq = radius * radius;
@@ -686,7 +686,7 @@ U32 ForestData::getItems( const ForestItemData *data, Vector<ForestItem> *outIte
    U32 count = 0;
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
 
    // 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 );
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
    {
       if ( !frustum.isCulled( iter->value->getBounds() ) )
          outCells->push_back( iter->value );
@@ -736,7 +736,7 @@ void ForestData::getCells( Vector<ForestCell*> *outCells ) const
    PROFILE_SCOPE( ForestData_getCells_nofrustum );
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )         
+   for (; iter != mBuckets.end(); ++iter)
       outCells->push_back( iter->value );
 }
 
@@ -746,7 +746,7 @@ U32 ForestData::getDatablocks( Vector<ForestItemData*> *outVector ) const
    U32 count = 0;
 
    BucketTable::ConstIterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
 
    // Now loop till we run out of cells.
@@ -786,7 +786,7 @@ void ForestData::clearPhysicsRep( Forest *forest )
    Vector<ForestCell*> stack;
 
    BucketTable::Iterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
 
    // Now loop till we run out of cells.
@@ -812,7 +812,7 @@ void ForestData::buildPhysicsRep( Forest *forest )
    Vector<ForestCell*> stack;
 
    BucketTable::Iterator iter = mBuckets.begin();
-   for ( ; iter != mBuckets.end(); iter++ )
+   for (; iter != mBuckets.end(); ++iter)
       stack.push_back( iter->value );
 
    // 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.
       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();
          if ( camDist < mWindRadius )

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

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

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

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

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

@@ -76,7 +76,7 @@ inline void D3D9Assert( HRESULT hr, const char *info )
 
 // Typedefs
 #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"
 #undef D3DX_FUNCTION
 
@@ -238,7 +238,7 @@ protected:
    // }
 
    virtual GFXShader* createShader();
-   void disableShaders();
+   void disableShaders(bool force = false);
 
    /// Device helper function
    virtual D3DPRESENT_PARAMETERS setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd ) const = 0;
@@ -272,7 +272,7 @@ public:
 
    virtual F32  getPixelShaderVersion() const { return mPixVersion; }
    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  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 ) \
    for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
-      if( (S32)tablearray##[i] == val ) \
+      if( (S32)tablearray[i] == val ) \
       { \
          val = i; \
          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 ) \
    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 ) \
    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 ); \
-      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 );
 
 //------------------------------------------------------------------------------

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

@@ -66,7 +66,7 @@ void GFXPCD3D9Device::createDirect3D9(LPDIRECT3D9 &d3d9, LPDIRECT3D9EX &d3d9ex)
       
       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));
       }
 

+ 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;)
    {
+      U32 wide = 0; 
       startLine = i;
       startLineOffset.push_back(startLine);
 
@@ -584,6 +585,10 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
          else if(isValidChar(txt[i]))
          {
             lineStrWidth += getCharInfo(txt[i]).xIncrement;
+            if(txt[i] < 0) // symbols which code > 127
+            {  
+               wide++; i++;
+            }
             if( lineStrWidth > lineWidth )
             {
                needsNewLine = true;
@@ -595,7 +600,7 @@ void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOff
       if (!needsNewLine)
       {
          // we are done!
-         lineLen.push_back(i - startLine);
+         lineLen.push_back(i - startLine - wide);
          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;
 
       // 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.
       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.
-      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);
-      glyphList.last().bitmap->copyRect(strip, ri, outRi); 
+      lastGlyphMap.bitmap->copyRect(strip, ri, outRi);
 
       // 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].xIncrement += kerning;
       mCharInfoList[i].yOffset -= padding;

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

@@ -161,7 +161,6 @@ GFXDevice::GFXDevice()
    mAllowRender = true;
    mCurrentRenderStyle = RS_Standard;
    mCurrentProjectionOffset = Point2F::Zero;
-   mStereoEyeOffset = Point3F::Zero;
    mCanCurrentlyRender = false;
    mInitialized = false;
    
@@ -197,6 +196,9 @@ GFXDevice::GFXDevice()
    #elif defined TORQUE_OS_PS3
       GFXShader::addGlobalMacro( "TORQUE_OS_PS3" );            
    #endif
+
+   mStereoTargets[0] = NULL;
+   mStereoTargets[1] = NULL;
 }
 
 GFXDrawUtil* GFXDevice::getDrawUtil()
@@ -733,14 +735,14 @@ void GFXDevice::setLight(U32 stage, GFXLightInfo* light)
 //-----------------------------------------------------------------------------
 // Set Light Material
 //-----------------------------------------------------------------------------
-void GFXDevice::setLightMaterial(GFXLightMaterial mat)
+void GFXDevice::setLightMaterial(const GFXLightMaterial& mat)
 {
    mCurrentLightMaterial = mat;
    mLightMaterialDirty = true;
    mStateDirty = true;
 }
 
-void GFXDevice::setGlobalAmbientColor(ColorF color)
+void GFXDevice::setGlobalAmbientColor(const ColorF& 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
       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)
       deStartOfField,
 
@@ -244,7 +247,12 @@ public:
    enum GFXDeviceRenderStyles
    {
       RS_Standard          = 0,
-      RS_StereoSideBySide  = (1<<0),
+      RS_StereoSideBySide  = (1<<0),     // Render into current Render Target side-by-side
+   };
+
+   enum GFXDeviceLimits
+   {
+      NumStereoPorts = 2
    };
 
 private:
@@ -277,7 +285,19 @@ protected:
    Point2F mCurrentProjectionOffset;
 
    /// 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
    /// have operations performed on it.
@@ -323,10 +343,50 @@ public:
    void setCurrentProjectionOffset(const Point2F& offset) { mCurrentProjectionOffset = offset; }
 
    /// 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
-   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; }
 
@@ -722,8 +782,8 @@ public:
    /// Returns the number of simultaneous render targets supported by the device.
    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)
    void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
@@ -841,8 +901,8 @@ public:
    /// because of the state caching stuff.
    /// @{
    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
          // now to completely remove it from the pool.
          TexturePoolMap::Iterator unref = iter;
-         iter++;
+         ++iter;
          unref->value = NULL;
          mTexturePool.erase( unref );
          continue;
       }
 
-      iter++;
+      ++iter;
    }
 }
 
@@ -1041,7 +1041,8 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height,
    }
 
    // 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 )
    {
@@ -1057,16 +1058,16 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height,
       {
          case GFXFormatR8G8B8:
             testingFormat = GFXFormatR8G8B8X8;
-            chekFmt = GFX->getCardProfiler()->checkFormat( testingFormat, profile, autoGenSupp );
+            chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);
             break;
 
          case GFXFormatA8:
             testingFormat = GFXFormatR8G8B8A8;
-            chekFmt = GFX->getCardProfiler()->checkFormat( testingFormat, profile, autoGenSupp );
+            chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);
             break;
          
          default:
-            chekFmt = GFX->getCardProfiler()->checkFormat( testingFormat, profile, autoGenSupp );
+            chekFmt = cardProfiler->checkFormat(testingFormat, profile, autoGenSupp);
             break;
       }
    }

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

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

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

@@ -114,10 +114,11 @@ void GFXVertexFormat::addElement( const String& semantic, GFXDeclType type, U32
 { 
    mDirty = true;
    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

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

@@ -14,7 +14,9 @@ public:
 
    ~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)
@@ -87,7 +89,9 @@ public:
 
    ~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 )

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

@@ -22,6 +22,7 @@
 
 #include "platform/platform.h"
 #include "gui/3d/guiTSControl.h"
+#include "gui/core/guiOffscreenCanvas.h"
 
 #include "console/engineAPI.h"
 #include "scene/sceneManager.h"
@@ -34,7 +35,12 @@
 #include "scene/reflectionManager.h"
 #include "postFx/postEffectManager.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 );
 
@@ -51,6 +57,7 @@ ConsoleDocClass( GuiTSCtrl,
 );
 
 U32 GuiTSCtrl::smFrameCount = 0;
+bool GuiTSCtrl::smUseLatestDisplayTransform = true;
 Vector<GuiTSCtrl*> GuiTSCtrl::smAwakeTSCtrls;
 
 ImplementEnumType( GuiTSRenderStyles,
@@ -60,7 +67,6 @@ ImplementEnumType( GuiTSRenderStyles,
 	{ GuiTSCtrl::RenderStyleStereoSideBySide, "stereo side by side"   },
 EndImplementEnumType;
 
-
 //-----------------------------------------------------------------------------
 
 namespace 
@@ -153,7 +159,8 @@ GuiTSCtrl::GuiTSCtrl()
    mLastCameraQuery.nearPlane = 0.01f;
 
    mLastCameraQuery.projectionOffset = Point2F::Zero;
-   mLastCameraQuery.eyeOffset = Point3F::Zero;
+   mLastCameraQuery.hasFovPort = false;
+   mLastCameraQuery.hasStereoTargets = 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"
 	   "@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!" );
    smAwakeTSCtrls.push_back( this );
 
+   // For VR
+   mLastCameraQuery.drawCanvas = getRoot();
+
    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)
 {
 	// Save the current transforms so we can restore
    // it for child control rendering below.
    GFXTransformSaver saver;
+   bool renderingToTarget = false;
 
    if(!processCameraQuery(&mLastCameraQuery))
    {
@@ -317,15 +370,70 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
       return;
    }
 
+   GFXTargetRef origTarget = GFX->getActiveRenderTarget();
+
    // Set up the appropriate render style
    U32 prevRenderStyle = GFX->getCurrentRenderStyle();
    Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
-   Point3F prevEyeOffset = GFX->getStereoEyeOffset();
+   Point2I renderSize = getExtent();
+
    if(mRenderStyle == RenderStyleStereoSideBySide)
    {
       GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
       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
    {
@@ -354,41 +462,37 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
       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;
    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
    {
+      // 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 right = (updateRect.point.x + updateRect.extent.x - offset.x) * hscale - wwidth;
       F32 top = wheight - vscale * (updateRect.point.y - offset.y);
@@ -407,15 +511,24 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &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
    GFX->clear( GFXClearZBuffer , ColorI(20,20,20), 1.0f, 0 );
+   //GFX->clear( GFXClearTarget, ColorI(255,0,0), 1.0f, 0);
 
    GFX->setFrustum( frustum );
    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
    // pixels - let the scene know so that it can calculate e.g. reflections
    // 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 
    // change the cameraMatrix in mLastCameraQuery. This is because 
@@ -455,20 +568,119 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
    renderWorld(updateRect);
    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
    // we begin rendering the child controls.
    saver.restore();
 
    // Restore the render style and any stereo parameters
+   GFX->setActiveRenderTarget(origTarget);
    GFX->setCurrentRenderStyle(prevRenderStyle);
    GFX->setCurrentProjectionOffset(prevProjectionOffset);
-   GFX->setStereoEyeOffset(prevEyeOffset);
+
+   
+   if(mRenderStyle == RenderStyleStereoSideBySide && gLastStereoTexture)
+   {
+      GFX->setClipRect(updateRect);
+      GFX->getDrawUtil()->drawBitmapStretch(gLastStereoTexture, updateRect);
+   }
 
    // Allow subclasses to render 2D elements.
    GFX->setClipRect(updateRect);
    renderGui( offset, updateRect );
 
-   renderChildControls(offset, updateRect);
+   if (shouldRenderChildControls())
+   {
+      renderChildControls(offset, updateRect);
+   }
    smFrameCount++;
 }
 
@@ -499,6 +711,12 @@ void GuiTSCtrl::drawLineList( const Vector<Point3F> &points, const ColorI color,
       drawLine( points[i], points[i+1], color, width );
 }
 
+
+void GuiTSCtrl::setStereoGui(GuiOffscreenCanvas *canvas)
+{
+   mStereoGuiTarget = canvas ? canvas->getTarget() : NULL;
+}
+
 //=============================================================================
 //    Console Methods.
 //=============================================================================
@@ -547,3 +765,10 @@ DefineEngineMethod( GuiTSCtrl, calculateViewDistance, F32, ( F32 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"
 #endif
 
+
+#ifndef _MATTEXTURETARGET_H_
+#include "materials/matTextureTarget.h"
+#endif
+
+class IDisplayDevice;
+class GuiOffscreenCanvas;
+
 struct CameraQuery
 {
    SimObject*  object;
    F32         nearPlane;
    F32         farPlane;
    F32         fov;
+   FovPort     fovPort[2]; // fov for each eye
    Point2F     projectionOffset;
-   Point3F     eyeOffset;
+   Point3F     eyeOffset[2];
+   MatrixF     eyeTransforms[2];
    bool        ortho;
+   bool        hasFovPort;
+   bool        hasStereoTargets;
    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.
@@ -50,11 +65,12 @@ class GuiTSCtrl : public GuiContainer
 public:
    enum RenderStyles {
       RenderStyleStandard           = 0,
-      RenderStyleStereoSideBySide   = (1<<0),
+      RenderStyleStereoSideBySide   = (1<<0)
    };
 
 protected:
    static U32     smFrameCount;
+   static bool    smUseLatestDisplayTransform;
    F32            mCameraZRot;
    F32            mForceFOV;
 
@@ -83,7 +99,11 @@ protected:
 
    /// The last camera query set in onRender.
    /// @see getLastCameraQuery
-   CameraQuery mLastCameraQuery;	
+   CameraQuery mLastCameraQuery;
+
+   NamedTexTargetRef mStereoGuiTarget;
+   GFXVertexBufferHandle<GFXVertexPCT> mStereoOverlayVB;
+   GFXStateBlockRef mStereoGuiSB;
    
 public:
    
@@ -155,6 +175,10 @@ public:
 
    static const U32& getFrameCount() { return smFrameCount; }
 
+   bool shouldRenderChildControls() { return mRenderStyle == RenderStyleStandard; }
+
+   void setStereoGui(GuiOffscreenCanvas *canvas);
+
    DECLARE_CONOBJECT(GuiTSCtrl);
    DECLARE_CATEGORY( "Gui 3D" );
    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 )
 {
-   RectI oldBounds = getBounds();
-   Point2I minExtent = getMinExtent();
-
    if( !Parent::resize( newPosition, newExtent ) )
       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; }
 
       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, () );
       /// @}
+      virtual void processTick();
 
    public:
    
@@ -152,7 +153,6 @@ class GuiRolloutCtrl : public GuiTickCtrl
 
       // Sizing Animation Functions
       void animateTo( S32 height );
-      virtual void processTick();
 
       void collapse() { animateTo( mHeader.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)
 {
    scrollTo(mChildRelPos.x + deltaX, mChildRelPos.y + deltaY);
+
+   onScroll_callback();
 }
 
 //-----------------------------------------------------------------------------
@@ -1091,8 +1093,9 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     }
 
     // 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.
     pos.y += mBitmapBounds[upArrowBitmap].extent.y;
@@ -1118,8 +1121,8 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     if ( trackRect.extent.y > 0 )
     {
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, trackRect, mBitmapBounds[trackBitmap] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, trackRect, mBitmapBounds[trackBitmap]);
     }
 
     // Update Pos.
@@ -1137,8 +1140,8 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     }
 
     // Render Down Arrow.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[downArrowBitmap] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[downArrowBitmap]);
 
     // Render the Thumb?
     if ( !mVBarEnabled )
@@ -1163,8 +1166,8 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     }
 
     // Render Thumb Top.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[thumbBitmapTop] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapTop]);
 
     // Update Pos.
     pos.y += mBitmapBounds[thumbBitmapTop].extent.y;
@@ -1179,16 +1182,16 @@ void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
     if ( thumbRect.extent.y > 0 )
     {
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle]);
     }
 
     // Update Pos.
     pos.y += thumbRect.extent.y;
 
     // 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.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[leftArrowBitmap] );
+    GFXDrawUtil* drawUtil = GFX->getDrawUtil();
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[leftArrowBitmap]);
 
     // Update Pos.
     pos.x += mBitmapBounds[leftArrowBitmap].extent.x;
@@ -1242,8 +1246,8 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     if ( trackRect.extent.x > 0 )
     {
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, trackRect, mBitmapBounds[trackBitmap] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, trackRect, mBitmapBounds[trackBitmap]);
     }
 
     // Update Pos.
@@ -1261,8 +1265,8 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     }
 
     // Render Right Arrow.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[rightArrowBitmap] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[rightArrowBitmap]);
 
     // Render the Thumb?
     if ( !mHBarEnabled )
@@ -1287,8 +1291,8 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     }
 
     // Render Thumb Left.
-    GFX->getDrawUtil()->clearBitmapModulation();
-    GFX->getDrawUtil()->drawBitmapSR( mTextureObject, pos, mBitmapBounds[thumbBitmapLeft] );
+    drawUtil->clearBitmapModulation();
+    drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapLeft]);
 
     // Update Pos.
     pos.x += mBitmapBounds[thumbBitmapLeft].extent.x;
@@ -1303,16 +1307,16 @@ void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
     if ( thumbRect.extent.x > 0 )
     {
         // Render Track.
-        GFX->getDrawUtil()->clearBitmapModulation();
-        GFX->getDrawUtil()->drawBitmapStretchSR( mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle] );
+       drawUtil->clearBitmapModulation();
+       drawUtil->drawBitmapStretchSR(mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle]);
     }
 
     // Update Pos.
     pos.x += thumbRect.extent.x;
 
     // 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 )
       return;

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

@@ -84,7 +84,7 @@ public:
    virtual inline Point2I getSplitPoint() { return mSplitPoint; };
    /// The Splitters entire Client Rectangle, this takes into account padding of this control
    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;   
 
 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();
    ColorI oldColor;
@@ -622,7 +622,7 @@ S32 GuiTabBookCtrl::calculatePageTabWidth( GuiTabPageCtrl *page )
 
    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;
 
    GFont *font = mProfile->mFont;

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