Browse Source

Merge branch 'GarageGames/master' into ueberengine-dev

Duion 10 years ago
parent
commit
3831cd6ccf
100 changed files with 700 additions and 291 deletions
  1. 5 1
      Engine/lib/convexDecomp/NvRemoveTjunctions.cpp
  2. 1 1
      Engine/lib/libvorbis/lib/codebook.c
  3. 1 1
      Engine/source/T3D/convexShape.cpp
  4. 38 8
      Engine/source/T3D/decal/decalManager.cpp
  5. 1 1
      Engine/source/T3D/examples/renderMeshExample.cpp
  6. 3 2
      Engine/source/T3D/lightAnimData.cpp
  7. 1 1
      Engine/source/console/arrayObject.cpp
  8. 0 4
      Engine/source/console/astNodes.cpp
  9. 5 4
      Engine/source/console/compiledEval.cpp
  10. 2 1
      Engine/source/console/consoleFunctions.cpp
  11. 2 1
      Engine/source/console/consoleObject.cpp
  12. 8 0
      Engine/source/console/dynamicTypes.h
  13. 9 9
      Engine/source/console/enginePrimitives.h
  14. 6 6
      Engine/source/console/engineStructs.h
  15. 1 1
      Engine/source/console/engineTypeInfo.h
  16. 47 1
      Engine/source/console/engineTypes.h
  17. 1 1
      Engine/source/console/sim.h
  18. 1 1
      Engine/source/console/typeValidators.cpp
  19. 2 2
      Engine/source/core/util/tVector.h
  20. 2 2
      Engine/source/forest/forestWindEmitter.cpp
  21. 1 1
      Engine/source/gfx/D3D9/pc/gfxPCD3D9Device.cpp
  22. 7 2
      Engine/source/gfx/gFont.cpp
  23. 6 2
      Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h
  24. 6 8
      Engine/source/gui/3d/guiTSControl.cpp
  25. 0 3
      Engine/source/gui/containers/guiContainer.cpp
  26. 2 0
      Engine/source/gui/containers/guiScrollCtrl.cpp
  27. 1 1
      Engine/source/gui/containers/guiTabBookCtrl.cpp
  28. 1 1
      Engine/source/gui/containers/guiWindowCtrl.cpp
  29. 4 1
      Engine/source/gui/controls/guiConsoleTextCtrl.cpp
  30. 5 5
      Engine/source/gui/controls/guiMLTextCtrl.cpp
  31. 3 1
      Engine/source/gui/controls/guiTextEditCtrl.cpp
  32. 34 25
      Engine/source/gui/core/guiControl.cpp
  33. 73 56
      Engine/source/gui/editor/guiMenuBar.cpp
  34. 5 2
      Engine/source/gui/editor/guiMenuBar.h
  35. 4 0
      Engine/source/gui/editor/guiShapeEdPreview.cpp
  36. 9 14
      Engine/source/gui/utility/guiMouseEventCtrl.cpp
  37. 9 9
      Engine/source/gui/utility/guiMouseEventCtrl.h
  38. 1 1
      Engine/source/gui/worldEditor/worldEditor.cpp
  39. 2 4
      Engine/source/materials/processedShaderMaterial.cpp
  40. 1 1
      Engine/source/math/mMatrix.cpp
  41. 28 1
      Engine/source/math/mPoint3.h
  42. 43 28
      Engine/source/math/mQuat.cpp
  43. 1 1
      Engine/source/math/mQuat.h
  44. 2 2
      Engine/source/math/mRandom.cpp
  45. 1 1
      Engine/source/math/mRandom.h
  46. 3 0
      Engine/source/math/mSphere.cpp
  47. 0 1
      Engine/source/navigation/guiNavEditorCtrl.cpp
  48. 48 2
      Engine/source/platform/threads/test/threadPoolTest.cpp
  49. 25 1
      Engine/source/platform/threads/threadPool.cpp
  50. 26 1
      Engine/source/platform/threads/threadPool.h
  51. 61 9
      Engine/source/platformSDL/menus/menuBarSDL.cpp
  52. 4 0
      Engine/source/platformSDL/sdlMsgBox.cpp
  53. 1 1
      Engine/source/platformWin32/winFileio.cpp
  54. 11 0
      Engine/source/platformWin32/winVolume.cpp
  55. 1 0
      Engine/source/platformWin32/winVolume.h
  56. 1 1
      Engine/source/postFx/postEffect.cpp
  57. 13 14
      Engine/source/renderInstance/renderPrePassMgr.cpp
  58. 5 0
      Engine/source/scene/sceneContainer.cpp
  59. 2 2
      Engine/source/scene/sceneObject.cpp
  60. 10 2
      Engine/source/shaderGen/GLSL/bumpGLSL.cpp
  61. 10 2
      Engine/source/shaderGen/HLSL/bumpHLSL.cpp
  62. 1 1
      Engine/source/sim/netConnection.cpp
  63. 1 1
      Engine/source/sim/netConnection.h
  64. 10 4
      Engine/source/terrain/glsl/terrFeatureGLSL.cpp
  65. 10 3
      Engine/source/terrain/hlsl/terrFeatureHLSL.cpp
  66. 2 1
      Engine/source/ts/tsMesh.cpp
  67. 2 2
      Engine/source/ts/tsMeshFit.cpp
  68. 11 7
      Engine/source/windowManager/sdl/sdlWindow.cpp
  69. 3 0
      Engine/source/windowManager/sdl/sdlWindow.h
  70. 19 14
      Engine/source/windowManager/windowInputGenerator.cpp
  71. 1 0
      Templates/Empty/game/core/scripts/client/defaults.cs
  72. 1 1
      Templates/Empty/game/core/scripts/gui/messageBoxes/messageBox.ed.cs
  73. 17 2
      Templates/Empty/game/shaders/common/gl/torque.glsl
  74. 15 0
      Templates/Empty/game/shaders/common/torque.hlsl
  75. 1 1
      Templates/Empty/game/tools/base/menuBar/menuBuilder.ed.cs
  76. 0 0
      Templates/Empty/game/tools/classIcons/BasicClouds.png
  77. 0 0
      Templates/Empty/game/tools/classIcons/Camera.png
  78. 0 0
      Templates/Empty/game/tools/classIcons/CameraBookmark.png
  79. 0 0
      Templates/Empty/game/tools/classIcons/CloudLayer.png
  80. 0 0
      Templates/Empty/game/tools/classIcons/ConvexShape.png
  81. 0 0
      Templates/Empty/game/tools/classIcons/DecalRoad.png
  82. 0 0
      Templates/Empty/game/tools/classIcons/Forest.png
  83. 0 0
      Templates/Empty/game/tools/classIcons/ForestBrush.png
  84. 0 0
      Templates/Empty/game/tools/classIcons/GroundCover.png
  85. 0 0
      Templates/Empty/game/tools/classIcons/GroundPlane.png
  86. 0 0
      Templates/Empty/game/tools/classIcons/GuiControl.png
  87. 0 0
      Templates/Empty/game/tools/classIcons/GuiFadeinBitmapCtrl.png
  88. 0 0
      Templates/Empty/game/tools/classIcons/Item.png
  89. 0 0
      Templates/Empty/game/tools/classIcons/LevelInfo.png
  90. 0 0
      Templates/Empty/game/tools/classIcons/Lightning.png
  91. 0 0
      Templates/Empty/game/tools/classIcons/Marker.png
  92. 0 0
      Templates/Empty/game/tools/classIcons/MeshRoad.png
  93. 0 0
      Templates/Empty/game/tools/classIcons/MissionArea.png
  94. 0 0
      Templates/Empty/game/tools/classIcons/ParticleEmitter.png
  95. 0 0
      Templates/Empty/game/tools/classIcons/ParticleEmitterNode.png
  96. 0 0
      Templates/Empty/game/tools/classIcons/Path.png
  97. 0 0
      Templates/Empty/game/tools/classIcons/PhysicalZone.png
  98. 0 0
      Templates/Empty/game/tools/classIcons/Player.png
  99. 0 0
      Templates/Empty/game/tools/classIcons/PointLight.png
  100. 0 0
      Templates/Empty/game/tools/classIcons/Portal.png

+ 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"

+ 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;

+ 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 

+ 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;
       }
    }
 

+ 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;

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

@@ -476,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);
@@ -1594,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
    

+ 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 ) \

+ 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_

+ 1 - 1
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

+ 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,

+ 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);
 };

+ 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];
 }
 

+ 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 )

+ 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));
       }
 

+ 7 - 2
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

+ 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 )

+ 6 - 8
Engine/source/gui/3d/guiTSControl.cpp

@@ -578,14 +578,12 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
       GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
       const FovPort *currentFovPort = GFX->getStereoFovPort();
       const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
-      const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();
       const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
+      Frustum gfxFrustum = originalFrustum;
 
       for (U32 i=0; i<2; i++)
       {
          GFX->activateStereoTarget(i);
-         Frustum gfxFrustum = originalFrustum;
-         const F32 frustumDepth = gfxFrustum.getNearDist();
          MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]);
          GFX->setFrustum(gfxFrustum);
 
@@ -618,11 +616,11 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
             F32 screenBottom = rectHeight * 0.5;
 
             const F32 fillConv = 0.0f;
-            const F32 frustumDepth = gfxFrustum.getNearDist() + 0.012;
-            verts[0].point.set( screenLeft  - fillConv, frustumDepth, screenTop    - fillConv );
-            verts[1].point.set( screenRight - fillConv, frustumDepth, screenTop    - fillConv );
-            verts[2].point.set( screenLeft  - fillConv, frustumDepth, screenBottom - fillConv );
-            verts[3].point.set( screenRight - fillConv, frustumDepth, screenBottom - fillConv );
+            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);
 

+ 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;
    

+ 2 - 0
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();
 }
 
 //-----------------------------------------------------------------------------

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

