Browse Source

Merge branch 'development' of https://github.com/thecelloman/Torque3D

thecelloman 12 years ago
parent
commit
69cae68e6d
100 changed files with 1160 additions and 346 deletions
  1. 2 1
      .gitignore
  2. 3 0
      Engine/lib/convexDecomp/NvRemoveTjunctions.cpp
  3. 10 0
      Engine/source/T3D/aiPlayer.cpp
  4. 26 6
      Engine/source/T3D/convexShape.cpp
  5. 4 0
      Engine/source/T3D/convexShape.h
  6. 14 5
      Engine/source/T3D/decal/decalManager.cpp
  7. 200 0
      Engine/source/T3D/fps/guiHealthTextHud.cpp
  8. 4 3
      Engine/source/T3D/fx/particle.cpp
  9. 14 13
      Engine/source/T3D/fx/particleEmitter.cpp
  10. 3 3
      Engine/source/T3D/gameBase/gameConnectionEvents.cpp
  11. 1 1
      Engine/source/T3D/gameBase/std/stdMoveList.cpp
  12. 17 2
      Engine/source/T3D/item.cpp
  13. 3 0
      Engine/source/T3D/item.h
  14. 11 0
      Engine/source/T3D/missionMarker.cpp
  15. 1 0
      Engine/source/T3D/missionMarker.h
  16. 5 1
      Engine/source/T3D/physics/bullet/btWorld.cpp
  17. 5 0
      Engine/source/T3D/physics/physicsWorld.h
  18. 9 1
      Engine/source/T3D/physics/physx/pxPlayer.cpp
  19. 2 0
      Engine/source/T3D/physics/physx/pxPlayer.h
  20. 6 1
      Engine/source/T3D/physics/physx/pxWorld.cpp
  21. 12 1
      Engine/source/T3D/player.cpp
  22. 4 0
      Engine/source/T3D/player.h
  23. 12 0
      Engine/source/T3D/shapeBase.cpp
  24. 3 0
      Engine/source/T3D/shapeBase.h
  25. 2 0
      Engine/source/T3D/tsStatic.cpp
  26. 20 4
      Engine/source/T3D/turret/turretShape.cpp
  27. 21 4
      Engine/source/app/net/tcpObject.cpp
  28. 5 0
      Engine/source/collision/abstractPolyList.h
  29. 27 1
      Engine/source/collision/clippedPolyList.cpp
  30. 1 0
      Engine/source/collision/clippedPolyList.h
  31. 35 35
      Engine/source/console/arrayObject.cpp
  32. 5 5
      Engine/source/console/arrayObject.h
  33. 1 1
      Engine/source/console/dynamicTypes.h
  34. 1 1
      Engine/source/console/engineTypes.h
  35. 17 0
      Engine/source/core/bitVector.h
  36. 5 5
      Engine/source/core/dnet.cpp
  37. 2 0
      Engine/source/core/stream/bitStream.cpp
  38. 5 2
      Engine/source/environment/editors/guiRiverEditorCtrl.cpp
  39. 1 0
      Engine/source/environment/editors/guiRiverEditorCtrl.h
  40. 10 4
      Engine/source/gfx/gfxFontRenderBatcher.cpp
  41. 3 1
      Engine/source/gui/containers/guiTabBookCtrl.cpp
  42. 11 3
      Engine/source/gui/controls/guiTreeViewCtrl.cpp
  43. 2 1
      Engine/source/gui/core/guiArrayCtrl.cpp
  44. 8 1
      Engine/source/gui/worldEditor/guiConvexShapeEditorCtrl.cpp
  45. 13 1
      Engine/source/gui/worldEditor/guiDecalEditorCtrl.cpp
  46. 3 0
      Engine/source/gui/worldEditor/worldEditor.cpp
  47. 3 3
      Engine/source/lighting/advanced/advancedLightingFeatures.cpp
  48. 3 3
      Engine/source/lighting/basic/basicLightManager.cpp
  49. 10 1
      Engine/source/lighting/common/lightMapParams.cpp
  50. 1 1
      Engine/source/lighting/common/lightMapParams.h
  51. 3 3
      Engine/source/lighting/lightManager.cpp
  52. 10 2
      Engine/source/lighting/shadowMap/lightShadowMap.cpp
  53. 1 1
      Engine/source/lighting/shadowMap/lightShadowMap.h
  54. 8 1
      Engine/source/materials/processedCustomMaterial.cpp
  55. 1 1
      Engine/source/math/mOrientedBox.cpp
  56. 2 2
      Engine/source/math/mSilhouetteExtractor.h
  57. 5 5
      Engine/source/platform/platform.h
  58. 3 3
      Engine/source/platform/platformCPUCount.cpp
  59. 2 0
      Engine/source/platform/types.visualc.h
  60. 2 0
      Engine/source/platform/typesWin32.h
  61. 16 4
      Engine/source/platformX86UNIX/threads/semaphore.cpp
  62. 2 0
      Engine/source/platformX86UNIX/x86UNIXStub.dedicated.cpp
  63. 54 65
      Engine/source/renderInstance/renderOcclusionMgr.cpp
  64. 12 6
      Engine/source/renderInstance/renderOcclusionMgr.h
  65. 1 1
      Engine/source/renderInstance/renderPassManager.cpp
  66. 2 2
      Engine/source/scene/reflectionManager.cpp
  67. 1 1
      Engine/source/scene/reflectionManager.h
  68. 4 3
      Engine/source/scene/sceneContainer.cpp
  69. 1 1
      Engine/source/scene/zones/scenePolyhedralZone.cpp
  70. 44 44
      Engine/source/sfx/fmod/fmodFunctions.h
  71. 2 2
      Engine/source/sfx/fmod/sfxFMODDevice.cpp
  72. 2 2
      Engine/source/sfx/fmod/sfxFMODDevice.h
  73. 3 3
      Engine/source/sfx/fmod/sfxFMODEvent.cpp
  74. 6 11
      Engine/source/sfx/fmod/sfxFMODProvider.cpp
  75. 2 2
      Engine/source/sfx/sfxDescription.cpp
  76. 61 53
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
  77. 1 1
      Engine/source/sim/netEvent.cpp
  78. 1 0
      Engine/source/terrain/terrCollision.cpp
  79. 5 0
      Engine/source/ts/collada/colladaAppMesh.cpp
  80. 67 10
      Engine/source/ts/tsMesh.cpp
  81. 3 0
      Engine/source/ts/tsShapeConstruct.h
  82. BIN
      QtCore4.dll
  83. BIN
      QtGui4.dll
  84. BIN
      QtNetwork4.dll
  85. BIN
      QtXml4.dll
  86. BIN
      Templates/Empty PhysX/game/Empty PhysX.dll
  87. BIN
      Templates/Empty PhysX/game/Empty PhysX.exe
  88. BIN
      Templates/Empty PhysX/game/IE Empty PhysX Plugin.dll
  89. BIN
      Templates/Empty PhysX/game/NP Empty PhysX Plugin.dll
  90. 7 0
      Templates/Empty PhysX/game/scripts/client/serverConnection.cs
  91. 1 1
      Templates/Empty PhysX/game/tools/materialEditor/scripts/materialEditor.ed.cs
  92. 4 1
      Templates/Empty PhysX/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs
  93. 67 0
      Templates/Empty/DeleteCachedDTSs.command
  94. 65 0
      Templates/Empty/buildFiles/config/project.linux_ded.conf
  95. 96 0
      Templates/Empty/buildFiles/config/torque3D_dedicated.conf
  96. BIN
      Templates/Empty/cleanShaders.command
  97. BIN
      Templates/Empty/game/Empty.exe
  98. BIN
      Templates/Empty/game/IE Empty Plugin.dll
  99. BIN
      Templates/Empty/game/NP Empty Plugin.dll
  100. 7 0
      Templates/Empty/game/scripts/client/serverConnection.cs

+ 2 - 1
.gitignore

@@ -159,7 +159,7 @@ pip-log.txt
 #Mr Developer
 .mr.developer.cfg
 
-# Mac crap
+# Mac
 .DS_Store
 
 #############
@@ -169,3 +169,4 @@ pip-log.txt
 console.log
 *.cached.dts
 !Engine/bin
+My Projects/

+ 3 - 0
Engine/lib/convexDecomp/NvRemoveTjunctions.cpp

@@ -67,6 +67,9 @@ NvRemoveTjunctions.cpp : A code snippet to remove tjunctions from a triangle mes
 #include "NvHashMap.h"
 #include "NvRemoveTjunctions.h"
 #include "NvFloatMath.h"
+#ifdef LINUX
+   #include <climits>
+#endif
 
 #pragma warning(disable:4189)
 

+ 10 - 0
Engine/source/T3D/aiPlayer.cpp

@@ -494,6 +494,16 @@ DefineEngineMethod( AIPlayer, setMoveSpeed, void, ( F32 speed ),,
 	object->setMoveSpeed(speed);
 }
 
+DefineEngineMethod( AIPlayer, getMoveSpeed, F32, ( ),,
+   "@brief Gets the move speed of an AI object.\n\n"
+
+   "@return A speed multiplier between 0.0 and 1.0.\n\n"
+
+   "@see setMoveSpeed()\n")
+{
+   return object->getMoveSpeed();
+}
+
 DefineEngineMethod( AIPlayer, setMoveDestination, void, ( Point3F goal, bool slowDown ), ( true ),
    "@brief Tells the AI to move to the location provided\n\n"
 

+ 26 - 6
Engine/source/T3D/convexShape.cpp

@@ -367,7 +367,14 @@ void ConvexShape::writeFields( Stream &stream, U32 tabStop )
 
    stream.write(2, "\r\n");   
 
-   for ( U32 i = 0; i < mSurfaces.size(); i++ )
+   S32 count = mSurfaces.size();
+   if ( count > smMaxSurfaces )
+   {
+       Con::errorf( "ConvexShape has too many surfaces to save! Truncated value %d to maximum value of %d", count, smMaxSurfaces );
+       count = smMaxSurfaces;
+   }
+
+   for ( U32 i = 0; i < count; i++ )
    {      
       const MatrixF &mat = mSurfaces[i];
 
@@ -423,12 +430,18 @@ U32 ConvexShape::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
    if ( stream->writeFlag( mask & UpdateMask ) )
    {
       stream->write( mMaterialName );
-
-      const U32 surfCount = mSurfaces.size();
+      
+      U32 surfCount = mSurfaces.size();
       stream->writeInt( surfCount, 32 );
 
-      for ( S32 i = 0; i < surfCount; i++ )      
-         mathWrite( *stream, mSurfaces[i] );               
+      for ( S32 i = 0; i < surfCount; i++ )    
+      {
+         QuatF quat( mSurfaces[i] );
+		 Point3F pos( mSurfaces[i].getPosition() );
+
+         mathWrite( *stream, quat );
+         mathWrite( *stream, pos );                    
+      }
    }
 
    return retMask;
@@ -462,7 +475,14 @@ void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream )
          mSurfaces.increment();
          MatrixF &mat = mSurfaces.last();
 
-         mathRead( *stream, &mat );
+         QuatF quat;
+         Point3F pos;
+
+         mathRead( *stream, &quat );
+         mathRead( *stream, &pos ); 
+
+         quat.setMatrix( &mat );
+         mat.setPosition( pos );
       }
 
       if ( isProperlyAdded() )

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

@@ -141,6 +141,10 @@ public:
 
    static bool smRenderEdges;   
 
+   // To prevent bitpack overflows.
+   // This is only indirectly enforced by trucation when serializing.
+   static const S32 smMaxSurfaces = 100;
+
 public:
    
    ConvexShape();

+ 14 - 5
Engine/source/T3D/decal/decalManager.cpp

@@ -361,19 +361,28 @@ bool DecalManager::clipDecal( DecalInstance *decal, Vector<Point3F> *edgeVerts,
    mClipper.cullUnusedVerts();
    mClipper.triangulate();
    
+   const U32 numVerts = mClipper.mVertexList.size();
+   const U32 numIndices = mClipper.mIndexList.size();
+
+   if ( !numVerts || !numIndices )
+      return false;
+
+   // Fail if either of the buffer metrics exceeds our limits
+   // on dynamic geometry buffers.
+   if ( numVerts > smMaxVerts ||
+        numIndices > smMaxIndices )
+      return false;
+
    if ( !decalData->skipVertexNormals )
       mClipper.generateNormals();
    
-   if ( mClipper.mVertexList.empty() )
-      return false;
-
 #ifdef DECALMANAGER_DEBUG
    mDebugPlanes.clear();
    mDebugPlanes.merge( mClipper.mPlaneList );
 #endif
 
-   decal->mVertCount = mClipper.mVertexList.size();
-   decal->mIndxCount = mClipper.mIndexList.size();
+   decal->mVertCount = numVerts;
+   decal->mIndxCount = numIndices;
    
    Vector<Point3F> tmpPoints;
 

+ 200 - 0
Engine/source/T3D/fps/guiHealthTextHud.cpp

@@ -0,0 +1,200 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------  
+// A gui control that displays health or energy information.  Based upon the   
+// stock healthBar control but rewritten by M.Hall to display a numerical value.  
+// ----------------------------------------------------------------------------  
+  
+#include "platform/platform.h"  
+#include "gui/core/guiControl.h"  
+#include "console/consoleTypes.h"  
+#include "T3D/gameBase/gameConnection.h"  
+#include "T3D/shapeBase.h"  
+#include "gfx/gfxDrawUtil.h"  
+  
+class GuiHealthTextHud : public GuiControl  
+{  
+   typedef GuiControl Parent;  
+  
+   bool mShowFrame;  
+   bool mShowFill;  
+   bool mShowEnergy;  
+   bool mShowTrueHealth;  
+  
+   ColorF mFillColor;  
+   ColorF mFrameColor;  
+   ColorF mTextColor;  
+   ColorF mWarnColor;  
+  
+   F32 mWarnLevel;  
+   F32 mPulseThreshold;  
+   S32 mPulseRate;  
+  
+   F32 mValue;  
+  
+public:  
+   GuiHealthTextHud();  
+  
+   void onRender(Point2I, const RectI &);  
+   static void initPersistFields();  
+   DECLARE_CONOBJECT(GuiHealthTextHud);  
+   DECLARE_CATEGORY("Gui Game");  
+   DECLARE_DESCRIPTION("Shows the damage or energy level of the current\n"  
+      "PlayerObjectType control object as a numerical text display.");  
+};  
+  
+// ----------------------------------------------------------------------------  
+  
+IMPLEMENT_CONOBJECT(GuiHealthTextHud);  
+  
+ConsoleDocClass(GuiHealthTextHud,  
+   "@brief Shows the health or energy value of the current PlayerObjectType control object.\n\n"  
+   "This gui can be configured to display either the health or energy value of the current Player Object. "  
+   "It can use an alternate display color if the health or drops below a set value. "  
+   "It can also be set to pulse if the health or energy drops below a set value. "  
+   "This control only works if a server connection exists and it's control object "  
+   "is a PlayerObjectType. If either of these requirements is false, the control is not rendered.\n\n"  
+  
+   "@tsexample\n"  
+      "\n new GuiHealthTextHud()"  
+      "{\n"  
+      "   fillColor = \"0.0 0.0 0.0 0.5\"; // Fills with a transparent black color\n"  
+      "   frameColor = \"1.0 1.0 1.0 1.0\"; // Solid white frame color\n"  
+      "   textColor = \"0.0 1.0 0.0 1.0\" // Solid green text color\n"  
+      "   warningColor = \"1.0 0.0 0.0 1.0\"; // Solid red color, used when damaged\n"  
+      "   showFill = \"true\";\n"  
+      "   showFrame = \"true\";\n"  
+      "   showTrueValue = \"false\";\n"  
+      "   showEnergy = \"false\";\n"  
+      "   warnThreshold = \"50\";\n"  
+      "   pulseThreshold = \"25\";\n"  
+      "   pulseRate = \"500\";\n"  
+      "   profile = \"GuiBigTextProfile\";\n"  
+      "};\n"  
+   "@endtsexample\n\n"  
+  
+   "@ingroup GuiGame\n"  
+);  
+  
+GuiHealthTextHud::GuiHealthTextHud()  
+{  
+   mShowFrame = mShowFill = true;  
+   mShowEnergy = false;  
+   mShowTrueHealth = false;  
+  
+   mFillColor.set(0, 0, 0, 0.5);  
+   mFrameColor.set(1, 1, 1, 1);  
+   mTextColor.set(0, 1, 0, 1);  
+   mWarnColor.set(1, 0, 0, 1);  
+  
+   mWarnLevel = 50.0f;  
+   mPulseThreshold = 25.0f;  
+   mPulseRate = 0;  
+     
+   mValue = 0.2f;  
+}  
+  
+void GuiHealthTextHud::initPersistFields()  
+{  
+   addGroup("Colors");       
+   addField("fillColor", TypeColorF, Offset(mFillColor, GuiHealthTextHud), "Color for the background of the control.");  
+   addField("frameColor", TypeColorF, Offset(mFrameColor, GuiHealthTextHud), "Color for the control's frame.");  
+   addField("textColor", TypeColorF, Offset(mTextColor, GuiHealthTextHud), "Color for the text on this control.");  
+   addField("warningColor", TypeColorF, Offset(mWarnColor, GuiHealthTextHud), "Color for the text when health is low.");    
+   endGroup("Colors");          
+  
+   addGroup("View");      
+   addField("showFill", TypeBool, Offset(mShowFill, GuiHealthTextHud), "If true, draw the background.");  
+   addField("showFrame", TypeBool, Offset(mShowFrame, GuiHealthTextHud), "If true, draw the frame.");  
+   addField("showTrueValue", TypeBool, Offset(mShowTrueHealth, GuiHealthTextHud), "If true, we don't hardcode maxHealth to 100.");  
+   addField("showEnergy", TypeBool, Offset(mShowEnergy, GuiHealthTextHud), "If true, display the energy value rather than the damage value.");  
+   endGroup("View");    
+  
+   addGroup("Alert");  
+   addField("warnThreshold", TypeF32, Offset(mWarnLevel, GuiHealthTextHud), "The health level at which to use the warningColor.");    
+   addField("pulseThreshold", TypeF32, Offset(mPulseThreshold, GuiHealthTextHud), "Health level at which to begin pulsing.");  
+   addField("pulseRate", TypeS32, Offset(mPulseRate, GuiHealthTextHud), "Speed at which the control will pulse.");  
+   endGroup("Alert");  
+  
+   Parent::initPersistFields();  
+}  
+  
+// ----------------------------------------------------------------------------  
+  
+void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)  
+{  
+   // Must have a connection and player control object  
+   GameConnection* conn = GameConnection::getConnectionToServer();  
+   if (!conn)  
+      return;  
+   ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject());  
+   if (!control || !(control->getTypeMask() & PlayerObjectType))  
+      return;  
+  
+   // Just grab the damage/energy right off the control object.    
+   // Damage value 0 = no damage (full health).    
+   if(mShowEnergy)    
+      mValue = control->getEnergyLevel();  
+   else    
+   {  
+      if (mShowTrueHealth)  
+         mValue = control->getMaxDamage() - control->getDamageLevel();  
+      else  
+         mValue = 100 - (100 * control->getDamageValue());    
+   }  
+  
+   // If enabled draw background first  
+   if (mShowFill)  
+      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);  
+  
+   // Prepare text and center it  
+   S32 val = (S32)mValue;    
+   char buf[256];    
+   dSprintf(buf, sizeof(buf), "%d", val);    
+   offset.x += (getBounds().extent.x - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;    
+   offset.y += (getBounds().extent.y - mProfile->mFont->getHeight()) / 2;    
+  
+   ColorF tColor = mTextColor;   
+  
+   // If warning level is exceeded switch to warning color  
+   if(mValue < mWarnLevel)   
+   {  
+      tColor = mWarnColor;    
+  
+      // If the pulseRate is set then pulse the text if health is below the threshold  
+      if (mPulseRate != 0 && mValue < mPulseThreshold)   
+      {  
+         U32 time = Platform::getVirtualMilliseconds();  
+         F32 alpha = 2.0f * F32(time % mPulseRate) / F32(mPulseRate);  
+         tColor.alpha = (alpha > 1.0f)? 2.0f - alpha: alpha;  
+      }  
+   }  
+  
+   GFX->getDrawUtil()->setBitmapModulation(tColor);    
+   GFX->getDrawUtil()->drawText(mProfile->mFont, offset, buf);    
+   GFX->getDrawUtil()->clearBitmapModulation();    
+  
+   // If enabled draw the border last  
+   if (mShowFrame)  
+      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);  
+}  