@@ -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;

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

@@ -1212,7 +1212,7 @@ void GuiWindowCtrl::onMouseUp(const GuiEvent &event)
       // We're either moving out of a collapse group or moving to another one
       // Not valid for windows not previously in a group
       if( mCollapseGroup >= 0 && 
-         ( snapType == -1 || ( snapType >= 0 && mCollapseGroup != hitWindow->mCollapseGroup) ) )
+		  (snapType == -1 || (hitWindow && snapType >= 0 && mCollapseGroup != hitWindow->mCollapseGroup)))
          moveFromCollapseGroup();
       
       // No window to connect to

+ 4 - 1
Engine/source/gui/controls/guiConsoleTextCtrl.cpp

@@ -113,7 +113,10 @@ void GuiConsoleTextCtrl::onPreRender()
 {   
    if ( mConsoleExpression.isNotEmpty() )
    {
-      mResult = (const char*)Con::evaluatef( "$guiConsoleTextCtrlTemp = %s;", mConsoleExpression.c_str() );
+      Con::evaluatef( "$guiConsoleTextCtrlTemp = %s;", mConsoleExpression.c_str() );
+      
+      //Fixes a bug with the above not always grabbing the console text.
+      mResult = Con::getVariable("$guiConsoleTextCtrlTemp");
       
       // Of the resulting string we will be printing,
       // Find the number of lines and length of each.      

+ 5 - 5
Engine/source/gui/controls/guiMLTextCtrl.cpp

@@ -168,7 +168,7 @@ DefineEngineMethod( GuiMLTextCtrl, scrollToTag, void, (S32 tagID),,
    object->scrollToTag( tagID );
 }
 
-DefineEngineMethod( GuiMLTextCtrl, scrollToTop, void, ( S32 param1, S32 param2),,
+DefineEngineMethod( GuiMLTextCtrl, scrollToTop, void, (),,
    "@brief Scroll to the top of the text.\n\n"
    "@tsexample\n"
    "// Inform GuiMLTextCtrl object to scroll to its top\n"
@@ -631,7 +631,7 @@ bool GuiMLTextCtrl::setCursorPosition(const S32 newPosition)
       mCursorPosition = 0;
       return true;
    }
-   else if (newPosition >= mTextBuffer.length()) 
+   else if (newPosition >= mTextBuffer.length() - 1)
    {
       mCursorPosition = mTextBuffer.length();
       return true;
@@ -669,11 +669,11 @@ void GuiMLTextCtrl::getCursorPositionAndColor(Point2I &cursorTop, Point2I &curso
 {
    S32 x = 0;
    S32 y = 0;
-   S32 height = mProfile->mFont->getHeight();
+   S32 height = (mProfile && mProfile->mFont) ? mProfile->mFont->getHeight() : 0;
    color = mProfile->mCursorColor;
    for(Line *walk = mLineList; walk; walk = walk->next)
    {
-      if ((mCursorPosition <= walk->textStart + walk->len) || (walk->next == NULL))
+      if ((mCursorPosition < walk->textStart + walk->len) || (walk->next == NULL))
       {
          // it's in the atoms on this line...
          y = walk->y;
@@ -768,7 +768,7 @@ void GuiMLTextCtrl::onMouseDown(const GuiEvent& event)
    mSelectionAnchorDropped = event.mousePoint;
    if (mSelectionAnchor < 0)
       mSelectionAnchor = 0;
-   else if (mSelectionAnchor >= mTextBuffer.length())
+   else if (mSelectionAnchor >= mTextBuffer.length() - 1)
       mSelectionAnchor = mTextBuffer.length();
 
    mVertMoveAnchorValid = false;

+ 3 - 1
Engine/source/gui/controls/guiTextEditCtrl.cpp

@@ -213,7 +213,7 @@ void GuiTextEditCtrl::execConsoleCallback()
 
    // Update the console variable:
    if ( mConsoleVariable[0] )
-      Con::setVariable( mConsoleVariable, mTextBuffer.getPtr8() );
+      Con::setVariable(mConsoleVariable, mTextBuffer.getPtr8());
 }
 
 void GuiTextEditCtrl::updateHistory( StringBuffer *inTxt, bool moveIndex )
@@ -374,6 +374,8 @@ S32 GuiTextEditCtrl::calculateCursorPos( const Point2I &globalPos )
 
 void GuiTextEditCtrl::onMouseDown( const GuiEvent &event )
 {
+   if(!isActive())
+      return;
    mDragHit = false;
 
    // If we have a double click, select all text.  Otherwise

+ 34 - 25
Engine/source/gui/core/guiControl.cpp

@@ -604,6 +604,8 @@ void GuiControl::setUpdate()
 void GuiControl::renderJustifiedText(Point2I offset, Point2I extent, const char *text)
 {
    GFont *font = mProfile->mFont;
+   if(!font)
+      return;
    S32 textWidth = font->getStrWidthPrecise((const UTF8*)text);
    U32 textHeight = font->getHeight();
 
@@ -1755,41 +1757,48 @@ void GuiControl::write(Stream &stream, U32 tabStop, U32 flags)
 {
    //note: this will return false if either we, or any of our parents, are non-save controls
    bool bCanSave	= ( flags & IgnoreCanSave ) || ( flags & NoCheckParentCanSave && getCanSave() ) || getCanSaveParent();
-   StringTableEntry steName = mAddGroup->getInternalName();
-   if(bCanSave && mAddGroup && (steName != NULL) && (steName != StringTable->insert("null")) && getName() )
+   
+   if (bCanSave && mAddGroup)
    {
-      MutexHandle handle;
-      handle.lock(mMutex);
+      StringTableEntry steName = mAddGroup->getInternalName();
 
-      // export selected only?
-      if((flags & SelectedOnly) && !isSelected())
+      if ((steName != NULL) && (steName != StringTable->insert("null")) && getName())
       {
-         for(U32 i = 0; i < size(); i++)
-            (*this)[i]->write(stream, tabStop, flags);
+         MutexHandle handle;
+         handle.lock(mMutex);
 
-         return;
+         // export selected only?
+         if ((flags & SelectedOnly) && !isSelected())
+         {
+            for (U32 i = 0; i < size(); i++)
+               (*this)[i]->write(stream, tabStop, flags);
 
-      }
+            return;
 
-      stream.writeTabs(tabStop);
-      char buffer[1024];
-      dSprintf(buffer, sizeof(buffer), "new %s(%s,%s) {\r\n", getClassName(), getName() ? getName() : "", mAddGroup->getInternalName());
-      stream.write(dStrlen(buffer), buffer);
-      writeFields(stream, tabStop + 1);
+         }
 
-      if(size())
-      {
-         stream.write(2, "\r\n");
-         for(U32 i = 0; i < size(); i++)
-            (*this)[i]->write(stream, tabStop + 1, flags);
-      }
+         stream.writeTabs(tabStop);
+         char buffer[1024];
+         dSprintf(buffer, sizeof(buffer), "new %s(%s,%s) {\r\n", getClassName(), getName() ? getName() : "", mAddGroup->getInternalName());
+         stream.write(dStrlen(buffer), buffer);
+         writeFields(stream, tabStop + 1);
 
-      stream.writeTabs(tabStop);
-      stream.write(4, "};\r\n");
+         if (size())
+         {
+            stream.write(2, "\r\n");
+            for (U32 i = 0; i < size(); i++)
+               (*this)[i]->write(stream, tabStop + 1, flags);
+         }
+
+         stream.writeTabs(tabStop);
+         stream.write(4, "};\r\n");
+
+         return;
+      }
    }
-   else if (bCanSave)
+   
+   if (bCanSave)
       Parent::write( stream, tabStop, flags );
-
 }
 
 //=============================================================================

+ 73 - 56
Engine/source/gui/editor/guiMenuBar.cpp

@@ -159,7 +159,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( S32 submenuId, const ch
 // console methods
 //------------------------------------------------------------------------------
 
-DefineEngineMethod( GuiMenuBar, clearMenus, void, ( S32 param1, S32 param2),,
+DefineEngineMethod( GuiMenuBar, clearMenus, void, (),,
    "@brief Clears all the menus from the menu bar.\n\n"
    "@tsexample\n"
    "// Inform the GuiMenuBar control to clear all menus from itself.\n"
@@ -795,14 +795,14 @@ GuiMenuBar::Menu* GuiMenuBar::sCreateMenu(const char *menuText, U32 menuId)
    return newMenu;
 }
 
-void GuiMenuBar::addMenu(GuiMenuBar::Menu *newMenu)
+void GuiMenuBar::addMenu(GuiMenuBar::Menu *newMenu, S32 pos)
 {
    // add it to the menu list
    menuBarDirty = true;
-   Menu **walk;
-	for(walk = &menuList; *walk; walk = &(*walk)->nextMenu)
-      ;
-   *walk = newMenu;
+   if (pos == -1)
+      mMenuList.push_back(newMenu);
+   else
+      mMenuList.insert(pos, newMenu);
 }
 
 void GuiMenuBar::addMenu(const char *menuText, U32 menuId)
@@ -817,16 +817,16 @@ GuiMenuBar::Menu *GuiMenuBar::findMenu(const char *menu)
 	if(dIsdigit(menu[0]))
 	{
 		U32 id = dAtoi(menu);
-		for(Menu *walk = menuList; walk; walk = walk->nextMenu)
-			if(id == walk->id)
-				return walk;
+      for (U32 i = 0; i < mMenuList.size(); ++i)
+         if (id == mMenuList[i]->id)
+            return mMenuList[i];
 		return NULL;
 	}
 	else
 	{
-		for(Menu *walk = menuList; walk; walk = walk->nextMenu)
-			if(!dStricmp(menu, walk->text))
-				return walk;
+      for (U32 i = 0; i < mMenuList.size(); ++i)
+         if (!dStricmp(menu, mMenuList[i]->text))
+            return mMenuList[i];
 		return NULL;
 	}
 }
@@ -854,16 +854,15 @@ void GuiMenuBar::removeMenu(Menu *menu)
 {
    menuBarDirty = true;
    clearMenuItems(menu);
-   for(Menu **walk = &menuList; *walk; walk = &(*walk)->nextMenu)
+
+   for (U32 i = 0; i < mMenuList.size(); ++i)
    {
-      if(*walk == menu)
+      if (mMenuList[i] == menu)
       {
-         *walk = menu->nextMenu;
+         mMenuList.erase(i);
          break;
       }
    }
-   dFree(menu->text);
-   delete menu;
 }
 
 void GuiMenuBar::removeMenuItem(Menu *menu, MenuItem *menuItem)
@@ -945,8 +944,26 @@ void GuiMenuBar::clearMenuItems(Menu *menu)
 
 void GuiMenuBar::clearMenus()
 {
-   while(menuList)
-      removeMenu(menuList);
+   mMenuList.clear();
+}
+
+void GuiMenuBar::attachToMenuBar(Menu* menu, S32 pos)
+{
+   addMenu(menu, pos);
+}
+
+void GuiMenuBar::removeFromMenuBar(Menu* menu)
+{
+   menuBarDirty = true;
+
+   for (U32 i = 0; i < mMenuList.size(); ++i)
+   {
+      if (mMenuList[i] == menu)
+      {
+         mMenuList.erase(i);
+         break;
+      }
+   }
 }
 
 //------------------------------------------------------------------------------
@@ -1018,7 +1035,7 @@ void GuiMenuBar::addSubmenuItem(Menu *menu, MenuItem *submenu, const char *text,
    newMenuItem->checkGroup = checkGroup;
    newMenuItem->nextMenuItem = NULL;
    newMenuItem->acceleratorIndex = 0;
-   newMenuItem->enabled = text[0] != '-';
+   newMenuItem->enabled = (dStrlen(text) > 1 || text[0] != '-');
    newMenuItem->visible = true;
    newMenuItem->bitmapIndex = -1;
 
@@ -1083,7 +1100,7 @@ void GuiMenuBar::clearSubmenuItems(MenuItem *menuitem)
 
 GuiMenuBar::GuiMenuBar()
 {
-	menuList = NULL;
+   mMenuList.clear();
    menuBarDirty = true;
    mouseDownMenu = NULL;
    mouseOverMenu = NULL;
@@ -1140,9 +1157,9 @@ GuiMenuBar::Menu *GuiMenuBar::findHitMenu(Point2I mousePoint)
 {
    Point2I pos = globalToLocalCoord(mousePoint);
 
-   for(Menu *walk = menuList; walk; walk = walk->nextMenu)
-      if(walk->visible && walk->bounds.pointInRect(pos))
-         return walk;
+   for (U32 i = 0; i < mMenuList.size(); ++i)
+      if (mMenuList[i]->visible && mMenuList[i]->bounds.pointInRect(pos))
+         return mMenuList[i];
    return NULL;
 }
 
@@ -1153,35 +1170,35 @@ void GuiMenuBar::onPreRender()
    {
       menuBarDirty = false;
       U32 curX = mPadding;
-      for(Menu *walk = menuList; walk; walk = walk->nextMenu)
+      for (U32 i = 0; i < mMenuList.size(); ++i)
       {
-         if(!walk->visible)
+         if (!mMenuList[i]->visible)
             continue;
 
 		 // Bounds depends on if there is a bitmap to be drawn or not
-		 if(walk->bitmapIndex == -1)
+         if (mMenuList[i]->bitmapIndex == -1)
 		 {
             // Text only
-            walk->bounds.set(curX, 0, mProfile->mFont->getStrWidth(walk->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2));
+            mMenuList[i]->bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2));
 
          } else
 		 {
             // Will the bitmap and text be draw?
-            if(!walk->drawBitmapOnly)
+          if (!mMenuList[i]->drawBitmapOnly)
 			{
                // Draw the bitmap and the text
                RectI *bitmapBounds = mProfile->mBitmapArrayRects.address();
-			   walk->bounds.set(curX, 0, bitmapBounds[walk->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(walk->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2));
+               mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2));
 
 			} else
 			{
                // Only the bitmap will be drawn
                RectI *bitmapBounds = mProfile->mBitmapArrayRects.address();
-               walk->bounds.set(curX, 0, bitmapBounds[walk->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2));
+               mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2));
 			}
 		 }
 
-         curX += walk->bounds.extent.x;
+         curX += mMenuList[i]->bounds.extent.x;
       }
 		mouseOverMenu = NULL;
 		mouseDownMenu = NULL;
@@ -1290,58 +1307,58 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
    if (mProfile->mBorder)
       renderBorder(ctrlRect, mProfile);
 
-   for(Menu *walk = menuList; walk; walk = walk->nextMenu)
+   for (U32 i = 0; i < mMenuList.size(); ++i)
    {
-      if(!walk->visible)
+      if (!mMenuList[i]->visible)
          continue;
       ColorI fontColor = mProfile->mFontColor;
-      RectI bounds = walk->bounds;
+      RectI bounds = mMenuList[i]->bounds;
       bounds.point += offset;
       
       Point2I start;
 
-      start.x = walk->bounds.point.x + mHorizontalMargin;
-      start.y = walk->bounds.point.y + ( walk->bounds.extent.y - mProfile->mFont->getHeight() ) / 2;
+      start.x = mMenuList[i]->bounds.point.x + mHorizontalMargin;
+      start.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - mProfile->mFont->getHeight()) / 2;
 
 	  // Draw the border
-	  if(walk->drawBorder)
+      if (mMenuList[i]->drawBorder)
 	  {
         RectI highlightBounds = bounds;
         highlightBounds.inset(1,1);
-         if(walk == mouseDownMenu)
+        if (mMenuList[i] == mouseDownMenu)
             renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL );
-         else if(walk == mouseOverMenu && mouseDownMenu == NULL)
-            renderFilledBorder(highlightBounds, mProfile->mBorderColor, mProfile->mFillColor );
+        else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL)
+           renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL);
 	  }
 
 	  // Do we draw a bitmap?
-	  if(walk->bitmapIndex != -1)
+      if (mMenuList[i]->bitmapIndex != -1)
 	  {
-         S32 index = walk->bitmapIndex * 3;
-         if(walk == mouseDownMenu)
+        S32 index = mMenuList[i]->bitmapIndex * 3;
+        if (mMenuList[i] == mouseDownMenu)
             ++index;
-         else if(walk == mouseOverMenu && mouseDownMenu == NULL)
+        else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL)
             index += 2;
 
          RectI rect = mProfile->mBitmapArrayRects[index];
 
 		 Point2I bitmapstart(start);
-		 bitmapstart.y = walk->bounds.point.y + ( walk->bounds.extent.y - rect.extent.y ) / 2;
+       bitmapstart.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - rect.extent.y) / 2;
 
          drawUtil->clearBitmapModulation();
          drawUtil->drawBitmapSR( mProfile->mTextureObject, offset + bitmapstart, rect);
 
 		 // Should we also draw the text?
-		 if(!walk->drawBitmapOnly)
+         if (!mMenuList[i]->drawBitmapOnly)
 		 {
             start.x += mBitmapMargin;
       drawUtil->setBitmapModulation( fontColor );
-      drawUtil->drawText( mProfile->mFont, start + offset, walk->text, mProfile->mFontColors );
+      drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors);
 		 }
 	  } else
 	  {
       drawUtil->setBitmapModulation( fontColor );
-      drawUtil->drawText( mProfile->mFont, start + offset, walk->text, mProfile->mFontColors );
+      drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors);
 	  }
    }
 
@@ -1354,9 +1371,9 @@ void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator
    // add all our keys:
    mCurAcceleratorIndex = 1;
 
-   for(Menu *menu = menuList; menu; menu = menu->nextMenu)
+   for (U32 i = 0; i < mMenuList.size(); ++i)
    {
-      for(MenuItem *item = menu->firstMenuItem; item; item = item->nextMenuItem)
+      for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem)
       {
          if(!item->accelerator)
          {
@@ -1384,20 +1401,20 @@ void GuiMenuBar::acceleratorKeyPress(U32 index)
 {
    // loop through all the menus
    // and find the item that corresponds to the accelerator index
-   for(Menu *menu = menuList; menu; menu = menu->nextMenu)
+   for (U32 i = 0; i < mMenuList.size(); ++i)
    {
-      if(!menu->visible)
+      if (!mMenuList[i]->visible)
          continue;
 
-      for(MenuItem *item = menu->firstMenuItem; item; item = item->nextMenuItem)
+      for (MenuItem *item = mMenuList[i]->firstMenuItem; item; item = item->nextMenuItem)
       {
          if(item->acceleratorIndex == index)
          {
             // first, call the script callback for menu selection:
-            onMenuSelect_callback(menu->id, menu->text);
+            onMenuSelect_callback(mMenuList[i]->id, mMenuList[i]->text);
 			
             if(item->visible)
-               menuItemSelected(menu, item);
+               menuItemSelected(mMenuList[i], item);
             return;
          }
       }

+ 5 - 2
Engine/source/gui/editor/guiMenuBar.h

@@ -133,7 +133,7 @@ public:
 	GuiSubmenuBackgroundCtrl *mSubmenuBackground; //  Background for a submenu
 	GuiMenuTextListCtrl *mSubmenuTextList;     //  Text list for a submenu
 
-	Menu *menuList;
+   Vector<Menu*> mMenuList;
    Menu *mouseDownMenu;
    Menu *mouseOverMenu;
 
@@ -164,7 +164,7 @@ public:
 	// internal menu handling functions
 	// these are used by the script manipulation functions to add/remove/change menu items
    static Menu* sCreateMenu(const char *menuText, U32 menuId);
-   void addMenu(Menu *menu);
+   void addMenu(Menu *menu, S32 pos = -1);
    void addMenu(const char *menuText, U32 menuId);
 	Menu *findMenu(const char *menu);  // takes either a menu text or a string id
 	static MenuItem *findMenuItem(Menu *menu, const char *menuItem); // takes either a menu text or a string id
@@ -175,6 +175,9 @@ public:
 	static void clearMenuItems(Menu *menu);
    void clearMenus();
 
+   void attachToMenuBar(Menu* menu, S32 pos = -1);
+   void removeFromMenuBar(Menu* menu);
+
    //  Methods to deal with submenus
    static MenuItem* findSubmenuItem(Menu *menu, const char *menuItem, const char *submenuItem);
    static MenuItem* findSubmenuItem(MenuItem *menuItem, const char *submenuItem);

+ 4 - 0
Engine/source/gui/editor/guiShapeEdPreview.cpp

@@ -1608,6 +1608,8 @@ void GuiShapeEdPreview::renderNodes() const
 
 void GuiShapeEdPreview::renderNodeAxes(S32 index, const ColorF& nodeColor) const
 {
+   if(mModel->mNodeTransforms.size() <= index || index < 0)
+      return;
    const Point3F xAxis( 1.0f,  0.15f, 0.15f );
    const Point3F yAxis( 0.15f, 1.0f,  0.15f );
    const Point3F zAxis( 0.15f, 0.15f, 1.0f  );
@@ -1631,6 +1633,8 @@ void GuiShapeEdPreview::renderNodeAxes(S32 index, const ColorF& nodeColor) const
 
 void GuiShapeEdPreview::renderNodeName(S32 index, const ColorF& textColor) const
 {
+   if(index < 0 || index >= mModel->getShape()->nodes.size() || index >= mProjectedNodes.size())
+      return;
    const TSShape::Node& node = mModel->getShape()->nodes[index];
    const String& nodeName = mModel->getShape()->getName( node.nameIndex );
 

+ 9 - 14
Engine/source/gui/utility/guiMouseEventCtrl.cpp

@@ -46,7 +46,7 @@ ConsoleDocClass( GuiMouseEventCtrl,
 );
 
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDown, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDown, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
 														  ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the mouse is pressed down while in this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -70,7 +70,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDown, void, ( U8 modifier, Point2I
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseUp, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseUp, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ),
 													    ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the mouse is released while in this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -94,7 +94,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseUp, void, ( U8 modifier, Point2I m
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseMove, void, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount  ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseMove, void, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount  ),
 												   ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the mouse is moved (without dragging) while in this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -118,7 +118,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseMove, void, ( U8 modifier, Point2I
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDragged, void, (  U8 modifier, Point2I mousePoint,U8 mouseClickCount  ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDragged, void, (  S32 modifier, Point2I mousePoint, S32 mouseClickCount  ),
 												   ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the mouse is dragged while in this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -142,7 +142,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseDragged, void, (  U8 modifier, Poi
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseEnter, void, (  U8 modifier, Point2I mousePoint,U8 mouseClickCount  ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseEnter, void, (  S32 modifier, Point2I mousePoint, S32 mouseClickCount  ),
 												   ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the mouse enters this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -166,7 +166,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseEnter, void, (  U8 modifier, Point
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseLeave, void, (  U8 modifier, Point2I mousePoint,U8 mouseClickCount  ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseLeave, void, (  S32 modifier, Point2I mousePoint, S32 mouseClickCount  ),
 												   ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the mouse leaves this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -190,7 +190,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onMouseLeave, void, (  U8 modifier, Point
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDown, void, (  U8 modifier, Point2I mousePoint,U8 mouseClickCount  ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDown, void, (  S32 modifier, Point2I mousePoint, S32 mouseClickCount  ),
 												   ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the right mouse button is pressed while in this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -214,7 +214,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDown, void, (  U8 modifier, P
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseUp, void, (  U8 modifier, Point2I mousePoint,U8 mouseClickCount  ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseUp, void, (  S32 modifier, Point2I mousePoint, S32 mouseClickCount  ),
 												   ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the right mouse button is released while in this control.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -238,7 +238,7 @@ IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseUp, void, (  U8 modifier, Poi
    "@see GuiControl\n\n"
 );
 
-IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDragged, void, (  U8 modifier, Point2I mousePoint,U8 mouseClickCount  ),
+IMPLEMENT_CALLBACK( GuiMouseEventCtrl, onRightMouseDragged, void, (  S32 modifier, Point2I mousePoint, S32 mouseClickCount  ),
 												   ( modifier, mousePoint, mouseClickCount ),
    "@brief Callback that occurs whenever the mouse is dragged in this control while the right mouse button is pressed.\n\n"
    "@param modifier Key that was pressed during this callback. Values are:\n\n" 
@@ -270,11 +270,6 @@ GuiMouseEventCtrl::GuiMouseEventCtrl()
 //------------------------------------------------------------------------------
 void GuiMouseEventCtrl::sendMouseEvent(const char * name, const GuiEvent & event)
 {
-   char buf[3][32];
-   dSprintf(buf[0], 32, "%d", event.modifier);
-   dSprintf(buf[1], 32, "%d %d", event.mousePoint.x, event.mousePoint.y);
-   dSprintf(buf[2], 32, "%d", event.mouseClickCount);
-
    if(dStricmp(name,"onMouseDown") == 0)
 	   onMouseDown_callback(event.modifier, event.mousePoint, event.mouseClickCount);
    else if(dStricmp(name,"onMouseUp") == 0)

+ 9 - 9
Engine/source/gui/utility/guiMouseEventCtrl.h

@@ -41,15 +41,15 @@ class GuiMouseEventCtrl : public GuiControl
 
       GuiMouseEventCtrl();
 
-	  DECLARE_CALLBACK( void, onMouseDown, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-  	  DECLARE_CALLBACK( void, onMouseUp, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-  	  DECLARE_CALLBACK( void, onMouseMove, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-  	  DECLARE_CALLBACK( void, onMouseDragged, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-  	  DECLARE_CALLBACK( void, onMouseEnter, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-  	  DECLARE_CALLBACK( void, onMouseLeave, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-	  DECLARE_CALLBACK( void, onRightMouseDown, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-	  DECLARE_CALLBACK( void, onRightMouseUp, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
-	  DECLARE_CALLBACK( void, onRightMouseDragged, ( U8 modifier, Point2I mousePoint,U8 mouseClickCount ));
+      DECLARE_CALLBACK( void, onMouseDown, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onMouseUp, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onMouseMove, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onMouseDragged, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onMouseEnter, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onMouseLeave, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onRightMouseDown, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onRightMouseUp, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
+      DECLARE_CALLBACK( void, onRightMouseDragged, ( S32 modifier, Point2I mousePoint, S32 mouseClickCount ));
 
       // GuiControl
       void onMouseDown(const GuiEvent & event);

+ 1 - 1
Engine/source/gui/worldEditor/worldEditor.cpp

@@ -2655,7 +2655,7 @@ void WorldEditor::renderScene( const RectI &updateRect )
 
          // Probably should test the entire icon screen-rect instead of just the centerpoint
          // but would need to move some code from renderScreenObj to here.
-         if ( mDragSelect )
+         if (mDragSelect && selection)
             if ( mDragRect.pointInRect(sPosI) && !selection->objInSet(obj) )
                mDragSelected->addObject(obj);
 

+ 2 - 4
Engine/source/materials/processedShaderMaterial.cpp

@@ -396,11 +396,9 @@ void ProcessedShaderMaterial::_determineFeatures(  U32 stageNum,
    // cannot do on SM 2.0 and below.
    if ( shaderVersion > 2.0f )
    {
-      // Only allow parallax if we have a normal map and
-      // we're not using DXTnm compression.
+
       if (  mMaterial->mParallaxScale[stageNum] > 0.0f &&
-         fd.features[ MFT_NormalMap ] &&
-         !fd.features[ MFT_IsDXTnm ] )
+         fd.features[ MFT_NormalMap ] )
          fd.features.addFeature( MFT_Parallax );
 
       // If not parallax then allow per-pixel specular if

+ 1 - 1
Engine/source/math/mMatrix.cpp

@@ -163,7 +163,7 @@ EulerF MatrixF::toEuler() const
    const F32 * mat = m;
 
    EulerF r;
-   r.x = mAsin(mat[MatrixF::idx(2,1)]);
+   r.x = mAsin(mClampF(mat[MatrixF::idx(2,1)], -1.0, 1.0));
 
    if(mCos(r.x) != 0.f)
    {

+ 28 - 1
Engine/source/math/mPoint3.h

@@ -233,11 +233,13 @@ class Point3D
    bool  isZero() const;
    F64 len()    const;
    F64 lenSquared() const;
+   F64 magnitudeSafe() const;
 
    //-------------------------------------- Mathematical mutators
   public:
    void neg();
    void normalize();
+   void normalizeSafe();
    void normalize(F64 val);
    void convolve(const Point3D&);
    void convolveInverse(const Point3D&);
@@ -728,11 +730,13 @@ inline Point3F& Point3F::operator*=(const Point3F &_vec)
 
 inline Point3F Point3F::operator/(const Point3F &_vec) const
 {
+   AssertFatal(_vec.x != 0.0f && _vec.y != 0.0f && _vec.z != 0.0f, "Error, div by zero attempted");
    return Point3F(x / _vec.x, y / _vec.y, z / _vec.z);
 }
 
 inline Point3F& Point3F::operator/=(const Point3F &_vec)
 {
+   AssertFatal(_vec.x != 0.0f && _vec.y != 0.0f && _vec.z != 0.0f, "Error, div by zero attempted");
    x /= _vec.x;
    y /= _vec.y;
    z /= _vec.z;
@@ -855,7 +859,8 @@ inline F64 Point3D::lenSquared() const
 
 inline F64 Point3D::len() const
 {
-   return mSqrtD(x*x + y*y + z*z);
+   F64 temp = x*x + y*y + z*z;
+   return (temp > 0.0) ? mSqrtD(temp) : 0.0;
 }
 
 inline void Point3D::normalize()
@@ -863,6 +868,28 @@ inline void Point3D::normalize()
    m_point3D_normalize(*this);
 }
 
+inline F64 Point3D::magnitudeSafe() const
+{
+   if( isZero() )
+   {
+      return 0.0;
+   }
+   else
+   {
+      return len();
+   }
+}
+
+inline void Point3D::normalizeSafe()
+{
+   F64 vmag = magnitudeSafe();
+
+   if( vmag > POINT_EPSILON )
+   {
+      *this *= F64(1.0 / vmag);
+   }
+}
+
 inline void Point3D::normalize(F64 val)
 {
    m_point3D_normalize_f(*this, val);

+ 43 - 28
Engine/source/math/mQuat.cpp

@@ -32,33 +32,48 @@ const QuatF QuatF::Identity(0.0f,0.0f,0.0f,1.0f);
 
 QuatF& QuatF::set( const EulerF & e )
 {
-   F32 cx, sx;
-   F32 cy, sy;
-   F32 cz, sz;
-   mSinCos( e.x * 0.5f, sx, cx );
-   mSinCos( e.y * 0.5f, sy, cy );
-   mSinCos( e.z * 0.5f, sz, cz );
-
-   // Qyaw(z) = [ (0, 0, sin z/2), cos z/2 ]
-   // Qpitch(x) = [ (sin x/2, 0, 0), cos x/2 ]
-   // Qroll(y) = [ (0, sin y/2, 0), cos y/2 ]
-   // this = Qresult = Qyaw*Qpitch*Qroll ZXY
-   //
-   // The code that folows is a simplification of:
-   // roll*=pitch;
-   // roll*=yaw;
-   // *this = roll;
-   F32 cycz, sysz, sycz, cysz;
-   cycz = cy*cz;
-   sysz = sy*sz;
-   sycz = sy*cz;
-   cysz = cy*sz;
-   w = cycz*cx - sysz*sx;
-   x = cycz*sx + sysz*cx;
-   y = sycz*cx + cysz*sx;
-   z = cysz*cx - sycz*sx;
-
-   return *this;
+	/*
+	F32 cx, sx;
+	F32 cy, sy;
+	F32 cz, sz;
+	mSinCos( -e.x * 0.5f, sx, cx );
+	mSinCos( -e.y * 0.5f, sy, cy );
+	mSinCos( -e.z * 0.5f, sz, cz );
+
+	// Qyaw(z)   = [ (0, 0, sin z/2), cos z/2 ]
+	// Qpitch(x) = [ (sin x/2, 0, 0), cos x/2 ]
+	// Qroll(y)  = [ (0, sin y/2, 0), cos y/2 ]
+	// this = Qresult = Qyaw*Qpitch*Qroll  ZXY
+	//
+	// The code that folows is a simplification of:
+	//    roll*=pitch;
+	//    roll*=yaw;
+	//    *this = roll;
+	F32 cycz, sysz, sycz, cysz;
+	cycz = cy*cz;
+	sysz = sy*sz;
+	sycz = sy*cz;
+	cysz = cy*sz;
+	w = cycz*cx + sysz*sx;
+	x = cycz*sx + sysz*cx;
+	y = sycz*cx - cysz*sx;
+	z = cysz*cx - sycz*sx;
+	*/
+	// Assuming the angles are in radians.
+	F32 c1 = mCos(e.y * 0.5f);
+	F32 s1 = mSin(e.y * 0.5f);
+	F32 c2 = mCos(e.z * 0.5f);
+	F32 s2 = mSin(e.z * 0.5f);
+	F32 c3 = mCos(e.x * 0.5f);
+	F32 s3 = mSin(e.x * 0.5f);
+	F32 c1c2 = c1*c2;
+	F32 s1s2 = s1*s2;
+	w =c1c2*c3 - s1s2*s3;
+	x =c1c2*s3 + s1s2*c3;
+	y =s1*c2*c3 + c1*s2*s3;
+	z =c1*s2*c3 - s1*c2*s3;
+
+	return *this;
 }
 
 QuatF& QuatF::operator *=( const QuatF & b )
@@ -289,7 +304,7 @@ QuatF & QuatF::interpolate( const QuatF & q1, const QuatF & q2, F32 t )
    return *this;
 }
 
-Point3F & QuatF::mulP(const Point3F& p, Point3F* r)
+Point3F & QuatF::mulP(const Point3F& p, Point3F* r) const
 {
    QuatF qq;
    QuatF qi = *this;

+ 1 - 1
Engine/source/math/mQuat.h

@@ -81,7 +81,7 @@ public:
    QuatF& interpolate( const QuatF & q1, const QuatF & q2, F32 t );
    F32  angleBetween( const QuatF & q );
 
-   Point3F& mulP(const Point3F& a, Point3F* b);   // r = p * this
+   Point3F& mulP(const Point3F& a, Point3F* r) const;   // r = p * this
    QuatF& mul(const QuatF& a, const QuatF& b);    // This = a * b
 
    // Vectors passed in must be normalized

+ 2 - 2
Engine/source/math/mRandom.cpp

@@ -88,13 +88,13 @@ void MRandomLCG::setSeed(S32 s)
 U32 MRandomLCG::randI()
 {
    if ( mSeed <= msQuotient )
-      mSeed = (mSeed * 16807L) % S32_MAX;
+      mSeed = (mSeed * 16807) % S32_MAX;
    else
    {
       S32 high_part = mSeed / msQuotient;
       S32 low_part  = mSeed % msQuotient;
 
-      S32 test = (16807L * low_part) - (msRemainder * high_part);
+      S32 test = (16807 * low_part) - (msRemainder * high_part);
 
       if ( test > 0 )
          mSeed = test;

+ 1 - 1
Engine/source/math/mRandom.h

@@ -54,7 +54,7 @@ public:
 inline F32 MRandomGenerator::randF()
 {
    // default: multiply by 1/(2^31)
-   return  F32(randI()) * (1.0f/2147483647.0f);
+   return F32(randI()) * (1.0f / S32_MAX);
 }
 
 inline S32 MRandomGenerator::randI(S32 i, S32 n)

+ 3 - 0
Engine/source/math/mSphere.cpp

@@ -77,8 +77,11 @@ bool SphereF::intersectsRay( const Point3F &start, const Point3F &end ) const
    // value for getting the exact
    // intersection point, by interpolating
    // start to end by t.
+
+   /*
    F32 t = 0;
    TORQUE_UNUSED(t);
+   */
 
    // if t1 is less than zero, the object is in the ray's negative direction
    // and consequently the ray misses the sphere

+ 0 - 1
Engine/source/navigation/guiNavEditorCtrl.cpp

@@ -308,7 +308,6 @@ void GuiNavEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
    U8 keys = Input::getModifierKeys();
    bool shift = keys & SI_LSHIFT;
    bool ctrl = keys & SI_LCTRL;
-   bool alt = keys & SI_LALT;
 
    if(mMode == mLinkMode && !mMesh.isNull())
    {

+ 48 - 2
Engine/source/platform/threads/test/threadPoolTest.cpp

@@ -44,6 +44,20 @@ public:
          mResults[mIndex] = mIndex;
       }
    };
+
+   // A worker that delays for some time. We'll use this to test the ThreadPool's
+   // synchronous and asynchronous operations.
+   struct DelayItem : public ThreadPool::WorkItem
+   {
+      U32 ms;
+      DelayItem(U32 _ms) : ms(_ms) {}
+
+   protected:
+      virtual void execute()
+      {
+         Platform::sleep(ms);
+      }
+   };
 };
 
 TEST_FIX(ThreadPool, BasicAPI)
@@ -63,8 +77,7 @@ TEST_FIX(ThreadPool, BasicAPI)
       pool->queueWorkItem(item);
    }
 
-   // Wait for all items to complete.
-   pool->flushWorkItems();
+   pool->waitForAllItems();
 
    // Verify.
    for (U32 i = 0; i < numItems; i++)
@@ -72,4 +85,37 @@ TEST_FIX(ThreadPool, BasicAPI)
    results.clear();
 }
 
+TEST_FIX(ThreadPool, Asynchronous)
+{
+   const U32 delay = 500; //ms
+
+   // Launch a single delaying work item.
+   ThreadPool* pool = &ThreadPool::GLOBAL();
+   ThreadSafeRef<DelayItem> item(new DelayItem(delay));
+   pool->queueWorkItem(item);
+
+   // The thread should not yet be finished.
+   EXPECT_EQ(false, item->hasExecuted());
+
+   // Wait til the item should have completed.
+   Platform::sleep(delay * 2);
+
+   EXPECT_EQ(true, item->hasExecuted());
+}
+
+TEST_FIX(ThreadPool, Synchronous)
+{
+   const U32 delay = 500; //ms
+
+   // Launch a single delaying work item.
+   ThreadPool* pool = &ThreadPool::GLOBAL();
+   ThreadSafeRef<DelayItem> item(new DelayItem(delay));
+   pool->queueWorkItem(item);
+
+   // Wait for the item to complete.
+   pool->waitForAllItems();
+
+   EXPECT_EQ(true, item->hasExecuted());
+}
+
 #endif

+ 25 - 1
Engine/source/platform/threads/threadPool.cpp

@@ -120,6 +120,7 @@ void ThreadPool::Context::updateAccumulatedPriorityBiases()
 void ThreadPool::WorkItem::process()
 {
    execute();
+   mExecuted = true;
 }
 
 //--------------------------------------------------------------------------
@@ -281,6 +282,8 @@ void ThreadPool::WorkerThread::run( void* arg )
             Platform::outputDebugString( "[ThreadPool::WorkerThread] thread '%i' takes item '0x%x'", getId(), *workItem );
 #endif
             workItem->process();
+
+            dFetchAndAdd( mPool->mNumPendingItems, ( U32 ) -1 );
          }
          else
             waitForSignal = true;
@@ -318,6 +321,7 @@ ThreadPool::ThreadPool( const char* name, U32 numThreads )
    : mName( name ),
      mNumThreads( numThreads ),
      mNumThreadsAwake( 0 ),
+     mNumPendingItems( 0 ),
      mThreads( 0 ),
      mSemaphore( 0 )
 {
@@ -409,7 +413,7 @@ void ThreadPool::queueWorkItem( WorkItem* item )
    else
    {
       // Put the item in the queue.
-
+      dFetchAndAdd( mNumPendingItems, 1 );
       mWorkItemQueue.insert( item->getPriority(), item );
 
       mSemaphore.release();
@@ -440,6 +444,26 @@ void ThreadPool::flushWorkItems( S32 timeOut )
    }
 }
 
+void ThreadPool::waitForAllItems( S32 timeOut )
+{
+   U32 endTime = 0;
+   if( timeOut != -1 )
+      endTime = Platform::getRealMilliseconds() + timeOut;
+
+   // Spinlock until there are no items that have not been processed.
+
+   while( dAtomicRead( mNumPendingItems ) )
+   {
+      Platform::sleep( 25 );
+
+      // Stop if we have exceeded our processing time budget.
+
+      if( timeOut != -1
+          && Platform::getRealMilliseconds() >= endTime )
+          break;
+   }
+}
+
 //--------------------------------------------------------------------------
 
 void ThreadPool::queueWorkItemOnMainThread( WorkItem* item )

+ 26 - 1
Engine/source/platform/threads/threadPool.h

@@ -194,6 +194,9 @@ class ThreadPool
             /// This is the primary function to implement by subclasses.
             virtual void execute() = 0;
 
+            /// This flag is set after the execute() method has completed.
+            bool mExecuted;
+
          public:
          
             /// Construct a new work item.
@@ -201,7 +204,8 @@ class ThreadPool
             /// @param context The work context in which the item should be placed.
             ///    If NULL, the root context will be used.
             WorkItem( Context* context = 0 )
-               : mContext( context ? context : Context::ROOT_CONTEXT() )
+               : mContext( context ? context : Context::ROOT_CONTEXT() ),
+                 mExecuted( false )
             {
             }
             
@@ -229,6 +233,12 @@ class ThreadPool
             /// Return the item's base priority value.
             /// @return item priority; defaults to 1.0.
             virtual F32 getPriority();
+
+            /// Has this work item been executed already?
+            bool hasExecuted() const
+            {
+               return mExecuted;
+            }
       };
 
       typedef ThreadSafeRef< WorkItem > WorkItemPtr;
@@ -254,6 +264,9 @@ class ThreadPool
       
       /// Number of worker threads guaranteed to be non-blocking.
       U32 mNumThreadsReady;
+
+      /// Number of work items that have not yet completed execution.
+      U32 mNumPendingItems;
       
       /// Semaphore used to wake up threads, if necessary.
       Semaphore mSemaphore;
@@ -306,6 +319,18 @@ class ThreadPool
       ///   the queue to flush out.  -1 = infinite.
       void flushWorkItems( S32 timeOut = -1 );
 
+      /// If you're using a non-global thread pool to parallelise some work, you
+      /// may want to block until all the parallel work is complete. As with
+      /// flushWorkItems, this method may block indefinitely if new items keep
+      /// getting added to the pool before old ones finish.
+      ///
+      /// <em>This method will not wait for items queued on the main thread using
+      /// queueWorkItemOnMainThread!</em>
+      ///
+      /// @param timeOut Soft limit on the number of milliseconds to wait for
+      ///   all items to complete.  -1 = infinite.
+      void waitForAllItems( S32 timeOut = -1 );
+
       /// Add a work item to the main thread's work queue.
       ///
       /// The main thread's work queue will be processed each frame using

+ 61 - 9
Engine/source/platformSDL/menus/menuBarSDL.cpp

@@ -112,15 +112,37 @@ void MenuBar::updateMenuBar(PopupMenu *popupMenu /* = NULL */)
    GuiPlatformGenericMenuBar* menuBarGui = _FindMenuBarCtrl();
    popupMenu->mData->mMenuBar = this;
 
-   AssertFatal( dStrcmp( popupMenu->mData->mMenuGui->text, popupMenu->getBarTitle() ) == 0, "");
-   GuiMenuBar::Menu* menuGui = menuBarGui->findMenu( popupMenu->getBarTitle() );
-   if(!menuGui)
+   String menuTitle = popupMenu->getBarTitle();
+
+   //Next, find out if we're still in the list of entries
+   SimSet::iterator itr = find(begin(), end(), popupMenu);
+
+   GuiMenuBar::Menu* menuGui = menuBarGui->findMenu(menuTitle);
+   if (!menuGui)
    {
-      menuBarGui->addMenu( popupMenu->mData->mMenuGui );
-      menuGui = menuBarGui->findMenu( popupMenu->getBarTitle() );
+      //This is our first time setting this particular menu up, so we'll OK it.
+      if (itr == end())
+         menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui);
+      else
+         menuBarGui->attachToMenuBar(popupMenu->mData->mMenuGui, itr - begin());
    }
+   else
+   {
+      //Not our first time through, so we're really updating it.
+
+      //So, first, remove it from the menubar
+      menuBarGui->removeFromMenuBar(menuGui);
+
+      //Next, find out if we're still in the list of entries
+      SimSet::iterator itr = find(begin(), end(), popupMenu);
+
+      //if we're no longer in the list, we're pretty much done here
+      if (itr == end())
+         return;
 
-   PlatformPopupMenuData::mMenuMap[ menuGui ] = popupMenu;
+      //We're still here, so this is a valid menu for our current bar configuration, so add us back in.
+      menuBarGui->attachToMenuBar(menuGui, itr - begin());
+   }
 }
 
 //-----------------------------------------------------------------------------
@@ -154,17 +176,47 @@ void MenuBar::attachToCanvas(GuiCanvas *owner, S32 pos)
 
       mCanvas->setMenuBar( base );
    }
+
+   for (S32 i = 0; i < size(); ++i)
+   {
+      PopupMenu *mnu = dynamic_cast<PopupMenu *>(at(i));
+      if (mnu == NULL)
+      {
+         Con::warnf("MenuBar::attachToMenuBar - Non-PopupMenu object in set");
+         continue;
+      }
+
+      if (mnu->isAttachedToMenuBar())
+         mnu->removeFromMenuBar();
+
+      mnu->attachToMenuBar(owner, pos + i);
+   }
    
 }
 
 void MenuBar::removeFromCanvas()
 {
-   _FindMenuBarCtrl()->clearMenus();
+   if (mCanvas == NULL || !isAttachedToCanvas())
+      return;
+
+   //_FindMenuBarCtrl()->clearMenus();
+
+   // Add the items
+   for (S32 i = 0; i < size(); ++i)
+   {
+      PopupMenu *mnu = dynamic_cast<PopupMenu *>(at(i));
+      if (mnu == NULL)
+      {
+         Con::warnf("MenuBar::removeFromMenuBar - Non-PopupMenu object in set");
+         continue;
+      }
+
+      mnu->removeFromMenuBar();
+   }
 
    mCanvas->setMenuBar(NULL);
 
-   if(mCanvas == NULL || !isAttachedToCanvas())
-      return;
+   mCanvas = NULL;
 }
 
 #endif

+ 4 - 0
Engine/source/platformSDL/sdlMsgBox.cpp

@@ -76,6 +76,10 @@ S32 Platform::messageBox(const UTF8 *title, const UTF8 *message, MBButtons butto
       initMsgBox_ButtonData();
 
    SDL_Window *window = WindowManager->getFirstWindow() ? SDL_GetWindowFromID( WindowManager->getFirstWindow()->getWindowId() ) : NULL;
+
+   if (window) //release the mouse from the window constaints
+      SDL_SetWindowGrab(window, SDL_FALSE);
+
    if(buttons == MBOk)
       return SDL_ShowSimpleMessageBox(0, title, message,  window );
 

+ 1 - 1
Engine/source/platformWin32/winFileio.cpp

@@ -998,7 +998,7 @@ S32 Platform::getFileSize(const char *pFilePath)
       return -1;
 
    // must be a real file then
-   return findData.nFileSizeLow;
+   return ((findData.nFileSizeHigh * (MAXDWORD+1)) + findData.nFileSizeLow);
 }
 
 

+ 11 - 0
Engine/source/platformWin32/winVolume.cpp

@@ -236,6 +236,14 @@ Win32FileSystem::~Win32FileSystem()
 {
 }
 
+void Win32FileSystem::verifyCompatibility(const Path& _path, WIN32_FIND_DATAW _info)
+{
+   if (_path.getFullFileName().isNotEmpty() && _path.getFullFileName().compare(String(_info.cFileName)) != 0)
+   {
+      Con::warnf("Linux Compatibility Warning: %s != %s", String(_info.cFileName).c_str(), _path.getFullFileName().c_str());
+   }
+}
+
 FileNodeRef Win32FileSystem::resolve(const Path& path)
 {
    String file = _BuildFileName(mVolume,path);
@@ -245,6 +253,9 @@ FileNodeRef Win32FileSystem::resolve(const Path& path)
    ::FindClose(handle);
    if (handle != INVALID_HANDLE_VALUE)
    {
+#ifdef TORQUE_DEBUG
+      verifyCompatibility(path, info);
+#endif
       if (S_ISREG(info.dwFileAttributes))
          return new Win32File(path,file);
       if (S_ISDIR(info.dwFileAttributes))

+ 1 - 0
Engine/source/platformWin32/winVolume.h

@@ -45,6 +45,7 @@ public:
    String   getTypeStr() const { return "Win32"; }
 
    FileNodeRef resolve(const Path& path);
+   void verifyCompatibility(const Path& _path, WIN32_FIND_DATAW _info);
    FileNodeRef create(const Path& path,FileNode::Mode);
    bool remove(const Path& path);
    bool rename(const Path& from,const Path& to);

+ 1 - 1
Engine/source/postFx/postEffect.cpp

@@ -737,7 +737,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       mShaderConsts->set( mMatPrevScreenToWorldSC, tempMat );
    }
 
-   if ( mAmbientColorSC->isValid() )
+   if (mAmbientColorSC->isValid() && state)
    {
       const ColorF &sunlight = state->getAmbientLightColor();
       Point3F ambientColor( sunlight.red, sunlight.green, sunlight.blue );

+ 13 - 14
Engine/source/renderInstance/renderPrePassMgr.cpp

@@ -202,21 +202,20 @@ void RenderPrePassMgr::addElement( RenderInst *inst )
    if ( isMeshInst || isDecalMeshInst )
       matInst = static_cast<MeshRenderInst*>(inst)->matInst;
 
-   // Skip decals if they don't have normal maps.
-   if ( isDecalMeshInst && !matInst->hasNormalMap() )
-      return;
+   if (matInst)
+   {
+      // Skip decals if they don't have normal maps.
+      if (isDecalMeshInst && !matInst->hasNormalMap())
+         return;
 
-   // If its a custom material and it refracts... skip it.
-   if (  matInst && 
-         matInst->isCustomMaterial() &&
-         static_cast<CustomMaterial*>( matInst->getMaterial() )->mRefract )
-      return;
+      // If its a custom material and it refracts... skip it.
+      if (matInst->isCustomMaterial() &&
+         static_cast<CustomMaterial*>(matInst->getMaterial())->mRefract)
+         return;
 
-   // Make sure we got a prepass material.
-   if ( matInst )
-   {
-      matInst = getPrePassMaterial( matInst );
-      if ( !matInst || !matInst->isValid() )
+      // Make sure we got a prepass material.
+      matInst = getPrePassMaterial(matInst);
+      if (!matInst || !matInst->isValid())
          return;
    }
 
@@ -241,7 +240,7 @@ void RenderPrePassMgr::addElement( RenderInst *inst )
    elem.key = *((U32*)&invSortDistSq);
 
    // Next sort by pre-pass material if its a mesh... use the original sort key.
-   if ( isMeshInst )
+   if (isMeshInst && matInst)
       elem.key2 = matInst->getStateHint();
    else
       elem.key2 = originalKey;

+ 5 - 0
Engine/source/scene/sceneContainer.cpp

@@ -1012,6 +1012,11 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en
       F32 currStartX = normalStart.x;
 
       AssertFatal(currStartX != normalEnd.x, "This is going to cause problems in SceneContainer::castRay");
+      if(mIsNaN_F(currStartX))
+      {
+         PROFILE_END();
+         return false;
+      }
       while (currStartX != normalEnd.x)
       {
          F32 currEndX   = getMin(currStartX + csmTotalBinSize, normalEnd.x);

+ 2 - 2
Engine/source/scene/sceneObject.cpp

@@ -720,9 +720,9 @@ const char* SceneObject::_getRenderEnabled( void* object, const char* data )
 {
    SceneObject* obj = reinterpret_cast< SceneObject* >( object );
    if( obj->mObjectFlags.test( RenderEnabledFlag ) )
-      return "true";
+      return "1";
    else
-      return "false";
+      return "0";
 }
 
 //-----------------------------------------------------------------------------

+ 10 - 2
Engine/source/shaderGen/GLSL/bumpGLSL.cpp

@@ -347,8 +347,16 @@ void ParallaxFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
    Var *normalMap = getNormalMapTex();
 	
    // Call the library function to do the rest.
-   meta->addStatement( new GenOp( "   @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", 
-      texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) );
+   if (fd.features.hasFeature(MFT_IsDXTnm, getProcessIndex()))
+   {
+      meta->addStatement(new GenOp("   @.xy += parallaxOffsetDxtnm( @, @.xy, @, @ );\r\n",
+      texCoord, normalMap, texCoord, negViewTS, parallaxInfo));
+   }
+   else
+   {
+      meta->addStatement(new GenOp("   @.xy += parallaxOffset( @, @.xy, @, @ );\r\n",
+      texCoord, normalMap, texCoord, negViewTS, parallaxInfo));
+   }
    
    // TODO: Fix second UV maybe?
 	

+ 10 - 2
Engine/source/shaderGen/HLSL/bumpHLSL.cpp

@@ -347,8 +347,16 @@ void ParallaxFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
    Var *normalMap = getNormalMapTex();
 
    // Call the library function to do the rest.
-   meta->addStatement( new GenOp( "   @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", 
-      texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) );
+   if(fd.features.hasFeature( MFT_IsDXTnm, getProcessIndex() ))
+   {
+      meta->addStatement( new GenOp( "   @.xy += parallaxOffsetDxtnm( @, @.xy, @, @ );\r\n", 
+         texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) );
+   }
+   else
+   {
+      meta->addStatement( new GenOp( "   @.xy += parallaxOffset( @, @.xy, @, @ );\r\n", 
+         texCoord, normalMap, texCoord, negViewTS, parallaxInfo ) );
+   }
 
    // TODO: Fix second UV maybe?
 

+ 1 - 1
Engine/source/sim/netConnection.cpp

@@ -215,7 +215,7 @@ U32 NetConnection::getSequence()
 static U32 gPacketRateToServer = 32;
 static U32 gPacketUpdateDelayToServer = 32;
 static U32 gPacketRateToClient = 10;
-static U32 gPacketSize = 200;
+static U32 gPacketSize = 508;
 
 void NetConnection::consoleInit()
 {

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

@@ -818,7 +818,7 @@ public:
    /// Some configuration values.
    enum GhostConstants
    {
-      GhostIdBitSize = 12,
+      GhostIdBitSize = 18, //262,144 ghosts
       MaxGhostCount = 1 << GhostIdBitSize, //4096,
       GhostLookupTableSize = 1 << GhostIdBitSize, //4096
       GhostIndexBitSize = 4 // number of bits GhostIdBitSize-3 fits into

+ 10 - 4
Engine/source/terrain/glsl/terrFeatureGLSL.cpp

@@ -468,8 +468,16 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
       Var *normalMap = _getNormalMapTex();
 
       // Call the library function to do the rest.
-      meta->addStatement( new GenOp( "   @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", 
-         inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
+      if (fd.features.hasFeature(MFT_IsDXTnm, detailIndex))
+      {
+         meta->addStatement(new GenOp("   @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n",
+         inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
+      }
+      else
+      {
+         meta->addStatement(new GenOp("   @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n",
+         inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
+      }
    }
 
    // If this is a prepass then we skip color.
@@ -812,12 +820,10 @@ void TerrainMacroMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentL
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
 
-   Var *baseColor = (Var*)LangElement::find( "baseColor" );
    Var *outColor = (Var*)LangElement::find( "col" );
 
    meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
                                     outColor, outColor, outColor, detailColor, detailBlend ) );
-   //outColor, outColor, baseColor, detailColor, detailBlend ) );
 
    meta->addStatement( new GenOp( "   }\r\n" ) );
 

+ 10 - 3
Engine/source/terrain/hlsl/terrFeatureHLSL.cpp

@@ -468,8 +468,16 @@ void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
       Var *normalMap = _getNormalMapTex();
 
       // Call the library function to do the rest.
-      meta->addStatement( new GenOp( "   @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", 
-         inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
+      if(fd.features.hasFeature( MFT_IsDXTnm, detailIndex ) )
+      {
+         meta->addStatement( new GenOp( "   @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n", 
+            inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
+      }
+      else
+      {
+         meta->addStatement( new GenOp( "   @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", 
+            inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
+      }
    }
 
    // If this is a prepass then we skip color.
@@ -542,7 +550,6 @@ void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
 
-   Var *baseColor = (Var*)LangElement::find( "baseColor" );
    Var *outColor = (Var*)LangElement::find( "col" );
 
    meta->addStatement( new GenOp( "      @ += @ * @;\r\n",

+ 2 - 1
Engine/source/ts/tsMesh.cpp

@@ -224,7 +224,7 @@ void TSMesh::innerRender( TSMaterialList *materials, const TSRenderState &rdata,
       if ( draw.matIndex & TSDrawPrimitive::NoMaterial )
          continue;
 
-#ifdef TORQUE_DEBUG
+#ifdef TORQUE_DEBUG_BREAK_INSPECT
       // for inspection if you happen to be running in a debugger and can't do bit 
       // operations in your head.
       S32 triangles = draw.matIndex & TSDrawPrimitive::Triangles;
@@ -237,6 +237,7 @@ void TSMesh::innerRender( TSMaterialList *materials, const TSRenderState &rdata,
       TORQUE_UNUSED(fan);
       TORQUE_UNUSED(indexed);
       TORQUE_UNUSED(type);
+      //define TORQUE_DEBUG_BREAK_INSPECT, and insert debug break here to inspect the above elements at runtime
 #endif
 
       const U32 matIndex = draw.matIndex & TSDrawPrimitive::MaterialMask;

+ 2 - 2
Engine/source/ts/tsMeshFit.cpp

@@ -28,9 +28,9 @@
 #include "console/engineAPI.h"
 
 // define macros required for ConvexDecomp headers
-#if defined( _WIN32 )
+#if defined( _WIN32 ) && !defined( WIN32 )
 #define WIN32
-#elif defined( __MACOSX__ )
+#elif defined( __MACOSX__ ) && !defined( APPLE )
 #define APPLE
 #endif
 

+ 11 - 7
Engine/source/windowManager/sdl/sdlWindow.cpp

@@ -434,7 +434,8 @@ void PlatformWindowSDL::_triggerMouseLocationNotify(const SDL_Event& evt)
 
 void PlatformWindowSDL::_triggerMouseWheelNotify(const SDL_Event& evt)
 {
-   wheelEvent.trigger(getWindowId(), 0, evt.wheel.x, evt.wheel.y);
+   S32 wheelDelta = Con::getIntVariable("$pref::Input::MouseWheelSpeed", 120);
+   wheelEvent.trigger(getWindowId(), 0, evt.wheel.x * wheelDelta, evt.wheel.y * wheelDelta);
 }
 
 void PlatformWindowSDL::_triggerMouseButtonNotify(const SDL_Event& event)
@@ -483,12 +484,6 @@ void PlatformWindowSDL::_triggerKeyNotify(const SDL_Event& evt)
       keyEvent.trigger(getWindowId(), torqueModifiers, inputAction, torqueKey);
       //Con::printf("Key %d : %d", tKey.sym, inputAction);
    }
-
-   // stop SDL_TEXTINPUT event when unwanted
-   if( inputAction == IA_MAKE && getKeyboardTranslation() && shouldNotTranslate( torqueModifiers, torqueKey ) )	
-      SDL_StopTextInput();
-   else   
-      SDL_StartTextInput();
 }
 
 void PlatformWindowSDL::_triggerTextNotify(const SDL_Event& evt)
@@ -605,3 +600,12 @@ const UTF16 *PlatformWindowSDL::getCurtainWindowClassName()
    static String str("CurtainWindowClassName");
    return str.utf16();
 }
+
+void PlatformWindowSDL::setKeyboardTranslation(const bool enabled)
+{
+   mEnableKeyboardTranslation = enabled;
+   if (mEnableKeyboardTranslation)
+      SDL_StartTextInput();
+   else
+      SDL_StopTextInput();
+}

+ 3 - 0
Engine/source/windowManager/sdl/sdlWindow.h

@@ -160,6 +160,9 @@ public:
    virtual bool isMouseLocked() const { return mMouseLocked; };
    virtual bool shouldLockMouse() const { return mShouldLockMouse; };
 
+   /// Set if relevant keypress events should be translated into character input events.
+   virtual void setKeyboardTranslation(const bool enabled);
+
    virtual WindowId getWindowId();
 
    SDL_Window* getSDLWindow() const { return mWindowHandle; }

+ 19 - 14
Engine/source/windowManager/windowInputGenerator.cpp

@@ -82,27 +82,32 @@ WindowInputGenerator::~WindowInputGenerator()
 //-----------------------------------------------------------------------------
 void WindowInputGenerator::generateInputEvent( InputEventInfo &inputEvent )
 {
-   if( !mInputController || !mFocused )
+   if (!mInputController || !mFocused)
       return;
 
-    if (inputEvent.action == SI_MAKE && inputEvent.deviceType == KeyboardDeviceType)
-    {
-        for( int i = 0; i < mAcceleratorMap.size(); ++i )
-        {
-            const AccKeyMap &acc = mAcceleratorMap[i];
-            if( acc.modifier & inputEvent.modifier && acc.keyCode == inputEvent.objInst )
-            {
-                Con::evaluatef(acc.cmd);
-                return;
-            }
-        }
-    }
+   if (inputEvent.action == SI_MAKE && inputEvent.deviceType == KeyboardDeviceType)
+   {
+      for (int i = 0; i < mAcceleratorMap.size(); ++i)
+      {
+         const AccKeyMap &acc = mAcceleratorMap[i];
+         if (!mWindow->getKeyboardTranslation() &&
+            (acc.modifier & inputEvent.modifier || (acc.modifier == 0 && inputEvent.modifier == 0))
+            && acc.keyCode == inputEvent.objInst)
+         {
+            Con::evaluatef(acc.cmd);
+            return;
+         }
+      }
+   }
 
    // Give the ActionMap first shot.
    if (ActionMap::handleEventGlobal(&inputEvent))
       return;
 
-   if( mInputController->processInputEvent( inputEvent ) )
+   if (mInputController->processInputEvent(inputEvent))
+      return;
+
+   if (mWindow->getKeyboardTranslation())
       return;
 
    // If we get here we failed to process it with anything prior... so let

+ 1 - 0
Templates/Empty/game/core/scripts/client/defaults.cs

@@ -41,6 +41,7 @@ $pref::Input::KeyboardEnabled = 1;
 $pref::Input::MouseEnabled = 1;
 $pref::Input::JoystickEnabled = 0;
 $pref::Input::KeyboardTurnSpeed = 0.1;
+$pref::Input::MouseWheelSpeed = 120;
 
 $sceneLighting::cacheSize = 20000;
 $sceneLighting::purgeMethod = "lastCreated";

+ 1 - 1
Templates/Empty/game/core/scripts/gui/messageBoxes/messageBox.ed.cs

@@ -21,7 +21,7 @@
 //-----------------------------------------------------------------------------
 
 if($GameCanvas == OculusCanvas)
-   $GameCanvas = 0;
+   $GameCanvas = Canvas;
 
 // Cleanup Dialog created by 'core'
 if( isObject( MessagePopupDlg ) )

+ 17 - 2
Templates/Empty/game/shaders/common/gl/torque.glsl

@@ -139,12 +139,27 @@ mat3x3 quatToMat( vec4 quat )
 vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale )
 {
    float depth = texture( texMap, texCoord ).a;
-   vec2 offset = negViewTS.xy * ( depth * depthScale );
+   vec2 offset = negViewTS.xy * vec2( depth * depthScale );
 
    for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ )
    {
       depth = ( depth + texture( texMap, texCoord + offset ).a ) * 0.5;
-      offset = negViewTS.xy * ( depth * depthScale );
+      offset = negViewTS.xy * vec2( depth * depthScale );
+   }
+
+   return offset;
+}
+
+/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha
+vec2 parallaxOffsetDxtnm(sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale)
+{
+   float depth = texture(texMap, texCoord).r;
+   vec2 offset = negViewTS.xy * vec2(depth * depthScale);
+
+   for (int i = 0; i < PARALLAX_REFINE_STEPS; i++)
+   {
+      depth = (depth + texture(texMap, texCoord + offset).r) * 0.5;
+      offset = negViewTS.xy * vec2(depth * depthScale);
    }
 
    return offset;

+ 15 - 0
Templates/Empty/game/shaders/common/torque.hlsl

@@ -151,6 +151,21 @@ float2 parallaxOffset( sampler2D texMap, float2 texCoord, float3 negViewTS, floa
    return offset;
 }
 
+/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha
+float2 parallaxOffsetDxtnm(sampler2D texMap, float2 texCoord, float3 negViewTS, float depthScale)
+{
+   float depth = tex2D(texMap, texCoord).r;
+   float2 offset = negViewTS.xy * (depth * depthScale);
+
+   for (int i = 0; i < PARALLAX_REFINE_STEPS; i++)
+   {
+      depth = (depth + tex2D(texMap, texCoord + offset).r) * 0.5;
+      offset = negViewTS.xy * (depth * depthScale);
+   }
+
+   return offset;
+}
+
 
 /// The maximum value for 16bit per component integer HDR encoding.
 static const float HDR_RGB16_MAX = 100.0;

+ 1 - 1
Templates/Empty/game/tools/base/menuBar/menuBuilder.ed.cs

@@ -132,7 +132,7 @@ function MenuBuilder::addItem(%this, %pos, %item)
    }
    else
    {
-      %this.insertItem(%pos, %name !$= "-" ? %name : "", %accel);
+      %this.insertItem(%pos, %name !$= "-" ? %name : "", %accel, %cmd);
    }
 }
 

+ 0 - 0
Templates/Empty/game/tools/classIcons/basicClouds.png → Templates/Empty/game/tools/classIcons/BasicClouds.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/camera.png → Templates/Empty/game/tools/classIcons/Camera.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/cameraBookmark.png → Templates/Empty/game/tools/classIcons/CameraBookmark.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/cloudLayer.png → Templates/Empty/game/tools/classIcons/CloudLayer.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/convexShape.png → Templates/Empty/game/tools/classIcons/ConvexShape.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/decalRoad.png → Templates/Empty/game/tools/classIcons/DecalRoad.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/forest.png → Templates/Empty/game/tools/classIcons/Forest.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/forestBrush.png → Templates/Empty/game/tools/classIcons/ForestBrush.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/groundCover.png → Templates/Empty/game/tools/classIcons/GroundCover.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/groundPlane.png → Templates/Empty/game/tools/classIcons/GroundPlane.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/guiControl.png → Templates/Empty/game/tools/classIcons/GuiControl.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/GuiFadeInBitmapCtrl.png → Templates/Empty/game/tools/classIcons/GuiFadeinBitmapCtrl.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/item.png → Templates/Empty/game/tools/classIcons/Item.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/levelInfo.png → Templates/Empty/game/tools/classIcons/LevelInfo.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/lightning.png → Templates/Empty/game/tools/classIcons/Lightning.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/marker.png → Templates/Empty/game/tools/classIcons/Marker.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/meshRoad.png → Templates/Empty/game/tools/classIcons/MeshRoad.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/missionArea.png → Templates/Empty/game/tools/classIcons/MissionArea.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/particleEmitter.png → Templates/Empty/game/tools/classIcons/ParticleEmitter.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/particleEmitterNode.png → Templates/Empty/game/tools/classIcons/ParticleEmitterNode.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/path.png → Templates/Empty/game/tools/classIcons/Path.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/physicalZone.png → Templates/Empty/game/tools/classIcons/PhysicalZone.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/player.png → Templates/Empty/game/tools/classIcons/Player.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/pointLight.png → Templates/Empty/game/tools/classIcons/PointLight.png


+ 0 - 0
Templates/Empty/game/tools/classIcons/portal.png → Templates/Empty/game/tools/classIcons/Portal.png


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