+ 4 - 3
Engine/source/T3D/fx/particle.cpp

@@ -21,6 +21,7 @@
 //-----------------------------------------------------------------------------
 #include "particle.h"
 #include "console/consoleTypes.h"
+#include "console/typeValidators.h"
 #include "core/stream/bitStream.h"
 #include "math/mRandom.h"
 #include "math/mathIO.h"
@@ -132,13 +133,13 @@ ParticleData::~ParticleData()
 //-----------------------------------------------------------------------------
 void ParticleData::initPersistFields()
 {
-   addField( "dragCoefficient", TYPEID< F32 >(), Offset(dragCoefficient, ParticleData),
+   addFieldV( "dragCoefficient", TYPEID< F32 >(), Offset(dragCoefficient, ParticleData), new FRangeValidator(0, 5),
       "Particle physics drag amount." );
    addField( "windCoefficient", TYPEID< F32 >(), Offset(windCoefficient, ParticleData),
       "Strength of wind on the particles." );
-   addField( "gravityCoefficient", TYPEID< F32 >(), Offset(gravityCoefficient, ParticleData),
+   addFieldV( "gravityCoefficient", TYPEID< F32 >(), Offset(gravityCoefficient, ParticleData), new FRangeValidator(-10, 10),
       "Strength of gravity on the particles." );
-   addField( "inheritedVelFactor", TYPEID< F32 >(), Offset(inheritedVelFactor, ParticleData),
+   addFieldV( "inheritedVelFactor", TYPEID< F32 >(), Offset(inheritedVelFactor, ParticleData), &CommonValidators::NormalizedFloat,
       "Amount of emitter velocity to add to particle initial velocity." );
    addField( "constantAcceleration", TYPEID< F32 >(), Offset(constantAcceleration, ParticleData),
       "Constant acceleration to apply to this particle." );

+ 14 - 13
Engine/source/T3D/fx/particleEmitter.cpp

@@ -26,6 +26,7 @@
 #include "scene/sceneManager.h"
 #include "scene/sceneRenderState.h"
 #include "console/consoleTypes.h"
+#include "console/typeValidators.h"
 #include "core/stream/bitStream.h"
 #include "core/strings/stringUnit.h"
 #include "math/mRandom.h"
@@ -177,31 +178,31 @@ void ParticleEmitterData::initPersistFields()
 {
    addGroup( "ParticleEmitterData" );
 
-      addField("ejectionPeriodMS", TYPEID< S32 >(), Offset(ejectionPeriodMS,   ParticleEmitterData),
+      addFieldV("ejectionPeriodMS", TYPEID< S32 >(), Offset(ejectionPeriodMS,   ParticleEmitterData), new IRangeValidator(1, 2047),
          "Time (in milliseconds) between each particle ejection." );
 
-      addField("periodVarianceMS", TYPEID< S32 >(), Offset(periodVarianceMS,   ParticleEmitterData),
+      addFieldV("periodVarianceMS", TYPEID< S32 >(), Offset(periodVarianceMS,   ParticleEmitterData), new IRangeValidator(0, 2047),
          "Variance in ejection period, from 1 - ejectionPeriodMS." );
 
-      addField( "ejectionVelocity", TYPEID< F32 >(), Offset(ejectionVelocity, ParticleEmitterData),
+      addFieldV( "ejectionVelocity", TYPEID< F32 >(), Offset(ejectionVelocity, ParticleEmitterData), new FRangeValidator(0, 655.35f),
          "Particle ejection velocity." );
 
-      addField( "velocityVariance", TYPEID< F32 >(), Offset(velocityVariance, ParticleEmitterData),
+      addFieldV( "velocityVariance", TYPEID< F32 >(), Offset(velocityVariance, ParticleEmitterData), new FRangeValidator(0, 163.83f),
          "Variance for ejection velocity, from 0 - ejectionVelocity." );
 
-      addField( "ejectionOffset", TYPEID< F32 >(), Offset(ejectionOffset, ParticleEmitterData),
+      addFieldV( "ejectionOffset", TYPEID< F32 >(), Offset(ejectionOffset, ParticleEmitterData), new FRangeValidator(0, 655.35f),
          "Distance along ejection Z axis from which to eject particles." );
 
-      addField( "thetaMin", TYPEID< F32 >(), Offset(thetaMin, ParticleEmitterData),
+      addFieldV( "thetaMin", TYPEID< F32 >(), Offset(thetaMin, ParticleEmitterData), new FRangeValidator(0, 180.0f),
          "Minimum angle, from the horizontal plane, to eject from." );
 
-      addField( "thetaMax", TYPEID< F32 >(), Offset(thetaMax, ParticleEmitterData),
+      addFieldV( "thetaMax", TYPEID< F32 >(), Offset(thetaMax, ParticleEmitterData), new FRangeValidator(0, 180.0f),
          "Maximum angle, from the horizontal plane, to eject particles from." );
 
-      addField( "phiReferenceVel", TYPEID< F32 >(), Offset(phiReferenceVel, ParticleEmitterData),
+      addFieldV( "phiReferenceVel", TYPEID< F32 >(), Offset(phiReferenceVel, ParticleEmitterData), new FRangeValidator(0, 360.0f),
          "Reference angle, from the vertical plane, to eject particles from." );
 
-      addField( "phiVariance", TYPEID< F32 >(), Offset(phiVariance, ParticleEmitterData),
+      addFieldV( "phiVariance", TYPEID< F32 >(), Offset(phiVariance, ParticleEmitterData), new FRangeValidator(0, 360.0f),
          "Variance from the reference angle, from 0 - 360." );
 
       addField( "softnessDistance", TYPEID< F32 >(), Offset(softnessDistance, ParticleEmitterData),
@@ -302,8 +303,8 @@ void ParticleEmitterData::packData(BitStream* stream)
 {
    Parent::packData(stream);
 
-   stream->writeInt(ejectionPeriodMS, 10);
-   stream->writeInt(periodVarianceMS, 10);
+   stream->writeInt(ejectionPeriodMS, 11);      // must match limit on valid range in ParticleEmitterData::initPersistFields
+   stream->writeInt(periodVarianceMS, 11);
    stream->writeInt((S32)(ejectionVelocity * 100), 16);
    stream->writeInt((S32)(velocityVariance * 100), 14);
    if( stream->writeFlag( ejectionOffset != sgDefaultEjectionOffset ) )
@@ -352,8 +353,8 @@ void ParticleEmitterData::unpackData(BitStream* stream)
 {
    Parent::unpackData(stream);
 
-   ejectionPeriodMS = stream->readInt(10);
-   periodVarianceMS = stream->readInt(10);
+   ejectionPeriodMS = stream->readInt(11);
+   periodVarianceMS = stream->readInt(11);
    ejectionVelocity = stream->readInt(16) / 100.0f;
    velocityVariance = stream->readInt(14) / 100.0f;
    if( stream->readFlag() )

+ 3 - 3
Engine/source/T3D/gameBase/gameConnectionEvents.cpp

@@ -328,9 +328,9 @@ void Sim3DAudioEvent::pack(NetConnection *con, BitStream *bstream)
       AssertFatal((1.0 - ((q.x * q.x) + (q.y * q.y) + (q.z * q.z))) >= (0.0 - 0.001),
                   "QuatF::normalize() is broken in Sim3DAudioEvent");
 
-      bstream->writeFloat(q.x,SoundRotBits);
-      bstream->writeFloat(q.y,SoundRotBits);
-      bstream->writeFloat(q.z,SoundRotBits);
+      bstream->writeSignedFloat(q.x,SoundRotBits);
+      bstream->writeSignedFloat(q.y,SoundRotBits);
+      bstream->writeSignedFloat(q.z,SoundRotBits);
       bstream->writeFlag(q.w < 0.0);
    }
 

+ 1 - 1
Engine/source/T3D/gameBase/std/stdMoveList.cpp

@@ -96,7 +96,7 @@ void StdMoveList::clientWriteMovePacket(BitStream *bstream)
    {
       move[offset + i].sendCount++;
       move[offset + i].pack(bstream,prevMove);
-      bstream->writeInt(move[offset + i].checksum,Move::ChecksumBits);
+      bstream->writeInt(move[offset + i].checksum & (~(0xFFFFFFFF << Move::ChecksumBits)),Move::ChecksumBits);
       prevMove = &move[offset+i];
    }
 }

+ 17 - 2
Engine/source/T3D/item.cpp

@@ -1276,11 +1276,26 @@ DefineEngineMethod( Item, getLastStickyNormal, const char *, (),,
 
 //----------------------------------------------------------------------------
 
+bool Item::_setStatic(void *object, const char *index, const char *data)
+{
+   Item *i = static_cast<Item*>(object);
+   i->mAtRest = dAtob(data);
+   i->setMaskBits(InitialUpdateMask | PositionMask);
+   return true;
+}
+
+bool Item::_setRotate(void *object, const char *index, const char *data)
+{
+   Item *i = static_cast<Item*>(object);
+   i->setMaskBits(InitialUpdateMask | RotationMask);
+   return true;
+}
+
 void Item::initPersistFields()
 {
    addGroup("Misc");	
-   addField("static",      TypeBool, Offset(mStatic, Item), "If true, the object is not moving in the world (and will not be updated through the network).\n");
-   addField("rotate",      TypeBool, Offset(mRotate, Item), "If true, the object will automatically rotate around its Z axis.\n");
+   addProtectedField("static", TypeBool, Offset(mStatic, Item), &_setStatic, &defaultProtectedGetFn, "If true, the object is not moving in the world.\n");
+   addProtectedField("rotate", TypeBool, Offset(mRotate, Item), &_setRotate, &defaultProtectedGetFn, "If true, the object will automatically rotate around its Z axis.\n");
    endGroup("Misc");
 
    Parent::initPersistFields();

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

@@ -150,6 +150,9 @@ class Item: public ShapeBase
    void buildConvex(const Box3F& box, Convex* convex);
    void onDeleteNotify(SimObject*);
 
+   static bool _setStatic(void *object, const char *index, const char *data);
+   static bool _setRotate(void *object, const char *index, const char *data);
+
   protected:
    void _updatePhysics();
    void prepRenderImage(SceneRenderState *state);

+ 11 - 0
Engine/source/T3D/missionMarker.cpp

@@ -382,6 +382,7 @@ ConsoleDocClass( SpawnSphere,
 SpawnSphere::SpawnSphere()
 {
    mAutoSpawn = false;
+   mSpawnTransform = false;
 
    mRadius = 100.f;
    mSphereWeight = 100.f;
@@ -420,6 +421,12 @@ SimObject* SpawnSphere::spawnObject(String additionalProps)
    // If we have a spawnObject add it to the MissionCleanup group
    if (spawnObject)
    {
+      if (mSpawnTransform)
+      {
+         if(SceneObject *s = dynamic_cast<SceneObject*>(spawnObject))
+            s->setTransform(getTransform());
+      }
+
       SimObject* cleanup = Sim::findObject("MissionCleanup");
 
       if (cleanup)
@@ -447,6 +454,7 @@ U32 SpawnSphere::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
    if(stream->writeFlag(mask & UpdateSphereMask))
    {
       stream->writeFlag(mAutoSpawn);
+      stream->writeFlag(mSpawnTransform);
 
       stream->write(mSpawnClass);
       stream->write(mSpawnDataBlock);
@@ -463,6 +471,7 @@ void SpawnSphere::unpackUpdate(NetConnection * con, BitStream * stream)
    if(stream->readFlag())
    {
       mAutoSpawn = stream->readFlag();
+      mSpawnTransform = stream->readFlag();
 
       stream->read(&mSpawnClass);
       stream->read(&mSpawnDataBlock);
@@ -505,6 +514,8 @@ void SpawnSphere::initPersistFields()
       "Command to execute immediately after spawning an object. New object id is stored in $SpawnObject.  Max 255 characters." );
    addField( "autoSpawn", TypeBool, Offset(mAutoSpawn, SpawnSphere),
       "Flag to spawn object as soon as SpawnSphere is created, true to enable or false to disable." );
+   addField( "spawnTransform", TypeBool, Offset(mSpawnTransform, SpawnSphere),
+      "Flag to set the spawned object's transform to the SpawnSphere's transform." );
    endGroup( "Spawn" );
 
    addGroup( "Dimensions" );

+ 1 - 0
Engine/source/T3D/missionMarker.h

@@ -176,6 +176,7 @@ class SpawnSphere : public MissionMarker
       String   mSpawnProperties;
       String   mSpawnScript;
       bool     mAutoSpawn;
+      bool     mSpawnTransform;
 
       // Radius/weight info
       F32      mRadius;

+ 5 - 1
Engine/source/T3D/physics/bullet/btWorld.cpp

@@ -33,7 +33,11 @@
 #include "console/consoleTypes.h"
 #include "scene/sceneRenderState.h"
 #include "T3D/gameBase/gameProcess.h"
-
+#ifdef _WIN32
+#include "BulletMultiThreaded/Win32ThreadSupport.h"
+#elif defined (USE_PTHREADS)
+#include "BulletMultiThreaded/PosixThreadSupport.h"
+#endif
 
 BtWorld::BtWorld() :
    mProcessList( NULL ),

+ 5 - 0
Engine/source/T3D/physics/physicsWorld.h

@@ -42,6 +42,8 @@ class PhysicsWorld
 {
 protected:
 
+   Signal<void()> mStaticChangedSignal;
+
    Signal<void()> mUpdateSignal;
 
    /// The current gravity force.
@@ -58,6 +60,9 @@ public:
    /// 
    Signal<void()>& getUpdateSignal() { return mUpdateSignal; }
 
+   // Called when a static body in the scene has been removed.
+   Signal<void()>& getStaticChangedSignal() { return mStaticChangedSignal; }
+   
    /// Overloaded to do debug drawing.
    ///
    /// It is assumed the GFX state is setup prior to this call for

+ 9 - 1
Engine/source/T3D/physics/physx/pxPlayer.cpp

@@ -53,7 +53,8 @@ void PxPlayer::_releaseController()
    if ( mController )
    {
       mController->getActor()->userData = NULL;
-	   mWorld->releaseController( *mController );
+      mWorld->getStaticChangedSignal().remove( this, &PxPlayer::_onStaticChanged );
+      mWorld->releaseController( *mController );
       mController = NULL;
    }
 }
@@ -99,6 +100,8 @@ void PxPlayer::init( const char *type,
       //mOriginOffset = 1.0f;
    }
 
+    mWorld->getStaticChangedSignal().notify( this, &PxPlayer::_onStaticChanged );
+
    // Put the kinematic actor on group 29.
    NxActor *kineActor = mController->getActor();
    kineActor->setGroup( 29 );
@@ -110,6 +113,11 @@ void PxPlayer::init( const char *type,
    kineActor->userData = &mUserData;
 }
 
+void PxPlayer::_onStaticChanged()
+{
+    mController->reportSceneChanged();
+}
+
 void PxPlayer::_onPhysicsReset( PhysicsResetEvent reset )
 {
    // The PhysX controller will crash out if it doesn't clear its

+ 2 - 0
Engine/source/T3D/physics/physx/pxPlayer.h

@@ -71,6 +71,8 @@ protected:
 
    void _onPhysicsReset( PhysicsResetEvent reset );
 
+   void _onStaticChanged();
+
 public:
    
 	PxPlayer();

+ 6 - 1
Engine/source/T3D/physics/physx/pxWorld.cpp

@@ -569,9 +569,11 @@ void PxWorld::_releaseQueues()
    mReleaseJointQueue.clear();
 
    // Now release any actors still pending in the queue.
+   bool staticChanged = false;
    for ( S32 i = 0; i < mReleaseActorQueue.size(); i++ )
    {
-      NxActor *currActor = mReleaseActorQueue[i];     
+      NxActor *currActor = mReleaseActorQueue[i];
+      staticChanged |= !currActor->isDynamic();
       mScene->releaseActor( *currActor );
    }
 
@@ -618,6 +620,9 @@ void PxWorld::_releaseQueues()
       mScene->releaseFluid( *currFluid );
    }
    mReleaseFluidQueue.clear();
+
+   if ( staticChanged )
+    mStaticChangedSignal.trigger();
 }
 
 void PxWorld::setEnabled( bool enabled )

+ 12 - 1
Engine/source/T3D/player.cpp

@@ -252,6 +252,7 @@ PlayerData::PlayerData()
    shadowProjectionDistance = 14.0f;
 
    renderFirstPerson = true;
+   firstPersonShadows = false;
 
    // Used for third person image rendering
    imageAnimPrefix = StringTable->insert("");
@@ -679,6 +680,9 @@ void PlayerData::initPersistFields()
       addField( "renderFirstPerson", TypeBool, Offset(renderFirstPerson, PlayerData),
          "@brief Flag controlling whether to render the player shape in first person view.\n\n" );
 
+      addField( "firstPersonShadows", TypeBool, Offset(firstPersonShadows, PlayerData),
+         "@brief Forces shadows to be rendered in first person when renderFirstPerson is disabled.  Defaults to false.\n\n" );
+
       addField( "minLookAngle", TypeF32, Offset(minLookAngle, PlayerData),
          "@brief Lowest angle (in radians) the player can look.\n\n"
          "@note An angle of zero is straight ahead, with positive up and negative down." );
@@ -1180,7 +1184,8 @@ void PlayerData::packData(BitStream* stream)
    Parent::packData(stream);
 
    stream->writeFlag(renderFirstPerson);
-
+   stream->writeFlag(firstPersonShadows);
+   
    stream->write(minLookAngle);
    stream->write(maxLookAngle);
    stream->write(maxFreelookAngle);
@@ -1361,6 +1366,7 @@ void PlayerData::unpackData(BitStream* stream)
    Parent::unpackData(stream);
 
    renderFirstPerson = stream->readFlag();
+   firstPersonShadows = stream->readFlag();
 
    stream->read(&minLookAngle);
    stream->read(&maxLookAngle);
@@ -6947,6 +6953,11 @@ void Player::prepRenderImage( SceneRenderState* state )
    GameConnection* connection = GameConnection::getConnectionToServer();
    if( connection && connection->getControlObject() == this && connection->isFirstPerson() )
    {
+      // If we're first person and we are not rendering the player
+      // then disable all shadow rendering... a floating gun shadow sucks.
+      if ( state->isShadowPass() && !mDataBlock->renderFirstPerson && !mDataBlock->firstPersonShadows )
+         return;
+
       renderPlayer = mDataBlock->renderFirstPerson || !state->isDiffusePass();
 
       if( !sRenderMyPlayer )

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

@@ -54,6 +54,10 @@ struct PlayerData: public ShapeBaseData {
    };
    bool renderFirstPerson;    ///< Render the player shape in first person
 
+   /// Render shadows while in first person when 
+   /// renderFirstPerson is disabled.
+   bool firstPersonShadows; 
+
    StringTableEntry  imageAnimPrefix;                             ///< Passed along to mounted images to modify
                                                                   ///  animation sequences played in third person. [optional]
    bool              allowImageStateAnimation;                    ///< When true a new thread is added to the player to allow for

+ 12 - 0
Engine/source/T3D/shapeBase.cpp

@@ -1632,6 +1632,11 @@ F32 ShapeBase::getDamageValue()
    return mDamage / mDataBlock->maxDamage;
 }
 
+F32 ShapeBase::getMaxDamage()
+{
+   return mDataBlock->maxDamage;
+}
+
 void ShapeBase::updateDamageLevel()
 {
    if (mDamageThread) {
@@ -4534,6 +4539,13 @@ DefineEngineMethod( ShapeBase, getDamagePercent, F32, (),,
 {
    return object->getDamageValue();
 }
+  
+DefineEngineMethod(ShapeBase, getMaxDamage, F32, (),,   
+   "Get the object's maxDamage level.\n"  
+   "@return datablock.maxDamage\n")    
+{    
+   return object->getMaxDamage();    
+}  
 
 DefineEngineMethod( ShapeBase, setDamageState, bool, ( const char* state ),,
    "@brief Set the object's damage state.\n\n"

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

@@ -1265,6 +1265,9 @@ public:
    ///
    /// @return Damage factor, between 0.0 - 1.0
    F32  getDamageValue();
+ 
+   /// Returns the datablock.maxDamage value  
+   F32 getMaxDamage(); 
 
    /// Returns the rate at which the object regenerates damage
    F32  getRepairRate() { return mRepairRate; }

+ 2 - 0
Engine/source/T3D/tsStatic.cpp

@@ -827,6 +827,8 @@ bool TSStatic::buildPolyList(PolyListContext context, AbstractPolyList* polyList
          return false;
       else if ( meshType == Bounds )
          polyList->addBox( mObjBox );
+      else if ( meshType == VisibleMesh )
+          mShapeInstance->buildPolyList( polyList, 0 );
       else
       {
          // Everything else is done from the collision meshes

+ 20 - 4
Engine/source/T3D/turret/turretShape.cpp

@@ -824,7 +824,11 @@ void TurretShape::_updateNodes(const Point3F& rot)
    {
       MatrixF* mat = &mShapeInstance->mNodeTransforms[node];
       Point3F defaultPos = mShapeInstance->getShape()->defaultTranslations[node];
-      mat->set(zRot);
+      Quat16 defaultRot = mShapeInstance->getShape()->defaultRotations[node];
+
+      QuatF qrot(zRot);
+      qrot *= defaultRot.getQuatF();
+      qrot.setMatrix( mat );      
       mat->setColumn(3, defaultPos);
    }
 
@@ -834,7 +838,11 @@ void TurretShape::_updateNodes(const Point3F& rot)
    {
       MatrixF* mat = &mShapeInstance->mNodeTransforms[node];
       Point3F defaultPos = mShapeInstance->getShape()->defaultTranslations[node];
-      mat->set(xRot);
+      Quat16 defaultRot = mShapeInstance->getShape()->defaultRotations[node];
+
+      QuatF qrot(xRot);
+      qrot *= defaultRot.getQuatF();
+      qrot.setMatrix( mat );    
       mat->setColumn(3, defaultPos);
    }
 
@@ -846,7 +854,11 @@ void TurretShape::_updateNodes(const Point3F& rot)
       {
          MatrixF* mat = &mShapeInstance->mNodeTransforms[node];
          Point3F defaultPos = mShapeInstance->getShape()->defaultTranslations[node];
-         mat->set(xRot);
+         Quat16 defaultRot = mShapeInstance->getShape()->defaultRotations[node];         
+
+         QuatF qrot(xRot);
+         qrot *= defaultRot.getQuatF();
+         qrot.setMatrix( mat );    
          mat->setColumn(3, defaultPos);
       }
 
@@ -855,7 +867,11 @@ void TurretShape::_updateNodes(const Point3F& rot)
       {
          MatrixF* mat = &mShapeInstance->mNodeTransforms[node];
          Point3F defaultPos = mShapeInstance->getShape()->defaultTranslations[node];
-         mat->set(zRot);
+         Quat16 defaultRot = mShapeInstance->getShape()->defaultRotations[node];
+
+         QuatF qrot(zRot);
+         qrot *= defaultRot.getQuatF();
+         qrot.setMatrix( mat );      
          mat->setColumn(3, defaultPos);
       }
    }

+ 21 - 4
Engine/source/app/net/tcpObject.cpp

@@ -129,6 +129,7 @@ IMPLEMENT_CALLBACK(TCPObject, onConnectionRequest, void, (const char* address, c
    "This callback is used when the TCPObject is listening to a port and a client is attempting to connect.\n"
    "@param address Server address connecting from.\n"
    "@param ID Connection ID\n"
+   "@see listen()\n"
    );
 
 IMPLEMENT_CALLBACK(TCPObject, onLine, void, (const char* line), (line),
@@ -424,14 +425,30 @@ DefineEngineMethod(TCPObject, send, void, (const char *data),,
 DefineEngineMethod(TCPObject, listen, void, (int port),, 
    "@brief Start listening on the specified port for connections.\n\n"
 
+   "This method starts a listener which looks for incoming TCP connections to a port.  "
+   "You must overload the onConnectionRequest callback to create a new TCPObject to "
+   "read, write, or reject the new connection.\n\n"
+
    "@param port Port for this TCPObject to start listening for connections on.\n"
 
    "@tsexample\n"
-      "// Set the port number list\n"
-      "%portNumber = 80;\n\n"
 
-      "// Inform this TCPObject to start listening at the specified port.\n"
-      "%thisTCPObj.send(%portNumber);\n"
+    "// Create a listener on port 8080.\n"
+    "new TCPObject( TCPListener );\n"
+    "TCPListener.listen( 8080 );\n\n"
+
+    "function TCPListener::onConnectionRequest( %this, %address, %id )\n"
+    "{\n"
+    "   // Create a new object to manage the connection.\n"
+    "   new TCPObject( TCPClient, %id );\n"
+    "}\n\n"
+
+    "function TCPClient::onLine( %this, %line )\n"
+    "{\n"
+    "   // Print the line of text from client.\n"
+    "   echo( %line );\n"
+    "}\n"
+
    "@endtsexample\n")
 {
    object->listen(U32(port));

+ 5 - 0
Engine/source/collision/abstractPolyList.h

@@ -157,6 +157,11 @@ public:
    /// an ID number for that point.
    virtual U32  addPoint(const Point3F& p) = 0;
 
+   /// Adds a point and normal to the poly list, and returns
+   /// an ID number for them.  Normals are ignored for polylists
+   /// that do not support them.
+   virtual U32  addPointAndNormal(const Point3F& p, const Point3F& normal) { return addPoint( p ); }
+
    /// Adds a plane to the poly list, and returns
    /// an ID number for that point.
    virtual U32  addPlane(const PlaneF& plane) = 0;

+ 27 - 1
Engine/source/collision/clippedPolyList.cpp

@@ -74,6 +74,11 @@ bool ClippedPolyList::isEmpty() const
 //----------------------------------------------------------------------------
 
 U32 ClippedPolyList::addPoint(const Point3F& p)
+{
+    return addPointAndNormal( p, Point3F::Zero );
+}
+
+U32 ClippedPolyList::addPointAndNormal(const Point3F& p, const Point3F& normal)
 {
    mVertexList.increment();
    Vertex& v = mVertexList.last();
@@ -82,6 +87,14 @@ U32 ClippedPolyList::addPoint(const Point3F& p)
    v.point.z = p.z * mScale.z;
    mMatrix.mulP(v.point);
 
+    mNormalList.increment();
+    VectorF& n = mNormalList.last();
+    n = normal;
+    if ( !n.isZero() )
+        mMatrix.mulV(n);
+
+    AssertFatal(mNormalList.size() == mVertexList.size(), "Normals count does not match vertex count!");    
+
    // Build the plane mask
    register U32      mask = 1;
    register S32      count = mPlaneList.size();
@@ -242,6 +255,13 @@ void ClippedPolyList::end()
             VectorF vv = v2 - v1;
             F32 t = -mPlaneList[p].distToPlane(v1) / mDot(mPlaneList[p],vv);
 
+            mNormalList.increment();
+            VectorF& n1 = mNormalList[mIndexList[i1]];
+            VectorF& n2 = mNormalList[mIndexList[i1]];
+            VectorF nn = mLerp( n1, n2, t );
+            nn.normalizeSafe();
+            mNormalList.last() = nn;
+
             mIndexList.push_back/*_noresize*/(mVertexList.size() - 1);
             Vertex& iv = mVertexList.last();
             iv.point.x = v1.x + vv.x * t;
@@ -343,12 +363,14 @@ void ClippedPolyList::cullUnusedVerts()
       if ( !result )
       {
          mVertexList.setSize( i );
+         mNormalList.setSize( i );
          break;
       }
 
       // Erase unused verts.
       numDeleted = (k-1) - i + 1;       
       mVertexList.erase( i, numDeleted );
+      mNormalList.erase( i, numDeleted );
 
       // Find any references to vertices after those deleted
       // in the mIndexList and correct with an offset
@@ -407,7 +429,7 @@ void ClippedPolyList::generateNormals()
 {
    PROFILE_SCOPE( ClippedPolyList_GenerateNormals );
 
-   mNormalList.setSize( mVertexList.size() );
+   AssertFatal(mNormalList.size() == mVertexList.size(), "Normals count does not match vertex count!");    
 
    U32 i, polyCount;
    VectorF normal;
@@ -418,6 +440,10 @@ void ClippedPolyList::generateNormals()
    U32 n = 0;
    for ( ; normalIter != mNormalList.end(); normalIter++, n++ )
    {
+       // Skip normals that already have values.
+       if ( !normalIter->isZero() )
+           continue;
+
       // Average all the face normals which 
       // share this vertex index.
       indexIter = mIndexList.begin();

+ 1 - 0
Engine/source/collision/clippedPolyList.h

@@ -119,6 +119,7 @@ public:
    // AbstractPolyList
    bool isEmpty() const;
    U32 addPoint(const Point3F& p);
+   U32 addPointAndNormal(const Point3F& p, const Point3F& normal);
    U32 addPlane(const PlaneF& plane);
    void begin(BaseMatInstance* material,U32 surfaceKey);
    void plane(U32 v1,U32 v2,U32 v3);

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

@@ -55,7 +55,7 @@ ConsoleDocClass( ArrayObject,
 );
 
 
-bool ArrayObject::smIncreasing = false;
+bool ArrayObject::smDecreasing = false;
 bool ArrayObject::smCaseSensitive = false;
 const char* ArrayObject::smCompareFunction;
 
@@ -65,7 +65,7 @@ S32 QSORT_CALLBACK ArrayObject::_valueCompare( const void* a, const void* b )
    ArrayObject::Element *ea = (ArrayObject::Element *) (a);
    ArrayObject::Element *eb = (ArrayObject::Element *) (b);
    S32 result = smCaseSensitive ? dStrnatcmp(ea->value, eb->value) : dStrnatcasecmp(ea->value, eb->value);
-   return ( smIncreasing ? -result : result );
+   return ( smDecreasing ? -result : result );
 }
 
 S32 QSORT_CALLBACK ArrayObject::_valueNumCompare( const void* a, const void* b )
@@ -76,7 +76,7 @@ S32 QSORT_CALLBACK ArrayObject::_valueNumCompare( const void* a, const void* b )
    F32 bCol = dAtof(eb->value);
    F32 result = aCol - bCol;
    S32 res = result < 0 ? -1 : (result > 0 ? 1 : 0);
-   return ( smIncreasing ? res : -res );
+   return ( smDecreasing ? res : -res );
 }
 
 S32 QSORT_CALLBACK ArrayObject::_keyCompare( const void* a, const void* b )
@@ -84,7 +84,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyCompare( const void* a, const void* b )
    ArrayObject::Element *ea = (ArrayObject::Element *) (a);
    ArrayObject::Element *eb = (ArrayObject::Element *) (b);
    S32 result = smCaseSensitive ? dStrnatcmp(ea->key, eb->key) : dStrnatcasecmp(ea->key, eb->key);
-   return ( smIncreasing ? -result : result );
+   return ( smDecreasing ? -result : result );
 }
 
 S32 QSORT_CALLBACK ArrayObject::_keyNumCompare( const void* a, const void* b )
@@ -95,7 +95,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyNumCompare( const void* a, const void* b )
    const char* bCol = eb->key;
    F32 result = dAtof(aCol) - dAtof(bCol);
    S32 res = result < 0 ? -1 : (result > 0 ? 1 : 0);
-   return ( smIncreasing ? res : -res );
+   return ( smDecreasing ? res : -res );
 }
 
 S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void* b )
@@ -110,7 +110,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void*
    
    S32 result = dAtoi( Con::execute( 3, argv ) );
    S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
-   return ( smIncreasing ? res : -res );
+   return ( smDecreasing ? res : -res );
 }
 
 S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void* b )
@@ -125,7 +125,7 @@ S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void
    
    S32 result = dAtoi( Con::execute( 3, argv ) );
    S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
-   return ( smIncreasing ? res : -res );
+   return ( smDecreasing ? res : -res );
 }
 
 
@@ -472,12 +472,12 @@ void ArrayObject::setValue( const String &value, S32 index )
 
 //-----------------------------------------------------------------------------
 
-void ArrayObject::sort( bool valsort, bool desc, bool numeric )
+void ArrayObject::sort( bool valsort, bool asc, bool numeric )
 {
    if ( mArray.size() <= 1 )
       return;
 
-   smIncreasing = desc ? false : true;
+   smDecreasing = asc ? false : true;
    smCaseSensitive = isCaseSensitive();
 
    if ( numeric )
@@ -498,12 +498,12 @@ void ArrayObject::sort( bool valsort, bool desc, bool numeric )
 
 //-----------------------------------------------------------------------------
 
-void ArrayObject::sort( bool valsort, bool desc, const char* callbackFunctionName )
+void ArrayObject::sort( bool valsort, bool asc, const char* callbackFunctionName )
 {
    if( mArray.size() <= 1 )
       return;
 
-   smIncreasing = desc ? false : true;
+   smDecreasing = asc ? false : true;
    smCompareFunction = callbackFunctionName;
 
    if( valsort )
@@ -767,80 +767,80 @@ DefineEngineMethod( ArrayObject, append, bool, ( ArrayObject* target ),,
    return false;
 }
 
-DefineEngineMethod( ArrayObject, sort, void, ( bool descending ), ( false ),
+DefineEngineMethod( ArrayObject, sort, void, ( bool ascending ), ( false ),
    "Alpha sorts the array by value\n\n"
-   "@param descending [optional] True for descending sort, false for ascending sort\n" )
+   "@param ascending [optional] True for ascending sort, false for descending sort\n" )
 {
-   object->sort( true, descending, false );
+   object->sort( true, ascending, false );
 }
 
 DefineEngineMethod( ArrayObject, sorta, void, (),,
    "Alpha sorts the array by value in ascending order" )
 {
-   object->sort( true, false, false );
+   object->sort( true, true, false );
 }
 
 DefineEngineMethod( ArrayObject, sortd, void, (),,
    "Alpha sorts the array by value in descending order" )
 {
-   object->sort( true, true, false );
+   object->sort( true, false, false );
 }
 
-DefineEngineMethod( ArrayObject, sortk, void, ( bool descending ), ( false ),
+DefineEngineMethod( ArrayObject, sortk, void, ( bool ascending ), ( false ),
    "Alpha sorts the array by key\n\n"
-   "@param descending [optional] True for descending sort, false for ascending sort\n" )
+   "@param ascending [optional] True for ascending sort, false for descending sort\n" )
 {
-   object->sort( false, descending, false );
+   object->sort( false, ascending, false );
 }
 
 DefineEngineMethod( ArrayObject, sortka, void, (),,
    "Alpha sorts the array by key in ascending order" )
 {
-   object->sort( false, false, false );
+   object->sort( false, true, false );
 }
 
 DefineEngineMethod( ArrayObject, sortkd, void, (),,
    "Alpha sorts the array by key in descending order" )
 {
-   object->sort( false, true, false );
+   object->sort( false, false, false );
 }
 
-DefineEngineMethod( ArrayObject, sortn, void, ( bool descending ), ( false ),
+DefineEngineMethod( ArrayObject, sortn, void, ( bool ascending ), ( false ),
    "Numerically sorts the array by value\n\n"
-   "@param descending [optional] True for descending sort, false for ascending sort\n" )
+   "@param ascending [optional] True for ascending sort, false for descending sort\n" )
 {
-   object->sort( true, descending, true );
+   object->sort( true, ascending, true );
 }
 
 DefineEngineMethod( ArrayObject, sortna, void, (),,
    "Numerically sorts the array by value in ascending order" ) 
 {
-   object->sort( true, false, true );
+   object->sort( true, true, true );
 }
 
 DefineEngineMethod( ArrayObject, sortnd, void, (),,
    "Numerically sorts the array by value in descending order" )
 {
-   object->sort( true, true, true );
+   object->sort( true, false, true );
 }
 
-DefineEngineMethod( ArrayObject, sortnk, void, ( bool descending ), ( false ),
+DefineEngineMethod( ArrayObject, sortnk, void, ( bool ascending ), ( false ),
    "Numerically sorts the array by key\n\n"
-   "@param descending [optional] True for descending sort, false for ascending sort\n" )
+   "@param ascending [optional] True for ascending sort, false for descending sort\n" )
 {
-   object->sort( false, descending, true );
+   object->sort( false, ascending, true );
 }
 
 DefineEngineMethod( ArrayObject, sortnka, void, (),,
    "Numerical sorts the array by key in ascending order" )
 {
-   object->sort( false, false, true );
+   object->sort( false, true, true );
 }
 
 DefineEngineMethod( ArrayObject, sortnkd, void, (),,
    "Numerical sorts the array by key in descending order" )
 {
-   object->sort( false, true, true );
+   object->sort( false, false, true );
 }
 
 DefineEngineMethod( ArrayObject, sortf, void,  ( const char* functionName ),,
@@ -854,7 +854,7 @@ DefineEngineMethod( ArrayObject, sortf, void,  ( const char* functionName ),,
    "%array.sortf( \"mySortCallback\" );\n"
    "@endtsexample\n" )
 {
-   object->sort( true, false, functionName );
+   object->sort( true, true, functionName );
 }
 
 DefineEngineMethod( ArrayObject, sortfk, void,  ( const char* functionName ),,
@@ -862,7 +862,7 @@ DefineEngineMethod( ArrayObject, sortfk, void,  ( const char* functionName ),,
    "@param functionName Name of a function that takes two arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal."
    "@see sortf\n" )
 {
-   object->sort( false, false, functionName );
+   object->sort( false, true, functionName );
 }
 
 DefineEngineMethod( ArrayObject, sortfd, void, ( const char* functionName ),,
@@ -870,7 +870,7 @@ DefineEngineMethod( ArrayObject, sortfd, void, ( const char* functionName ),,
    "@param functionName Name of a function that takes two arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal."
    "@see sortf\n" )
 {
-   object->sort( true, true, functionName );
+   object->sort( true, false, functionName );
 }
 
 DefineEngineMethod( ArrayObject, sortfkd, void, ( const char* functionName ),,
@@ -878,7 +878,7 @@ DefineEngineMethod( ArrayObject, sortfkd, void, ( const char* functionName ),,
    "@param functionName Name of a function that takes two arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal."
    "@see sortf\n" )
 {
-   object->sort( false, true, functionName );
+   object->sort( false, false, functionName );
 }
 
 DefineEngineMethod( ArrayObject, moveFirst, S32, (),,

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

@@ -57,7 +57,7 @@ protected:
    /// @name Sorting
    /// @{
 
-   static bool smIncreasing;
+   static bool smDecreasing;
    static bool smCaseSensitive;
    static const char* smCompareFunction;
 
@@ -175,15 +175,15 @@ public:
 
    /// This sorts the array.
    /// @param valtest  Determines whether sorting by value or key.
-   /// @param desc     Determines if sorting ascending or descending.
+   /// @param asc      Determines if sorting ascending or descending.
    /// @param numeric  Determines if sorting alpha or numeric search.
-   void sort( bool valtest, bool desc, bool numeric );
+   void sort( bool valtest, bool asc, bool numeric );
    
    /// This sorts the array using a script callback.
    /// @param valtest  Determines whether sorting by value or key.
-   /// @param desc     Determines if sorting ascending or descending.
+   /// @param asc      Determines if sorting ascending or descending.
    /// @param callbackFunctionName Name of the script function.
-   void sort( bool valtest, bool desc, const char* callbackFunctionName );
+   void sort( bool valtest, bool asc, const char* callbackFunctionName );
 
    /// @}
 

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

@@ -252,7 +252,7 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
    extern S32 type; \
    extern const char* castConsoleTypeToString( _ConsoleConstType< nativeType >::ConstType &arg ); \
    extern bool castConsoleTypeFromString( nativeType &arg, const char *str ); \
-   template<> extern S32 TYPEID< nativeType >();
+   template<> S32 TYPEID< nativeType >();
    
 #define DefineUnmappedConsoleType( type, nativeType ) \
    DefineConsoleType( type, nativeType ) \

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

@@ -416,7 +416,7 @@ namespace _Private {
 
 
 #define _DECLARE_TYPE( type )                                                                \
-   template<> extern const EngineTypeInfo* TYPE< type >();                                   \
+   template<> const EngineTypeInfo* TYPE< type >();                                          \
    template<> struct _SCOPE< type > {                                                        \
       EngineExportScope& operator()() const {                                                \
          return *reinterpret_cast< EngineExportScope* >(                                     \

+ 17 - 0
Engine/source/core/bitVector.h

@@ -56,6 +56,9 @@ class BitVector
       /// Constructs a bit vector with the desired size.
       /// @note The resulting vector is not cleared.
       BitVector( U32 sizeInBits );
+
+      /// Copy constructor
+      BitVector( const BitVector &r);
       
       /// Destructor.
       ~BitVector();
@@ -86,6 +89,9 @@ class BitVector
       /// Copy the content of another bit vector.
       void copy( const BitVector &from );
 
+      /// Copy the contents of another bit vector
+      BitVector& operator=( const BitVector &r);
+
       /// @name Mutators
       /// Note that bits are specified by index, unlike BitSet32.
       /// @{
@@ -150,6 +156,11 @@ inline BitVector::BitVector( U32 sizeInBits )
    setSize( sizeInBits );
 }
 
+inline BitVector::BitVector( const BitVector &r )
+{
+   copy(r);
+}
+
 inline BitVector::~BitVector()
 {
    delete [] mBits;
@@ -182,6 +193,12 @@ inline void BitVector::copy( const BitVector &from )
       dMemcpy( mBits, from.getBits(), getByteSize() );
 }
 
+inline BitVector& BitVector::operator=( const BitVector &r)
+{
+   copy(r);
+   return *this;
+}
+
 inline void BitVector::set()
 {
    if (mSize != 0)

+ 5 - 5
Engine/source/core/dnet.cpp

@@ -79,11 +79,11 @@ void ConnectionProtocol::buildSendPacketHeader(BitStream *stream, S32 packetType
 
    stream->writeFlag(true);
    stream->writeInt(mConnectSequence & 1, 1);
-   stream->writeInt(mLastSendSeq, 9);
-   stream->writeInt(mLastSeqRecvd, 9);
-   stream->writeInt(packetType, 2);
-   stream->writeInt(ackByteCount, 3);
-   stream->writeInt(mAckMask, ackByteCount * 8);
+   stream->writeInt(mLastSendSeq & 0x1FF, 9);
+   stream->writeInt(mLastSeqRecvd & 0x1FF, 9);
+   stream->writeInt(packetType & 0x3, 2);
+   stream->writeInt(ackByteCount & 0x7, 3);
+   stream->writeInt(mAckMask & (~(0xFFFFFFFF << ackByteCount*8)), ackByteCount * 8);
 
    // if we're resending this header, we can't advance the
    // sequence recieved (in case this packet drops and the prev one

+ 2 - 0
Engine/source/core/stream/bitStream.cpp

@@ -336,6 +336,8 @@ S32 BitStream::readInt(S32 bitCount)
 
 void BitStream::writeInt(S32 val, S32 bitCount)
 {
+   AssertWarn((bitCount == 32) || ((val >> bitCount) == 0), "BitStream::writeInt: value out of range");
+
    val = convertHostToLEndian(val);
    writeBits(bitCount, &val);
 }

+ 5 - 2
Engine/source/environment/editors/guiRiverEditorCtrl.cpp

@@ -225,13 +225,16 @@ void GuiRiverEditorCtrl::get3DCursor( GuiCursor *&cursor,
 
 void GuiRiverEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
 {
-   
+   _process3DMouseDown( event );
 
    mGizmo->on3DMouseDown( event );
 
    if ( !isFirstResponder() )
       setFirstResponder();
-	
+}
+
+void GuiRiverEditorCtrl::_process3DMouseDown( const Gui3DMouseEvent& event )
+{
 	// Get the raycast collision position
    Point3F tPos;
    if ( !getStaticPos( event, tPos ) )

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

@@ -121,6 +121,7 @@ class GuiRiverEditorCtrl : public EditTSCtrl
       void _prepRenderImage( SceneManager* sceneGraph, const SceneRenderState* sceneState );
       void _drawRiverSpline( River *river, const ColorI &color );
       void _drawRiverControlNodes( River *river, const ColorI &color );
+      void _process3DMouseDown( const Gui3DMouseEvent& event );
 
       void submitUndo( const UTF8 *name = "Action" );
 

+ 10 - 4
Engine/source/gfx/gfxFontRenderBatcher.cpp

@@ -215,12 +215,18 @@ void FontRenderBatcher::queueChar( UTF16 c, S32 &currentX, GFXVertexColor &curre
 
 FontRenderBatcher::SheetMarker & FontRenderBatcher::getSheetMarker( U32 sheetID )
 {
-   // Allocate if it doesn't exist...
-   if(mSheets.size() <= sheetID || !mSheets[sheetID])
+   // Add empty sheets up to and including the requested sheet if necessary
+   if (mSheets.size() <= sheetID)
    {
-      if(sheetID >= mSheets.size())
-         mSheets.setSize(sheetID+1);
+      S32 oldSize = mSheets.size();
+      mSheets.setSize( sheetID + 1 );
+      for ( S32 i = oldSize; i < mSheets.size(); i++ )
+         mSheets[i] = NULL;
+   }
 
+   // Allocate if it doesn't exist...
+   if (!mSheets[sheetID])
+   {
       S32 size = sizeof( SheetMarker) + mLength * sizeof( CharMarker );
       mSheets[sheetID] = (SheetMarker *)mStorage.alloc(size);
       mSheets[sheetID]->numChars = 0;

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

@@ -496,7 +496,9 @@ void GuiTabBookCtrl::onRender(Point2I offset, const RectI &updateRect)
 
    // Clip to tab area
    RectI savedClipRect = GFX->getClipRect();
-   GFX->setClipRect( tabRect );
+   RectI clippedTabRect = tabRect;
+   clippedTabRect.intersect( savedClipRect );
+   GFX->setClipRect( clippedTabRect );
 
    // Render our tabs
    renderTabs( offset, tabRect );

+ 11 - 3
Engine/source/gui/controls/guiTreeViewCtrl.cpp

@@ -33,7 +33,9 @@
 #include "platform/event.h"
 #include "gfx/gfxDrawUtil.h"
 #include "gui/controls/guiTextEditCtrl.h"
-#include "gui/editor/editorFunctions.h"
+#ifdef TORQUE_TOOLS
+   #include "gui/editor/editorFunctions.h"
+#endif
 #include "console/engineAPI.h"
 
 
@@ -4042,7 +4044,10 @@ void GuiTreeViewCtrl::onRenderCell(Point2I offset, Point2I cell, bool, bool )
       // If this item is a VirtualParent we can use the generic SimGroup123 icons.
       // However if there is already an icon in the EditorIconRegistry for this
       // exact class (not counting parent class icons) we want to use that instead.
-      bool hasClassIcon = gEditorIcons.hasIconNoRecurse( pObject );
+      bool hasClassIcon = false;
+#ifdef TORQUE_TOOLS
+      hasClassIcon = gEditorIcons.hasIconNoRecurse( pObject );
+#endif
 
       // draw the icon associated with the item
       if ( !hasClassIcon && item->mState.test(Item::VirtualParent))
@@ -5280,7 +5285,10 @@ void GuiTreeViewCtrl::onRenameValidate()
 
    if ( mRenameInternal )
       obj->setInternalName( data );   
-   else if ( validateObjectName( data, obj ) )
+   else
+#ifdef TORQUE_TOOLS
+   if ( validateObjectName( data, obj ) )
+#endif
       obj->assignName( data ); 
 }
 

+ 2 - 1
Engine/source/gui/core/guiArrayCtrl.cpp

@@ -284,7 +284,8 @@ void GuiArrayCtrl::onRender(Point2I offset, const RectI &updateRect)
          //now render the header
          onRenderColumnHeaders(offset, parentOffset, mHeaderDim);
 
-         clipRect.point.y = headerClip.point.y + headerClip.extent.y - 1;
+         clipRect.point.y += headerClip.extent.y;
+         clipRect.extent.y -= headerClip.extent.y;
       }
       offset.y += mHeaderDim.y;
    }

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

@@ -871,10 +871,17 @@ void GuiConvexEditorCtrl::renderScene(const RectI & updateRect)
             text = "Scale face.";
          }
       }
+   
+      // Issue a warning in the status bar
+      // if this convex has an excessive number of surfaces...
+      if ( mConvexSEL && mConvexSEL->getSurfaces().size() > ConvexShape::smMaxSurfaces )
+      {
+          text = "WARNING: Reduce the number of surfaces on the selected ConvexShape, only the first 100 will be saved!";
+      }
 
       Con::executef( statusbar, "setInfo", text.c_str() );
 
-		Con::executef( statusbar, "setSelectionObjectsByCount", Con::getIntArg( mConvexSEL == NULL ? 0 : 1 ) );
+	Con::executef( statusbar, "setSelectionObjectsByCount", Con::getIntArg( mConvexSEL == NULL ? 0 : 1 ) );
    }   
 
    if ( mActiveTool )

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

@@ -394,7 +394,19 @@ void GuiDecalEditorCtrl::on3DMouseDragged(const Gui3DMouseEvent & event)
 
       // Assign the appropriate changed value back to the decal.
       if ( mGizmo->getMode() == ScaleMode )
-         mSELDecal->mSize = (scale.x + scale.y) * 0.5f;
+      {
+         // Save old size.
+         const F32 oldSize = mSELDecal->mSize;
+
+         // Set new size.
+         mSELDecal->mSize = ( scale.x + scale.y ) * 0.5f;
+
+         // See if the decal properly clips/projects at this size.  If not,
+         // stick to the old size.
+         mSELEdgeVerts.clear();
+         if ( !gDecalManager->clipDecal( mSELDecal, &mSELEdgeVerts ) )
+            mSELDecal->mSize = oldSize;
+      }
       else if ( mGizmo->getMode() == MoveMode )
          mSELDecal->mPosition = gizmoPos;
       else if ( mGizmo->getMode() == RotateMode )

+ 3 - 0
Engine/source/gui/worldEditor/worldEditor.cpp

@@ -2911,6 +2911,9 @@ void WorldEditor::dropCurrentSelection( bool skipUndo )
       submitUndo( mSelected );
 
 	dropSelection( mSelected );	
+
+   if ( mSelected->hasCentroidChanged() )
+      Con::executef( this, "onSelectionCentroidChanged" );
 }
 
 void WorldEditor::redirectConsole( S32 objID )

+ 3 - 3
Engine/source/lighting/advanced/advancedLightingFeatures.cpp

@@ -31,7 +31,7 @@
 #include "gfx/gfxDevice.h"
 #include "core/util/safeDelete.h"
 
-#ifndef TORQUE_OS_MAC
+#if !defined( TORQUE_OS_MAC ) && !defined( TORQUE_OS_LINUX )
 #  include "lighting/advanced/hlsl/gBufferConditionerHLSL.h"
 #  include "lighting/advanced/hlsl/advancedLightingFeaturesHLSL.h"
 #else
@@ -54,7 +54,7 @@ void AdvancedLightingFeatures::registerFeatures( const GFXFormat &prepassTargetF
 
    if(GFX->getAdapterType() == OpenGL)
    {
-#ifdef TORQUE_OS_MAC
+#if defined( TORQUE_OS_MAC ) || defined( TORQUE_OS_LINUX )
       cond = new GBufferConditionerGLSL( prepassTargetFormat );
       FEATUREMGR->registerFeature(MFT_PrePassConditioner, cond);
       FEATUREMGR->registerFeature(MFT_RTLighting, new DeferredRTLightingFeatGLSL());
@@ -66,7 +66,7 @@ void AdvancedLightingFeatures::registerFeatures( const GFXFormat &prepassTargetF
    }
    else
    {
-#ifndef TORQUE_OS_MAC
+#if !defined( TORQUE_OS_MAC ) && !defined( TORQUE_OS_LINUX )
       cond = new GBufferConditionerHLSL( prepassTargetFormat, GBufferConditionerHLSL::ViewSpace );
       FEATUREMGR->registerFeature(MFT_PrePassConditioner, cond);
       FEATUREMGR->registerFeature(MFT_RTLighting, new DeferredRTLightingFeatHLSL());

+ 3 - 3
Engine/source/lighting/basic/basicLightManager.cpp

@@ -49,7 +49,7 @@
 #include "lighting/common/projectedShadow.h"
 
 
-#ifdef TORQUE_OS_MAC
+#if defined( TORQUE_OS_MAC ) || defined( TORQUE_OS_LINUX )
 #include "shaderGen/GLSL/shaderFeatureGLSL.h"
 #include "shaderGen/GLSL/bumpGLSL.h"
 #include "shaderGen/GLSL/pixSpecularGLSL.h"
@@ -167,7 +167,7 @@ void BasicLightManager::activate( SceneManager *sceneManager )
 
    if( GFX->getAdapterType() == OpenGL )
    {
-      #ifdef TORQUE_OS_MAC
+      #if defined( TORQUE_OS_MAC ) || defined( TORQUE_OS_LINUX )
          FEATUREMGR->registerFeature( MFT_LightMap, new LightmapFeatGLSL );
          FEATUREMGR->registerFeature( MFT_ToneMap, new TonemapFeatGLSL );
          FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatGLSL );
@@ -177,7 +177,7 @@ void BasicLightManager::activate( SceneManager *sceneManager )
    }
    else
    {
-      #ifndef TORQUE_OS_MAC
+      #if !defined( TORQUE_OS_MAC ) && !defined( TORQUE_OS_LINUX )
          FEATUREMGR->registerFeature( MFT_LightMap, new LightmapFeatHLSL );
          FEATUREMGR->registerFeature( MFT_ToneMap, new TonemapFeatHLSL );
          FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatHLSL );

+ 10 - 1
Engine/source/lighting/common/lightMapParams.cpp

@@ -22,8 +22,17 @@
 
 #include "lighting/common/lightMapParams.h"
 #include "core/stream/bitStream.h"
+#include "core/module.h"
 
-const LightInfoExType LightMapParams::Type( "LightMapParams" );
+MODULE_BEGIN( LightMapParams )
+MODULE_INIT_AFTER( ShadowMapParams )
+MODULE_INIT
+{
+   LightMapParams::Type = "LightMapParams";
+}
+MODULE_END;
+
+LightInfoExType LightMapParams::Type( "" );
 
 LightMapParams::LightMapParams( LightInfo *light ) :
    representedInLightmap(false), 

+ 1 - 1
Engine/source/lighting/common/lightMapParams.h

@@ -34,7 +34,7 @@ public:
    virtual ~LightMapParams();
 
    /// The LightInfoEx hook type.
-   static const LightInfoExType Type;
+   static LightInfoExType Type;
 
    // LightInfoEx
    virtual void set( const LightInfoEx *ex );

+ 3 - 3
Engine/source/lighting/lightManager.cpp

@@ -314,7 +314,7 @@ void LightManager::_update4LightConsts(   const SceneData &sgData,
 
       // NOTE: We haven't ported the lighting shaders on OSX
       // to the optimized HLSL versions.
-      #ifdef TORQUE_OS_MAC
+      #if defined( TORQUE_OS_MAC ) || defined( TORQUE_OS_LINUX )
          static AlignedArray<Point3F> lightPositions( 4, sizeof( Point4F ) );
       #else
          static AlignedArray<Point4F> lightPositions( 3, sizeof( Point4F ) );
@@ -342,7 +342,7 @@ void LightManager::_update4LightConsts(   const SceneData &sgData,
          if ( !light )            
             break;
 
-         #ifdef TORQUE_OS_MAC
+         #if defined( TORQUE_OS_MAC ) || defined( TORQUE_OS_LINUX )
 
             lightPositions[i] = light->getPosition();
 
@@ -381,7 +381,7 @@ void LightManager::_update4LightConsts(   const SceneData &sgData,
       shaderConsts->setSafe( lightDiffuseSC, lightColors );
       shaderConsts->setSafe( lightInvRadiusSqSC, lightInvRadiusSq );
 
-      #ifndef TORQUE_OS_MAC
+      #if !defined( TORQUE_OS_MAC ) && !defined( TORQUE_OS_LINUX )
 
          shaderConsts->setSafe( lightSpotDirSC, lightSpotDirs );
          shaderConsts->setSafe( lightSpotAngleSC, lightSpotAngle );

+ 10 - 2
Engine/source/lighting/shadowMap/lightShadowMap.cpp

@@ -34,7 +34,7 @@
 #include "materials/baseMatInstance.h"
 #include "scene/sceneManager.h"
 #include "scene/sceneRenderState.h"
-#include "scene/zones/SceneZoneSpace.h"
+#include "scene/zones/sceneZoneSpace.h"
 #include "lighting/lightManager.h"
 #include "math/mathUtils.h"
 #include "shaderGen/shaderGenVars.h"
@@ -42,6 +42,7 @@
 #include "core/stream/bitStream.h"
 #include "math/mathIO.h"
 #include "materials/shaderData.h"
+#include "core/module.h"
 
 // Used for creation in ShadowMapParams::getOrCreateShadowMap()
 #include "lighting/shadowMap/singleLightShadowMap.h"
@@ -545,8 +546,15 @@ void LightingShaderConstants::_onShaderReload()
       init( mShader );
 }
 
+MODULE_BEGIN( ShadowMapParams )
+MODULE_INIT_BEFORE( LightMapParams )
+MODULE_INIT
+{
+   ShadowMapParams::Type = "ShadowMapParams" ;
+}
+MODULE_END;
 
-const LightInfoExType ShadowMapParams::Type( "ShadowMapParams" );
+LightInfoExType ShadowMapParams::Type( "" );
 
 ShadowMapParams::ShadowMapParams( LightInfo *light ) 
    :  mLight( light ),

+ 1 - 1
Engine/source/lighting/shadowMap/lightShadowMap.h

@@ -287,7 +287,7 @@ public:
    virtual ~ShadowMapParams();
 
    /// The LightInfoEx hook type.
-   static const LightInfoExType Type;
+   static LightInfoExType Type;
 
    // LightInfoEx
    virtual void set( const LightInfoEx *ex );

+ 8 - 1
Engine/source/materials/processedCustomMaterial.cpp

@@ -39,6 +39,7 @@
 #include "console/simFieldDictionary.h"
 #include "console/propertyParsing.h"
 #include "gfx/util/screenspace.h"
+#include "scene/reflectionManager.h"
 
 
 ProcessedCustomMaterial::ProcessedCustomMaterial(Material &mat)
@@ -346,7 +347,13 @@ void ProcessedCustomMaterial::setTextureStages( SceneRenderState *state, const S
             }
          case Material::BackBuff:
             {
-               GFX->setTexture( samplerRegister, sgData.backBuffTex );
+               if ( sgData.reflectTex )
+                  GFX->setTexture( samplerRegister, sgData.reflectTex );
+               else
+               {
+                   GFXTextureObject *refractTex = REFLECTMGR->getRefractTex( true );
+                   GFX->setTexture( samplerRegister, refractTex );
+               }
                break;
             }
          case Material::ReflectBuff:

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

@@ -52,7 +52,7 @@ void OrientedBox3F::set( const MatrixF& transform, const Point3F& extents )
    mAxes[ ForwardVector ] = transform.getForwardVector();
    mAxes[ UpVector ] = transform.getUpVector();
 
-   mHalfExtents = extents;
+   mHalfExtents = extents * 0.5f;
 
    _initPoints();
 }

+ 2 - 2
Engine/source/math/mSilhouetteExtractor.h

@@ -92,14 +92,14 @@ struct SilhouetteExtractorBasePerspective : public SilhouetteExtractorBase< Poly
 
          // Determine orientation of each of the polygons.
 
-         const U32 numPolygons = mPolyhedron->getNumPlanes();
+         const U32 numPolygons = this->mPolyhedron->getNumPlanes();
          mPolygonOrientations = ( Orientation* ) FrameAllocator::alloc( sizeof( Orientation ) * numPolygons );
 
          Point3F camPos = camView.getPosition();
 
          for( U32 i = 0; i < numPolygons; ++ i )
          {
-            if (mPolyhedron->getPlanes()[i].whichSide( camPos ) == PlaneF::Front)
+            if (this->mPolyhedron->getPlanes()[i].whichSide( camPos ) == PlaneF::Front)
                mPolygonOrientations[i] = FrontFacing;
             else
                mPolygonOrientations[i] = BackFacing;

+ 5 - 5
Engine/source/platform/platform.h

@@ -523,17 +523,17 @@ template<class T,class S> void dCopyArray(T *dst, const S *src, dsize_t size)
       dst[i] = (T)src[i];
 }
 
+extern void* dMemcpy(void *dst, const void *src, dsize_t size);
+extern void* dMemmove(void *dst, const void *src, dsize_t size);
+extern void* dMemset(void *dst, int c, dsize_t size);
+extern int   dMemcmp(const void *ptr1, const void *ptr2, dsize_t size);
+
 // Special case of the above function when the arrays are the same type (use memcpy)
 template<class T> void dCopyArray(T *dst, const T *src, dsize_t size)
 {
    dMemcpy(dst, src, size * sizeof(T));
 }
 
-extern void* dMemcpy(void *dst, const void *src, dsize_t size);
-extern void* dMemmove(void *dst, const void *src, dsize_t size);
-extern void* dMemset(void *dst, int c, dsize_t size);
-extern int   dMemcmp(const void *ptr1, const void *ptr2, dsize_t size);
-
 /// The dALIGN macro ensures the passed declaration is
 /// data aligned at 16 byte boundaries.
 #if defined( TORQUE_COMPILER_VISUALC )

+ 3 - 3
Engine/source/platform/platformCPUCount.cpp

@@ -522,9 +522,9 @@ next:
                // processors per core
 
                tblSMTID[j]  = GetNzbSubID(apicID, MaxLPPerCore, 0);
-               tblCoreID[j] = GetNzbSubID(apicID, 
-                  MaxCorePerPhysicalProc(),
-                  (unsigned char) find_maskwidth(MaxLPPerCore));
+               unsigned char maxCorePPP = MaxCorePerPhysicalProc();
+               unsigned char maskWidth = find_maskwidth(MaxLPPerCore);
+               tblCoreID[j] = GetNzbSubID(apicID, maxCorePPP, maskWidth);
 
                // Extract package ID, assume single cluster.
                // Shift value is the mask width for max Logical per package

+ 2 - 0
Engine/source/platform/types.visualc.h

@@ -88,7 +88,9 @@ typedef unsigned _int64 U64;
 #  define FN_CDECL __cdecl            ///< Calling convention
 #endif
 
+#if _MSC_VER < 1700
 #define for if(false) {} else for   ///< Hack to work around Microsoft VC's non-C++ compliance on variable scoping
+#endif
 
 // disable warning caused by memory layer
 // see msdn.microsoft.com "Compiler Warning (level 1) C4291" for more details

+ 2 - 0
Engine/source/platform/typesWin32.h

@@ -116,8 +116,10 @@ static const F32 F32_MAX = F32(3.402823466e+38F);                 ///< Constant
 
 
 #ifdef _MSC_VER
+#if _MSC_VER < 1700
 #define for if(false) {} else for   ///< Hack to work around Microsoft VC's non-C++ compliance on variable scoping
 #endif
+#endif
 
 
 #endif //_NTYPES_H_

+ 16 - 4
Engine/source/platformX86UNIX/threads/semaphore.cpp

@@ -55,13 +55,25 @@ Semaphore::~Semaphore()
   delete mData;
 }
 
-bool Semaphore::acquire(bool block)
+bool Semaphore::acquire(bool block, S32 timeoutMS)
 {
-   AssertFatal(mData, "Semaphore::acquire - Invalid semaphore.");
+   AssertFatal(mData && mData->semaphore, "Semaphore::acquire - Invalid semaphore.");
    if (block)
    {
-      if (SDL_SemWait(mData->semaphore) < 0)
-         AssertFatal(false, "Semaphore::acquie - Wait failed.");
+      // Semaphore acquiring is different from the MacOS/Win realization because SDL_SemWaitTimeout() with "infinite" timeout can be too heavy on some platforms.
+      // (see "man SDL_SemWaitTimeout(3)" for more info)
+      // "man" states to avoid the use of SDL_SemWaitTimeout at all, but at current stage this looks like a valid and working solution, so keeping it this way.
+      // [bank / Feb-2010]
+      if (timeoutMS == -1)
+      {
+         if (SDL_SemWait(mData->semaphore) < 0)
+            AssertFatal(false, "Semaphore::acquie - Wait failed.");
+      }
+      else
+      {
+         if (SDL_SemWaitTimeout(mData->semaphore, timeoutMS) < 0)
+            AssertFatal(false, "Semaphore::acquie - Wait with timeout failed.");
+      }
       return (true);
    }
    else

+ 2 - 0
Engine/source/platformX86UNIX/x86UNIXStub.dedicated.cpp

@@ -81,6 +81,8 @@ void OpenALDLLShutdown() {}
 
 // Platform Stubs
 
+bool Platform::excludeOtherInstances(const char*) { return true; }
+
 // clipboard
 const char* Platform::getClipboard() { return ""; }
 bool Platform::setClipboard(const char *text) { return false; }

+ 54 - 65
Engine/source/renderInstance/renderOcclusionMgr.cpp

@@ -29,7 +29,11 @@
 #include "gfx/gfxDrawUtil.h"
 #include "gfx/gfxTransformSaver.h"
 #include "math/util/sphereMesh.h"
+#include "materials/materialManager.h"
+#include "materials/sceneData.h"
+#include "math/util/matrixSet.h"
 #include "gfx/gfxDebugEvent.h"
+#include "materials/materialFeatureTypes.h"
 
 
 IMPLEMENT_CONOBJECT(RenderOcclusionMgr);
@@ -48,14 +52,14 @@ bool RenderOcclusionMgr::smDebugRender = false;
 RenderOcclusionMgr::RenderOcclusionMgr()
 : RenderBinManager(RenderPassManager::RIT_Occluder, 1.0f, 1.0f)
 {
-   mOverrideMat = NULL;
    mSpherePrimCount = 0;
+   mMatInstance = NULL;
 }
 
 RenderOcclusionMgr::RenderOcclusionMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
 : RenderBinManager(riType, renderOrder, processAddOrder)
 {  
-   mOverrideMat = NULL;
+    delete mMatInstance;
 }
 
 static const Point3F cubePoints[8] = 
@@ -72,25 +76,33 @@ static const U32 cubeFaces[6][4] =
 
 void RenderOcclusionMgr::init()
 {
-   GFXStateBlockDesc d;
+   delete mMatInstance;
+
+   mMaterial = MATMGR->allocateAndRegister( String::EmptyString );
+   mMaterial->mDiffuse[0] = ColorF( 1, 0, 1, 1 );
+   mMaterial->mEmissive[0] = true;
+   mMaterial->mAutoGenerated = true;
+
+   mMatInstance = mMaterial->createMatInstance();
+   FeatureSet features = MATMGR->getDefaultFeatures();
+   features.removeFeature( MFT_Visibility );
+   features.removeFeature( MFT_Fog );
+   features.removeFeature( MFT_HDROut );
+   mMatInstance->init( features, getGFXVertexFormat<GFXVertexP>() );
 
+   GFXStateBlockDesc d;
    d.setBlend( false );   
    d.cullDefined = true;
    d.cullMode = GFXCullCCW;
    d.setZReadWrite( true, false );   
-
-   mDebugSB = GFX->createStateBlock(d);
-
    d.setColorWrites( false, false, false, false );
-
-   mNormalSB = GFX->createStateBlock(d);      
+   mRenderSB = GFX->createStateBlock(d);      
 
    d.setZReadWrite( false, false );
-
    mTestSB = GFX->createStateBlock(d);
 
    mBoxBuff.set( GFX, 36, GFXBufferTypeStatic );
-   GFXVertexPC *verts = mBoxBuff.lock();
+   GFXVertexP *verts = mBoxBuff.lock();
 
    U32 vertexIndex = 0;
    U32 idx;
@@ -98,32 +110,26 @@ void RenderOcclusionMgr::init()
    {
       idx = cubeFaces[i][0];
       verts[vertexIndex].point = cubePoints[idx];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
 
       idx = cubeFaces[i][1];
       verts[vertexIndex].point = cubePoints[idx];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
 
       idx = cubeFaces[i][3];
       verts[vertexIndex].point = cubePoints[idx];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
 
       idx = cubeFaces[i][1];
       verts[vertexIndex].point = cubePoints[idx];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
 
       idx = cubeFaces[i][3];
       verts[vertexIndex].point = cubePoints[idx];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
 
       idx = cubeFaces[i][2];
       verts[vertexIndex].point = cubePoints[idx];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
    }
 
@@ -139,15 +145,12 @@ void RenderOcclusionMgr::init()
    for ( S32 i = 0; i < mSpherePrimCount; i++ )
    {      
       verts[vertexIndex].point = sphereMesh->poly[i].pnt[0];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
 
       verts[vertexIndex].point = sphereMesh->poly[i].pnt[1];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
 
       verts[vertexIndex].point = sphereMesh->poly[i].pnt[2];
-      verts[vertexIndex].color.set( 1,0,1,1 );
       vertexIndex++;
    }
    mSphereBuff.unlock();
@@ -177,62 +180,52 @@ void RenderOcclusionMgr::render( SceneRenderState *state )
    if ( !mElementList.size() )
       return;
    
+   GFXTransformSaver saver;
+
    GFXDEBUGEVENT_SCOPE(RenderOcclusionMgr_Render, ColorI::BLUE);
 
-   if ( mNormalSB.isNull() )
+   if ( mMatInstance == NULL )
       init();
 
-   GFX->disableShaders();
-   GFX->setupGenericShaders( GFXDevice::GSColor );  
+   SceneData sgData;
+   sgData.init( state );
 
+   // Restore transforms
+   MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
+   matrixSet.restoreSceneViewProjection();
 
-   OccluderRenderInst *firstEl = static_cast<OccluderRenderInst*>(mElementList[0].inst);
-   
-   if ( firstEl->isSphere )   
-      GFX->setVertexBuffer( mSphereBuff );
-   else
-      GFX->setVertexBuffer( mBoxBuff );
-
-   bool wasSphere = firstEl->isSphere;   
-
+   // The material is single pass... just setup once here.
+   mMatInstance->setupPass( state, sgData );
 
+   U32 primCount;
    for( U32 i=0; i<mElementList.size(); i++ )
    {
-      OccluderRenderInst *ri = static_cast<OccluderRenderInst*>(mElementList[i].inst);
-      
+      OccluderRenderInst *ri = static_cast<OccluderRenderInst*>(mElementList[i].inst);      
       AssertFatal( ri->query != NULL, "RenderOcclusionMgr::render, OcclusionRenderInst has NULL GFXOcclusionQuery" );
 
-      if ( ri->isSphere != wasSphere )
-      {
-         if ( ri->isSphere )
-            GFX->setVertexBuffer( mSphereBuff );
-         else
-            GFX->setVertexBuffer( mBoxBuff );
-
-         wasSphere = ri->isSphere;
-      }
+     if ( ri->isSphere )
+     {
+        GFX->setVertexBuffer( mSphereBuff );
+        primCount = mSpherePrimCount;
+     }
+     else
+     {
+        GFX->setVertexBuffer( mBoxBuff );
+        primCount = 12;
+     }
 
-      GFX->pushWorldMatrix();
-      
       MatrixF xfm( *ri->orientation );
       xfm.setPosition( ri->position );      
       xfm.scale( ri->scale );
 
-      //GFXTransformSaver saver;      
-      GFX->multWorld( xfm );
+      matrixSet.setWorld(xfm);
+      mMatInstance->setTransforms(matrixSet, state);
 
-      if ( smDebugRender )
-         GFX->setStateBlock( mDebugSB );
-      else
-         GFX->setStateBlock( mNormalSB );   
-
-      ri->query->begin();
-      
-      if ( wasSphere )
-         GFX->drawPrimitive( GFXTriangleList, 0, mSpherePrimCount );
-      else
-         GFX->drawPrimitive( GFXTriangleList, 0, 12 );
+      if ( !smDebugRender )
+         GFX->setStateBlock( mRenderSB );   
 
+      ri->query->begin();      
+      GFX->drawPrimitive( GFXTriangleList, 0, primCount );
       ri->query->end();
 
       if ( ri->query2 )
@@ -240,15 +233,11 @@ void RenderOcclusionMgr::render( SceneRenderState *state )
          GFX->setStateBlock( mTestSB );
 
          ri->query2->begin();
-
-         if ( wasSphere )
-            GFX->drawPrimitive( GFXTriangleList, 0, mSpherePrimCount );
-         else
-            GFX->drawPrimitive( GFXTriangleList, 0, 12 );
-
+         GFX->drawPrimitive( GFXTriangleList, 0, primCount );
          ri->query2->end();
       }
+   }   
 
-      GFX->popWorldMatrix();      
-   }
+   // Call setup one more time to end the pass.
+   mMatInstance->setupPass( state, sgData );
 }

+ 12 - 6
Engine/source/renderInstance/renderOcclusionMgr.h

@@ -26,6 +26,10 @@
 #include "renderInstance/renderBinManager.h"
 #endif
 
+class Material;
+class BaseMatInstance;
+
+
 //**************************************************************************
 // RenderOcclusionMgr
 //**************************************************************************
@@ -46,15 +50,17 @@ public:
    DECLARE_CONOBJECT(RenderOcclusionMgr);
 
 protected:
-   BaseMatInstance* mOverrideMat;
-   GFXStateBlockRef mNormalSB;
+   GFXStateBlockRef mRenderSB;
    GFXStateBlockRef mTestSB;
-   
-   GFXStateBlockRef mDebugSB;
+
+   /// The material for rendering occluders.
+   SimObjectPtr<Material> mMaterial;
+   BaseMatInstance *mMatInstance;
+
    static bool smDebugRender;
 
-   GFXVertexBufferHandle<GFXVertexPC> mBoxBuff;
-   GFXVertexBufferHandle<GFXVertexPC> mSphereBuff;
+   GFXVertexBufferHandle<GFXVertexP> mBoxBuff;
+   GFXVertexBufferHandle<GFXVertexP> mSphereBuff;
    U32 mSpherePrimCount;
 };
 

+ 1 - 1
Engine/source/renderInstance/renderPassManager.cpp

@@ -42,7 +42,7 @@
 #include "console/engineAPI.h"
 
 
-const RenderInstType RenderInstType::Invalid( String::EmptyString );
+const RenderInstType RenderInstType::Invalid( "" );
 
 const RenderInstType RenderPassManager::RIT_Interior("Interior");
 const RenderInstType RenderPassManager::RIT_Mesh("Mesh");

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

@@ -236,7 +236,7 @@ GFXTexHandle ReflectionManager::allocRenderTarget( const Point2I &size )
                         avar("%s() - mReflectTex (line %d)", __FUNCTION__, __LINE__) );
 }
 
-GFXTextureObject* ReflectionManager::getRefractTex()
+GFXTextureObject* ReflectionManager::getRefractTex( bool forceUpdate )
 {
    GFXTarget *target = GFX->getActiveRenderTarget();
    GFXFormat targetFormat = target->getFormat();
@@ -261,7 +261,7 @@ GFXTextureObject* ReflectionManager::getRefractTex()
       mUpdateRefract = true;
    }
 
-   if ( mUpdateRefract )
+   if ( forceUpdate || mUpdateRefract )
    {
       target->resolveTo( mRefractTex );   
       mUpdateRefract = false;

+ 1 - 1
Engine/source/scene/reflectionManager.h

@@ -101,7 +101,7 @@ public:
 
    GFXTexHandle allocRenderTarget( const Point2I &size );  
 
-   GFXTextureObject* getRefractTex();
+   GFXTextureObject* getRefractTex( bool forceUpdate = false );
 
    BaseMatInstance* getReflectionMaterial( BaseMatInstance *inMat ) const;
 

+ 4 - 3
Engine/source/scene/sceneContainer.cpp

@@ -1612,7 +1612,8 @@ DefineEngineFunction( containerRayCast, const char*,
    "@returns A string containing either null, if nothing was struck, or these fields:\n"
    "<ul><li>The ID of the object that was struck.</li>"
    "<li>The x, y, z position that it was struck.</li>"
-   "<li>The x, y, z of the normal of the face that was struck.</li></ul>" 
+   "<li>The x, y, z of the normal of the face that was struck.</li>"
+   "<li>The distance between the start point and the position we hit.</li></ul>" 
 
    "@ingroup Game")
 {
@@ -1633,9 +1634,9 @@ DefineEngineFunction( containerRayCast, const char*,
    char *returnBuffer = Con::getReturnBuffer(256);
    if(ret)
    {
-      dSprintf(returnBuffer, 256, "%d %g %g %g %g %g %g",
+      dSprintf(returnBuffer, 256, "%d %g %g %g %g %g %g %g",
                ret, rinfo.point.x, rinfo.point.y, rinfo.point.z,
-               rinfo.normal.x, rinfo.normal.y, rinfo.normal.z);
+               rinfo.normal.x, rinfo.normal.y, rinfo.normal.z, rinfo.distance);
    }
    else
    {

+ 1 - 1
Engine/source/scene/zones/scenePolyhedralZone.cpp

@@ -73,7 +73,7 @@ void ScenePolyhedralZone::_updateOrientedWorldBox()
    if( mIsBox )
       Parent::_updateOrientedWorldBox();
    else
-      mOrientedWorldBox.set( getTransform(), Point3F( mObjBox.len_x(), mObjBox.len_y(), mObjBox.len_z() ) );
+       mOrientedWorldBox.set( getTransform(), mObjBox.getExtents() * getScale() );
 }
 
 //-----------------------------------------------------------------------------

+ 44 - 44
Engine/source/sfx/fmod/fmodFunctions.h

@@ -107,51 +107,51 @@ FMOD_FUNCTION( FMOD_Memory_Initialize, ( void *poolmem, int poollen, FMOD_MEMORY
 
 // FMOD Designer API:
 
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_Create, ( FMOD_EVENTSYSTEM** eventsystem ), "_FMOD_EventSystem_Create@4" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetSystemObject, ( FMOD_EVENTSYSTEM* eventsystem, FMOD_SYSTEM** system ), "_FMOD_EventSystem_GetSystemObject@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetVersion, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int* version ), "_FMOD_EventSystem_GetVersion@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_Init, ( FMOD_EVENTSYSTEM* eventsystem, int maxchannels, FMOD_INITFLAGS flags, void* extradriverdata, FMOD_EVENT_INITFLAGS eventflags ), "_FMOD_EventSystem_Init@20" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_Release, ( FMOD_EVENTSYSTEM* eventsystem ), "_FMOD_EventSystem_Release@4" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_Load, ( FMOD_EVENTSYSTEM* eventsystem, const char* name_or_data, FMOD_EVENT_LOADINFO* loadinfo, FMOD_EVENTPROJECT** project ), "_FMOD_EventSystem_Load@16" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_Update, ( FMOD_EVENTSYSTEM* eventsystem ), "_FMOD_EventSystem_Update@4" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetMemoryInfo, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ), "_FMOD_EventSystem_GetMemoryInfo@20" )
-FMOD_EVENT_FUNCTION( FMOD_EventSystem_SetMediaPath, ( FMOD_EVENTSYSTEM* eventsystem, const char* path ), "_FMOD_EventSystem_SetMediaPath@8" )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_Create, ( FMOD_EVENTSYSTEM** eventsystem ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetSystemObject, ( FMOD_EVENTSYSTEM* eventsystem, FMOD_SYSTEM** system ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetVersion, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int* version ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_Init, ( FMOD_EVENTSYSTEM* eventsystem, int maxchannels, FMOD_INITFLAGS flags, void* extradriverdata, FMOD_EVENT_INITFLAGS eventflags ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_Release, ( FMOD_EVENTSYSTEM* eventsystem ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_Load, ( FMOD_EVENTSYSTEM* eventsystem, const char* name_or_data, FMOD_EVENT_LOADINFO* loadinfo, FMOD_EVENTPROJECT** project ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_Update, ( FMOD_EVENTSYSTEM* eventsystem ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetMemoryInfo, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ) )
+FMOD_EVENT_FUNCTION( FMOD_EventSystem_SetMediaPath, ( FMOD_EVENTSYSTEM* eventsystem, const char* path ) )
 
-FMOD_EVENT_FUNCTION( FMOD_EventProject_Release, ( FMOD_EVENTPROJECT* eventproject ), "_FMOD_EventProject_Release@4" )
-FMOD_EVENT_FUNCTION( FMOD_EventProject_GetInfo, ( FMOD_EVENTPROJECT* eventproject, FMOD_EVENT_PROJECTINFO* info ), "_FMOD_EventProject_GetInfo@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumEvents, ( FMOD_EVENTPROJECT* eventproject, int* numevents ), "_FMOD_EventProject_GetNumEvents@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumGroups, ( FMOD_EVENTPROJECT* eventproject, int* numgroups ), "_FMOD_EventProject_GetNumGroups@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroupByIndex, ( FMOD_EVENTPROJECT* eventproject, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ), "_FMOD_EventProject_GetGroupByIndex@16" )
-FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroup, ( FMOD_EVENTPROJECT* eventproject, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ), "_FMOD_EventProject_GetGroup@16" )
+FMOD_EVENT_FUNCTION( FMOD_EventProject_Release, ( FMOD_EVENTPROJECT* eventproject ) )
+FMOD_EVENT_FUNCTION( FMOD_EventProject_GetInfo, ( FMOD_EVENTPROJECT* eventproject, FMOD_EVENT_PROJECTINFO* info ) )
+FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumEvents, ( FMOD_EVENTPROJECT* eventproject, int* numevents ) )
+FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumGroups, ( FMOD_EVENTPROJECT* eventproject, int* numgroups ) )
+FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroupByIndex, ( FMOD_EVENTPROJECT* eventproject, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
+FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroup, ( FMOD_EVENTPROJECT* eventproject, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
 
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetInfo, ( FMOD_EVENTGROUP* eventgroup, int* index, char** name ), "_FMOD_EventGroup_GetInfo@12" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_LoadEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT_RESOURCE resource, FMOD_EVENT_MODE mode ), "_FMOD_EventGroup_LoadEventData@12" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_FreeEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT* event, FMOD_BOOL waituntilready ), "_FMOD_EventGroup_FreeEventData@12" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumEvents, ( FMOD_EVENTGROUP* eventgroup, int* numevents ), "_FMOD_EventGroup_GetNumEvents@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumGroups, ( FMOD_EVENTGROUP* eventgroup, int* numgroups ), "_FMOD_EventGroup_GetNumGroups@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEventByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_EVENT_MODE mode, FMOD_EVENT** event ), "_FMOD_EventGroup_GetEventByIndex@16" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEvent, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_EVENT_MODE mode, FMOD_EVENT** event ), "_FMOD_EventGroup_GetEvent@16" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroupByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ), "_FMOD_EventGroup_GetGroupByIndex@16" )
-FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroup, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ), "_FMOD_EventGroup_GetGroup@16" )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetInfo, ( FMOD_EVENTGROUP* eventgroup, int* index, char** name ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_LoadEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT_RESOURCE resource, FMOD_EVENT_MODE mode ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_FreeEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT* event, FMOD_BOOL waituntilready ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumEvents, ( FMOD_EVENTGROUP* eventgroup, int* numevents ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumGroups, ( FMOD_EVENTGROUP* eventgroup, int* numgroups ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEventByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_EVENT_MODE mode, FMOD_EVENT** event ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEvent, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_EVENT_MODE mode, FMOD_EVENT** event ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroupByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
+FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroup, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
 
-FMOD_EVENT_FUNCTION( FMOD_Event_GetInfo, ( FMOD_EVENT* event, int* index, char** name, FMOD_EVENT_INFO* info ), "_FMOD_Event_GetInfo@16" )
-FMOD_EVENT_FUNCTION( FMOD_Event_Release, ( FMOD_EVENT* event, FMOD_BOOL freeeventdata, FMOD_BOOL waituntilready ), "_FMOD_Event_Release@12" )
-FMOD_EVENT_FUNCTION( FMOD_Event_Start, ( FMOD_EVENT* event ), "_FMOD_Event_Start@4" )
-FMOD_EVENT_FUNCTION( FMOD_Event_Stop, ( FMOD_EVENT* event, FMOD_BOOL immediate ), "_FMOD_Event_Stop@8" )
-FMOD_EVENT_FUNCTION( FMOD_Event_SetPaused, ( FMOD_EVENT* event, FMOD_BOOL paused ), "_FMOD_Event_SetPaused@8" )
-FMOD_EVENT_FUNCTION( FMOD_Event_SetVolume, ( FMOD_EVENT* event, float volume ), "_FMOD_Event_SetVolume@8" )
-FMOD_EVENT_FUNCTION( FMOD_Event_SetPitch, ( FMOD_EVENT* event, float pitch, FMOD_EVENT_PITCHUNITS units ), "_FMOD_Event_SetPitch@12" )
-FMOD_EVENT_FUNCTION( FMOD_Event_Set3DAttributes, ( FMOD_EVENT* event, const FMOD_VECTOR* position, const FMOD_VECTOR* velocity, const FMOD_VECTOR* orientation ), "_FMOD_Event_Set3DAttributes@16" )
-FMOD_EVENT_FUNCTION( FMOD_Event_GetState, ( FMOD_EVENT* event, FMOD_EVENT_STATE* state ), "_FMOD_Event_GetState@8" )
-FMOD_EVENT_FUNCTION( FMOD_Event_GetNumParameters, ( FMOD_EVENT* event, int* numparameters ), "_FMOD_Event_GetNumParameters@8" )
-FMOD_EVENT_FUNCTION( FMOD_Event_GetParameter, ( FMOD_EVENT* event, const char* name, FMOD_EVENTPARAMETER** parameter ), "_FMOD_Event_GetParameter@12" )
-FMOD_EVENT_FUNCTION( FMOD_Event_GetParameterByIndex, ( FMOD_EVENT* event, int index, FMOD_EVENTPARAMETER** parameter ), "_FMOD_Event_GetParameterByIndex@12" )
-FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ), "_FMOD_Event_GetPropertyByIndex@16" )
-FMOD_EVENT_FUNCTION( FMOD_Event_SetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ), "_FMOD_Event_SetPropertyByIndex@16" )
-FMOD_EVENT_FUNCTION( FMOD_Event_GetProperty, ( FMOD_EVENT* event, const char* propertyname, void* value, FMOD_BOOL this_instance ), "_FMOD_Event_GetProperty@16" )
-FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyInfo, ( FMOD_EVENT* event, int* propertyindex, char** propertyname, FMOD_EVENTPROPERTY_TYPE* type ), "_FMOD_Event_GetPropertyInfo@16" )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetInfo, ( FMOD_EVENT* event, int* index, char** name, FMOD_EVENT_INFO* info ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_Release, ( FMOD_EVENT* event, FMOD_BOOL freeeventdata, FMOD_BOOL waituntilready ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_Start, ( FMOD_EVENT* event ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_Stop, ( FMOD_EVENT* event, FMOD_BOOL immediate ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_SetPaused, ( FMOD_EVENT* event, FMOD_BOOL paused ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_SetVolume, ( FMOD_EVENT* event, float volume ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_SetPitch, ( FMOD_EVENT* event, float pitch, FMOD_EVENT_PITCHUNITS units ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_Set3DAttributes, ( FMOD_EVENT* event, const FMOD_VECTOR* position, const FMOD_VECTOR* velocity, const FMOD_VECTOR* orientation ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetState, ( FMOD_EVENT* event, FMOD_EVENT_STATE* state ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetNumParameters, ( FMOD_EVENT* event, int* numparameters ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetParameter, ( FMOD_EVENT* event, const char* name, FMOD_EVENTPARAMETER** parameter ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetParameterByIndex, ( FMOD_EVENT* event, int index, FMOD_EVENTPARAMETER** parameter ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_SetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetProperty, ( FMOD_EVENT* event, const char* propertyname, void* value, FMOD_BOOL this_instance ) )
+FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyInfo, ( FMOD_EVENT* event, int* propertyindex, char** propertyname, FMOD_EVENTPROPERTY_TYPE* type ) )
 
-FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetInfo, ( FMOD_EVENTPARAMETER* eventparameter, int* index, char** name ), "_FMOD_EventParameter_GetInfo@12" )
-FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetValue, ( FMOD_EVENTPARAMETER* eventparameter, float* value ), "_FMOD_EventParameter_GetValue@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventParameter_SetValue, ( FMOD_EVENTPARAMETER* eventparameter, float value ), "_FMOD_EventParameter_SetValue@8" )
-FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetRange, ( FMOD_EVENTPARAMETER* eventparameter, float* rangemin, float* rangemax ), "_FMOD_EventParameter_GetRange@12" )
+FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetInfo, ( FMOD_EVENTPARAMETER* eventparameter, int* index, char** name ) )
+FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetValue, ( FMOD_EVENTPARAMETER* eventparameter, float* value ) )
+FMOD_EVENT_FUNCTION( FMOD_EventParameter_SetValue, ( FMOD_EVENTPARAMETER* eventparameter, float value ) )
+FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetRange, ( FMOD_EVENTPARAMETER* eventparameter, float* rangemin, float* rangemax ) )

+ 2 - 2
Engine/source/sfx/fmod/sfxFMODDevice.cpp

@@ -245,9 +245,9 @@ bool SFXFMODDevice::_init()
       if( smPrefDisableSoftware )
          flags |= FMOD_INIT_SOFTWARE_DISABLE;
       if( smPrefUseSoftwareOcclusion )
-         flags |= FMOD_INIT_SOFTWARE_OCCLUSION;
+         flags |= FMOD_INIT_OCCLUSION_LOWPASS;
       if( smPrefUseSoftwareHRTF )
-         flags |= FMOD_INIT_SOFTWARE_HRTF;
+         flags |= FMOD_INIT_HRTF_LOWPASS;
       if( smPrefUseSoftwareReverbLowmem )
          flags |= FMOD_INIT_SOFTWARE_REVERB_LOWMEM;
       if( smPrefEnableProfile )

+ 2 - 2
Engine/source/sfx/fmod/sfxFMODDevice.h

@@ -78,7 +78,7 @@
 // Typedefs
 #define FMOD_FUNCTION(fn_name, fn_args) \
    typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
-#define FMOD_EVENT_FUNCTION(fn_name, fn_args, dllexport) \
+#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
    typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
 #include FMOD_FN_FILE
 #undef FMOD_FUNCTION
@@ -189,7 +189,7 @@ struct FModFNTable
 
 #define FMOD_FUNCTION(fn_name, fn_args) \
    Thunk< FMODFNPTR##fn_name > fn_name;
-#define FMOD_EVENT_FUNCTION(fn_name, fn_args, dllexport) \
+#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
    Thunk< FMODFNPTR##fn_name > fn_name;
 #include FMOD_FN_FILE
 #undef FMOD_FUNCTION

+ 3 - 3
Engine/source/sfx/fmod/sfxFMODEvent.cpp

@@ -117,11 +117,11 @@ SFXFMODEvent::SFXFMODEvent( SFXFMODEventGroup* group, FMOD_EVENT* handle )
    if( group->isClientOnly() )
       Sim::getRootGroup()->addObject( mDescription );
    
-   int intValue;
+   FMOD_MODE modeValue;
    float floatValue;
    
-   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_MODE, &intValue, true ) == FMOD_OK )
-      mDescription->mIs3D = ( intValue == FMOD_3D );
+   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_MODE, &modeValue, true ) == FMOD_OK )
+      mDescription->mIs3D = ( modeValue == FMOD_3D );
    if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_VOLUME, &floatValue, true ) == FMOD_OK )
       mDescription->mVolume = floatValue;
    if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_PITCH, &floatValue, true ) == FMOD_OK )

+ 6 - 11
Engine/source/sfx/fmod/sfxFMODProvider.cpp

@@ -201,21 +201,16 @@ void SFXFMODProvider::init()
    
    mFMod.eventDllRef = OsLoadLibrary( eventDllName );
    if(!mFMod.eventDllRef)
-      Con::warnf( "SFXFMODProvider - Could not locate %s - FMOD Designer intergration not available.", eventDllName );
+      Con::warnf( "SFXFMODProvider - Could not locate %s - FMOD Designer integration not available.", eventDllName );
 
    mFMod.isLoaded = true;
    mFMod.eventIsLoaded = true;
 
    #define FMOD_FUNCTION(fn_name, fn_args) \
       mFMod.isLoaded &= fmodBindFunction(mFMod.dllRef, *(void**)&mFMod.fn_name.fn, #fn_name);
-   #ifdef TORQUE_OS_WIN32
-      #define FMOD_EVENT_FUNCTION(fn_name, fn_args, export) \
-         mFMod.eventIsLoaded &= fmodBindFunction(mFMod.eventDllRef, *(void**)&mFMod.fn_name.fn, export);
-   #else
-      #define FMOD_EVENT_FUNCTION(fn_name, fn_args, export) \
-         mFMod.eventIsLoaded &= fmodBindFunction(mFMod.eventDllRef, *(void**)&mFMod.fn_name.fn, #fn_name);
-   #endif
-      
+   #define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
+      mFMod.eventIsLoaded &= fmodBindFunction(mFMod.eventDllRef, *(void**)&mFMod.fn_name.fn, #fn_name);
+            
    #include FMOD_FN_FILE
    
    #undef FMOD_FUNCTION
@@ -223,11 +218,11 @@ void SFXFMODProvider::init()
 
    if(mFMod.isLoaded == false)
    {
-      Con::warnf("SFXFMODProvider - Could not locate %s - FMOD not available.", dllName);
+      Con::warnf("SFXFMODProvider - Could not load %s - FMOD not available.", dllName);
       return;
    }
    if( !mFMod.eventIsLoaded && mFMod.eventDllRef )
-      Con::warnf("SFXFMODProvider - Could not load the %s - FMOD Designer integration not available.", eventDllName);
+      Con::warnf("SFXFMODProvider - Could not load %s - FMOD Designer integration not available.", eventDllName);
 
 #endif
 

+ 2 - 2
Engine/source/sfx/sfxDescription.cpp

@@ -508,8 +508,8 @@ void SFXDescription::packData( BitStream *stream )
    Parent::packData( stream );
 
    stream->writeFloat( mVolume, 6 );
-   stream->writeFloat( mPitch, 6 );
-   stream->writeFloat( mPriority, 6 );
+   stream->write( mPitch );
+   stream->write( mPriority );
 
    stream->writeFlag( mIsLooping );
    stream->writeFlag( mFadeLoops );

+ 61 - 53
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp

@@ -1659,59 +1659,67 @@ void ReflectCubeFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
          meta->addStatement( new GenOp( "   @ = @;\r\n", outTex, inTex ) );
       }
    }
-
-   // create cubeTrans
-   Var *cubeTrans = new Var;
-   cubeTrans->setType( "float3x3" );
-   cubeTrans->setName( "cubeTrans" );
-   cubeTrans->uniform = true;
-   cubeTrans->constSortPos = cspPrimitive;   
-
-   // create cubeEye position
-   Var *cubeEyePos = new Var;
-   cubeEyePos->setType( "float3" );
-   cubeEyePos->setName( "cubeEyePos" );
-   cubeEyePos->uniform = true;
-   cubeEyePos->constSortPos = cspPrimitive;   
-
-   // cube vert position
-   Var * cubeVertPos = new Var;
-   cubeVertPos->setName( "cubeVertPos" );
-   cubeVertPos->setType( "float3" );
-   LangElement *cubeVertPosDecl = new DecOp( cubeVertPos );
-
-   meta->addStatement( new GenOp( "   @ = mul(@, @).xyz;\r\n", 
-                       cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
-
-   // cube normal
-   Var * cubeNormal = new Var;
-   cubeNormal->setName( "cubeNormal" );
-   cubeNormal->setType( "float3" );
-   LangElement *cubeNormDecl = new DecOp( cubeNormal );
-
-   meta->addStatement( new GenOp( "   @ = normalize( mul(@, normalize(@)).xyz );\r\n", 
-                       cubeNormDecl, cubeTrans, inNormal ) );
-
-   // eye to vert
-   Var * eyeToVert = new Var;
-   eyeToVert->setName( "eyeToVert" );
-   eyeToVert->setType( "float3" );
-   LangElement *e2vDecl = new DecOp( eyeToVert );
-
-   meta->addStatement( new GenOp( "   @ = @ - @;\r\n", 
-                       e2vDecl, cubeVertPos, cubeEyePos ) );
-
-   // grab connector texcoord register
-   ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
-   Var *reflectVec = connectComp->getElement( RT_TEXCOORD );
-   reflectVec->setName( "reflectVec" );
-   reflectVec->setStructName( "OUT" );
-   reflectVec->setType( "float3" );
-   reflectVec->mapsToSampler = true;
-
-   meta->addStatement( new GenOp( "   @ = reflect(@, @);\r\n", reflectVec, eyeToVert, cubeNormal ) );
-
-   output = meta;
+       
+    // create cubeTrans
+    bool useInstancing = fd.features[MFT_UseInstancing];
+    Var *cubeTrans = getObjTrans( componentList, useInstancing, meta );
+
+    // cube vert position
+    Var * cubeVertPos = new Var;
+    cubeVertPos->setName( "cubeVertPos" );
+    cubeVertPos->setType( "float3" );
+    LangElement *cubeVertPosDecl = new DecOp( cubeVertPos );
+
+    meta->addStatement( new GenOp( "   @ = mul((float3x3)@, @).xyz;\r\n", 
+                        cubeVertPosDecl, cubeTrans, LangElement::find( "position" ) ) );
+
+    // cube normal
+    Var * cubeNormal = new Var;
+    cubeNormal->setName( "cubeNormal" );
+    cubeNormal->setType( "float3" );
+    LangElement *cubeNormDecl = new DecOp( cubeNormal );
+
+    meta->addStatement( new GenOp( "   @ = normalize( mul(@, normalize(@)).xyz );\r\n", 
+                        cubeNormDecl, cubeTrans, inNormal ) );
+
+    // grab the eye position
+    Var *eyePos = (Var*)LangElement::find( "eyePosWorld" );
+    if ( !eyePos )
+    {
+        eyePos = new Var( "eyePosWorld", "float3" );
+        eyePos->uniform = true;
+        eyePos->constSortPos = cspPass;
+    }
+
+    // cube position
+    Var * cubePos = new Var;
+    cubePos->setName( "cubePos" );
+    cubePos->setType( "float3" );
+    LangElement *cubePosDecl = new DecOp( cubePos );
+
+    meta->addStatement( new GenOp( "   @ = float3( @[0][3], @[1][3], @[2][3] );\r\n", 
+                        cubePosDecl, cubeTrans, cubeTrans, cubeTrans ) );
+
+    // eye to vert
+    Var * eyeToVert = new Var;
+    eyeToVert->setName( "eyeToVert" );
+    eyeToVert->setType( "float3" );
+    LangElement *e2vDecl = new DecOp( eyeToVert );
+
+    meta->addStatement( new GenOp( "   @ = @ - ( @ - @ );\r\n", 
+                        e2vDecl, cubeVertPos, eyePos, cubePos ) );
+
+    // grab connector texcoord register
+    ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
+    Var *reflectVec = connectComp->getElement( RT_TEXCOORD );
+    reflectVec->setName( "reflectVec" );
+    reflectVec->setStructName( "OUT" );
+    reflectVec->setType( "float3" );
+    reflectVec->mapsToSampler = true;
+
+    meta->addStatement( new GenOp( "   @ = reflect(@, @);\r\n", reflectVec, eyeToVert, cubeNormal ) );
+
+    output = meta;
 }
 
 void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList, 

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

@@ -243,7 +243,7 @@ void NetConnection::eventWritePacket(BitStream *bstream, PacketNotify *notify)
          packQueueTail->mNextEvent = ev;
       packQueueTail = ev;
       if(!bstream->writeFlag(ev->mSeqCount == prevSeq + 1))
-         bstream->writeInt(ev->mSeqCount, 7);
+         bstream->writeInt(ev->mSeqCount & 0x7F, 7);
 
       prevSeq = ev->mSeqCount;
 

+ 1 - 0
Engine/source/terrain/terrCollision.cpp

@@ -616,6 +616,7 @@ bool TerrainBlock::castRay(const Point3F &start, const Point3F &end, RayInfo *in
       
    // Set intersection point.
    info->setContactPoint( start, end );
+   getTransform().mulP( info->point );    // transform to world coordinates for getGridPos
 
    // Set material at contact point.
    Point2I gridPos = getGridPos( info->point );

+ 5 - 0
Engine/source/ts/collada/colladaAppMesh.cpp

@@ -463,6 +463,11 @@ S32 ColladaAppMesh::addMaterial(const char* symbol)
          }
       }
    }
+   else
+   {
+      // No Collada material is present for this symbol, so just create an empty one
+      appMaterials.push_back(new ColladaAppMaterial(symbol));
+   }
 
    // Add this symbol to the bound list for the mesh
    boundMaterials.insert(StringTable->insert(symbol), matIndex);

+ 67 - 10
Engine/source/ts/tsMesh.cpp

@@ -322,9 +322,11 @@ bool TSMesh::buildPolyList( S32 frame, AbstractPolyList *polyList, U32 &surfaceK
          }
          else
          {
-            base = polyList->addPoint( mVertexData[firstVert].vert() );
+            base = polyList->addPointAndNormal( mVertexData[firstVert].vert(), mVertexData[firstVert].normal() );
             for ( i = 1; i < vertsPerFrame; i++ )
-               polyList->addPoint( mVertexData[ i + firstVert ].vert() );
+            {
+               polyList->addPointAndNormal( mVertexData[ i + firstVert ].vert(), mVertexData[ i + firstVert ].normal() );
+            }
          }
       }
       else
@@ -348,9 +350,9 @@ bool TSMesh::buildPolyList( S32 frame, AbstractPolyList *polyList, U32 &surfaceK
          }
          else
          {
-            base = polyList->addPoint( verts[firstVert] );
+            base = polyList->addPointAndNormal( verts[firstVert], norms[firstVert] );
             for ( i = 1; i < vertsPerFrame; i++ )
-               polyList->addPoint( verts[ i + firstVert ] );
+               polyList->addPointAndNormal( verts[ i + firstVert ], norms[ i + firstVert ] );
          }
       }
    }
@@ -1301,6 +1303,8 @@ void TSSkinMesh::createBatchData()
    // Temp vector to build batch operations
    Vector<BatchData::BatchedVertex> batchOperations;
 
+   bool issuedWeightWarning = false;
+
    // Build the batch operations
    while( curVtx != endVtx )
    {
@@ -1313,13 +1317,43 @@ void TSSkinMesh::createBatchData()
       const F32 w = *curWeight;
       ++curWeight;
 
+      // Ignore empty weights
+      if ( vidx < 0 || midx < 0 || w == 0 )
+         continue;
+
       if( !batchOperations.empty() &&
          batchOperations.last().vertexIndex == vidx )
       {
          AssertFatal( batchOperations.last().transformCount > 0, "Not sure how this happened!" );
 
-         const int opIdx = batchOperations.last().transformCount++;
-         AssertISV( BatchData::maxBonePerVert > opIdx, "Too many bones affecting the same vertex, increase the size of 'TSMesh::BatchData::maxBonePerVert'" );
+         S32 opIdx = batchOperations.last().transformCount++;
+
+         // Limit the number of weights per bone (keep the N largest influences)
+         if ( opIdx >= TSSkinMesh::BatchData::maxBonePerVert )
+         {
+            if ( !issuedWeightWarning )
+            {
+               issuedWeightWarning = true;
+               Con::warnf( "At least one vertex has too many bone weights - limiting "
+                  "to the largest %d influences (see maxBonePerVert in tsMesh.h).",
+                  TSSkinMesh::BatchData::maxBonePerVert );
+            }
+
+            // Too many weights => find and replace the smallest one
+            S32 minIndex = 0;
+            F32 minWeight = batchOperations.last().transform[0].weight;
+            for ( S32 i = 1; i < batchOperations.last().transformCount; i++ )
+            {
+               if ( batchOperations.last().transform[i].weight < minWeight )
+               {
+                  minWeight = batchOperations.last().transform[i].weight;
+                  minIndex = i;
+               }
+            }
+
+            opIdx = minIndex;
+            batchOperations.last().transformCount = TSSkinMesh::BatchData::maxBonePerVert;
+         }
 
          batchOperations.last().transform[opIdx].transformIndex = midx;
          batchOperations.last().transform[opIdx].weight = w;
@@ -1337,6 +1371,25 @@ void TSSkinMesh::createBatchData()
    }
    //Con::printf("End skin update");
 
+   // Normalize vertex weights (force weights for each vert to sum to 1)
+   if ( issuedWeightWarning )
+   {
+      for ( S32 i = 0; i < batchOperations.size(); i++ )
+      {
+         BatchData::BatchedVertex& batchOp = batchOperations[i];
+
+         // Sum weights for this vertex
+         F32 invTotalWeight = 0;
+         for ( S32 j = 0; j < batchOp.transformCount; j++ )
+            invTotalWeight += batchOp.transform[j].weight;
+
+         // Then normalize the vertex weights
+         invTotalWeight = 1.0f / invTotalWeight;
+         for ( S32 j = 0; j < batchOp.transformCount; j++ )
+            batchOp.transform[j].weight *= invTotalWeight;
+      }
+   }
+
 #ifdef _BATCH_BY_VERTEX
    // Copy data to member, and be done
    batchData.vertexBatchOperations.set(batchOperations.address(), batchOperations.size());
@@ -2636,10 +2689,14 @@ void TSMesh::disassemble()
       {
          const TSDrawPrimitive& prim = primitives[i];
 
-         TriListOpt::OptimizeTriangleOrdering(verts.size(), prim.numElements,
-            indices.address() + prim.start, tmpIdxs.address());
-         dCopyArray(indices.address() + prim.start, tmpIdxs.address(), 
-            prim.numElements);
+         // only optimize triangle lists (strips and fans are assumed to be already optimized)
+         if ( (prim.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles )
+         {
+            TriListOpt::OptimizeTriangleOrdering(verts.size(), prim.numElements,
+               indices.address() + prim.start, tmpIdxs.address());
+            dCopyArray(indices.address() + prim.start, tmpIdxs.address(), 
+               prim.numElements);
+         }
       }
    }
 

+ 3 - 0
Engine/source/ts/tsShapeConstruct.h

@@ -38,6 +38,9 @@
 #ifndef _COLLADA_UTILS_H_
 #include "ts/collada/colladaUtils.h"
 #endif
+#ifndef _ENGINEAPI_H_
+#include "console/engineAPI.h"
+#endif
 
 /// This class allows an artist to export their animations for the model
 /// into the .dsq format.  This class in particular matches up the model

BIN
QtCore4.dll


BIN
QtGui4.dll


BIN
QtNetwork4.dll


BIN
QtXml4.dll


BIN
Templates/Empty PhysX/game/Empty PhysX.dll


BIN
Templates/Empty PhysX/game/Empty PhysX.exe


BIN
Templates/Empty PhysX/game/IE Empty PhysX Plugin.dll


BIN
Templates/Empty PhysX/game/NP Empty PhysX Plugin.dll


+ 7 - 0
Templates/Empty PhysX/game/scripts/client/serverConnection.cs

@@ -121,6 +121,13 @@ function disconnectedCleanup()
    // Back to the launch screen
    if (isObject( MainMenuGui ))
       Canvas.setContent( MainMenuGui );
+
+   // Before we destroy the client physics world
+   // make sure all ServerConnection objects are deleted.
+   if(isObject(ServerConnection))
+   {
+      ServerConnection.deleteAllObjects();
+   }
    
    // We can now delete the client physics simulation.
    physicsDestroyWorld( "client" );                 

+ 1 - 1
Templates/Empty PhysX/game/tools/materialEditor/scripts/materialEditor.ed.cs

@@ -814,7 +814,7 @@ function MaterialEditorGui::guiSync( %this, %material )
    MaterialEditorPropertiesWindow-->showFootprintsCheckbox.setValue((%material).showFootprints);
    MaterialEditorPropertiesWindow-->showDustCheckbox.setValue((%material).showDust);
    MaterialEditorGui.updateSoundPopup("Footstep", (%material).footstepSoundId, (%material).customFootstepSound);
-   MaterialEditorGui.updateSoundPopup("Impact", (%material).footstepSoundId, (%material).customFootstepSound);
+   MaterialEditorGui.updateSoundPopup("Impact", (%material).impactSoundId, (%material).customImpactSound);
 
    //layer specific controls are located here
    %layer = MaterialEditorGui.currentLayer;

+ 4 - 1
Templates/Empty PhysX/game/tools/worldEditor/scripts/editors/worldEditor.ed.cs

@@ -119,6 +119,9 @@ function WorldEditor::onSelectionCentroidChanged( %this )
 {
    // Inform the camera
    commandToServer('EditorOrbitCameraSelectChange', %this.getSelectionSize(), %this.getSelectionCentroid());
+   
+   // Refresh inspector.
+   Inspector.refresh();
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -126,7 +129,7 @@ function WorldEditor::onSelectionCentroidChanged( %this )
 function WorldEditor::init(%this)
 {
    // add objclasses which we do not want to collide with
-   %this.ignoreObjClass(Sky, AIObjective);
+   %this.ignoreObjClass(Sky);
 
    // editing modes
    %this.numEditModes = 3;

+ 67 - 0
Templates/Empty/DeleteCachedDTSs.command

@@ -0,0 +1,67 @@
+<?php
+
+// Set the game project name, this is what your game's exe/dll will be called
+setGameProjectName("Empty");
+
+setPlatform( 'linux' );
+
+// Libs
+includeLib( 'mng' );
+includeLib( 'png' );
+includeLib( 'ungif' );
+includeLib( 'jpeg' );
+includeLib( 'tinyxml' );
+includeLib( 'opcode' );
+includeLib( 'squish' );
+includeLib( 'libvorbis' );
+includeLib( 'libtheora' );
+includeLib( 'libogg' );
+includeLib( 'zlib' );
+includeLib( 'pcre' );
+includeLib( 'collada_dom' );
+includeLib( 'convexDecomp' );
+
+// We need to pick the right physics engine to include.
+global $USE_BULLET_PHYSICS;
+
+/////// Application Config
+beginAppConfig( getGameProjectName(), '{CDECDFF9-E125-523F-87BC-2D89DB971CAB}' );
+
+   // Include only the dedicated crunchy Torque3D goodness
+   echo( "\n   - Loading project code configuration from \"torque3D.conf\"\n");
+   include "torque3D.conf";
+   
+   // Include the project specific source files
+   echo( "\n   - Loading project code configuration from \"projectCode.conf\"\n");
+   include "projectCode.conf";
+
+	addEngineSrcDir( 'main' );
+	
+endAppConfig();
+
+
+
+///////////////// And our solution
+beginSolutionConfig( 'Makefile', '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' );
+
+   addSolutionProjectRef( getGameProjectName() );
+
+   addSolutionProjectRef( 'collada_dom' );
+
+   addSolutionProjectRef( 'libvorbis' );
+   addSolutionProjectRef( 'libtheora' );
+   addSolutionProjectRef( 'libogg' );
+   addSolutionProjectRef( 'ljpeg' );
+   addSolutionProjectRef( 'lmng' );
+   addSolutionProjectRef( 'lpng' );
+   addSolutionProjectRef( 'lungif' );
+   addSolutionProjectRef( 'opcode' );
+   addSolutionProjectRef( 'pcre' );
+   addSolutionProjectRef( 'squish' );
+   addSolutionProjectRef( 'tinyxml' );
+   addSolutionProjectRef( 'zlib' );
+   addSolutionProjectRef( 'convexDecomp' );
+
+endSolutionConfig();
+
+?>

+ 65 - 0
Templates/Empty/buildFiles/config/project.linux_ded.conf

@@ -0,0 +1,65 @@
+<?php
+
+// Set the game project name, this is what your game's exe/dll will be called
+setGameProjectName("Empty");
+
+setPlatform( 'linux_dedicated' );
+
+// Libs
+includeLib( 'mng' );
+includeLib( 'png' );
+includeLib( 'ungif' );
+includeLib( 'jpeg' );
+includeLib( 'tinyxml' );
+includeLib( 'opcode' );
+includeLib( 'squish' );
+includeLib( 'libvorbis' );
+includeLib( 'libtheora' );
+includeLib( 'libogg' );
+includeLib( 'zlib' );
+includeLib( 'pcre' );
+includeLib( 'collada_dom' );
+includeLib( 'convexDecomp' );
+
+// We need to pick the right physics engine to include.
+global $USE_BULLET_PHYSICS;
+
+/////// Application Config
+beginAppConfig( getGameProjectName(), '{CDECDFF9-E125-523F-87BC-2D89DB971CAB}' );
+
+   // Include only the dedicated crunchy Torque3D goodness
+   echo( "\n   - Loading project code configuration from \"torque3D_dedicated.conf\"\n");
+   include "torque3D_dedicated.conf";
+   
+   // Include the project specific source files
+   echo( "\n   - Loading project code configuration from \"projectCode.conf\"\n");
+   include "projectCode.conf";
+
+   addEngineSrcDir( 'main' );
+	
+endAppConfig();
+
+///////////////// And our solution
+beginSolutionConfig( 'Makefile', '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' );
+
+   addSolutionProjectRef( getGameProjectName() );
+
+   addSolutionProjectRef( 'collada_dom' );
+
+   addSolutionProjectRef( 'libvorbis' );
+   addSolutionProjectRef( 'libtheora' );
+   addSolutionProjectRef( 'libogg' );
+   addSolutionProjectRef( 'ljpeg' );
+   addSolutionProjectRef( 'lmng' );
+   addSolutionProjectRef( 'lpng' );
+   addSolutionProjectRef( 'lungif' );
+   addSolutionProjectRef( 'opcode' );
+   addSolutionProjectRef( 'pcre' );
+   addSolutionProjectRef( 'squish' );
+   addSolutionProjectRef( 'tinyxml' );
+   addSolutionProjectRef( 'zlib' );
+   addSolutionProjectRef( 'convexDecomp' );
+
+endSolutionConfig();
+
+?>

+ 96 - 0
Templates/Empty/buildFiles/config/torque3D_dedicated.conf

@@ -0,0 +1,96 @@
+<?php
+        
+    /// Prefs
+    addProjectDefine( 'TORQUE_SHADERGEN' );
+    addProjectDefine( 'TORQUE_UNICODE' );
+    addProjectDefine( 'TORQUE_DEDICATED' );
+
+    /// For OPCODE
+    addProjectDefine( 'BAN_OPCODE_AUTOLINK' );
+    addProjectDefine( 'ICE_NO_DLL' );
+    addProjectDefine( 'TORQUE_OPCODE' );
+    
+    // Additional includes
+    addIncludePath( "../../game/shaders" );
+
+    addLibIncludePath( "lmng" );
+    addLibIncludePath( "lpng" );
+    addLibIncludePath( "ljpeg" );
+    addLibIncludePath( "lungif" );
+    addLibIncludePath( "zlib" );
+    addLibIncludePath( "tinyxml" );
+    addLibIncludePath( "opcode" );
+    addLibIncludePath( "squish" );
+    addLibIncludePath( "libvorbis/include" );
+    addLibIncludePath( "libogg/include" );
+    addLibIncludePath( "libtheora/include" );
+    addLibIncludePath( "convexDecomp" );
+
+    // Modules
+    includeModule( 'Torque3D' );
+    includeModule( 'core' );
+    includeModule( 'T3D' );
+    includeModule( 'advancedLighting' );
+    includeModule( 'basicLighting' );
+    includeModule( 'vorbis' );
+    includeModule( 'theora' );
+    
+    includeModule( 'collada' );
+   
+    // Dependencies
+    addProjectDependency( 'lmng' );
+    addProjectDependency( 'lpng' );
+    addProjectDependency( 'lungif' );
+    addProjectDependency( 'ljpeg' );
+    addProjectDependency( 'zlib' );
+    addProjectDependency( 'tinyxml' );
+    
+    addProjectDependency( 'opcode' );
+    addProjectDependency( 'pcre' );
+    addProjectDependency( 'squish' );
+    addProjectDependency( 'collada_dom' );
+    addProjectDependency( 'libvorbis' );
+    addProjectDependency( 'libogg' );
+    addProjectDependency( 'libtheora' );
+    addProjectDependency( 'convexDecomp' );
+    
+    if ( $USE_BULLET_PHYSICS == true )
+    {
+        includeModule( 'bullet' );
+        addProjectDependency( 'libbullet' );
+    }
+
+    if ( Generator::$platform == "mac" )
+    {    
+        addProjectDefine( '__MACOSX__' );
+        addProjectDefine( 'LTM_DESC' );
+    }
+
+
+    if (Generator::$platform == "win32")
+    {
+        setProjectModuleDefinitionFile('../../' . getLibSrcDir() . 'Torque3D/msvc/torque3d.def');
+
+        addProjectDefine( 'UNICODE' );
+        addProjectDefine( 'INITGUID' );
+        addProjectDefine( '_CRT_SECURE_NO_DEPRECATE' );
+
+        addProjectLibInput('COMCTL32.LIB');
+        addProjectLibInput('COMDLG32.LIB');
+        addProjectLibInput('USER32.LIB');
+        addProjectLibInput('ADVAPI32.LIB');
+        addProjectLibInput('GDI32.LIB');
+        addProjectLibInput('WINMM.LIB');
+        addProjectLibInput('WSOCK32.LIB');
+        addProjectLibInput('vfw32.lib');
+        addProjectLibInput('Imm32.lib');
+        addProjectLibInput('d3d9.lib');
+        addProjectLibInput('d3dx9.lib');
+        addProjectLibInput('DxErr.lib');
+        addProjectLibInput('ole32.lib');
+        addProjectLibInput('shell32.lib');
+        addProjectLibInput('oleaut32.lib');
+        addProjectLibInput('version.lib');
+    }
+
+?>

BIN
Templates/Empty/cleanShaders.command


BIN
Templates/Empty/game/Empty.exe


BIN
Templates/Empty/game/IE Empty Plugin.dll


BIN
Templates/Empty/game/NP Empty Plugin.dll


+ 7 - 0
Templates/Empty/game/scripts/client/serverConnection.cs

@@ -121,6 +121,13 @@ function disconnectedCleanup()
    // Back to the launch screen
    if (isObject( MainMenuGui ))
       Canvas.setContent( MainMenuGui );
+
+   // Before we destroy the client physics world
+   // make sure all ServerConnection objects are deleted.
+   if(isObject(ServerConnection))
+   {
+      ServerConnection.deleteAllObjects();
+   }
    
    // We can now delete the client physics simulation.
    physicsDestroyWorld( "client" );                 

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