Browse Source

Merge remote-tracking branch 'gg/development-3.6' into development

Conflicts:
	Engine/source/T3D/gameFunctions.cpp
Daniel Buckmaster 10 years ago
parent
commit
014b566014

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

@@ -438,7 +438,7 @@ bool AIPlayer::getAIMove(Move *movePtr)
 
 
    // Replicate the trigger state into the move so that
    // Replicate the trigger state into the move so that
    // triggers can be controlled from scripts.
    // triggers can be controlled from scripts.
-   for( S32 i = 0; i < MaxTriggerKeys; i++ )
+   for( U32 i = 0; i < MaxMountedImages; i++ )
       movePtr->trigger[i] = getImageTriggerState(i);
       movePtr->trigger[i] = getImageTriggerState(i);
 
 
    mLastLocation = location;
    mLastLocation = location;
@@ -701,7 +701,7 @@ bool AIPlayer::checkInFoV(GameBase* target, F32 camFov, bool _checkEnabled)
    // projection and box test.
    // projection and box test.
    shapeDir.normalize();
    shapeDir.normalize();
    F32 dot = mDot(shapeDir, camDir);
    F32 dot = mDot(shapeDir, camDir);
-   return (dot > camFov);
+   return (dot > mCos(camFov));
 }
 }
 
 
 DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (NULL, 45.0f, false),
 DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (NULL, 45.0f, false),

+ 4 - 4
Engine/source/T3D/fps/guiShapeNameHud.cpp

@@ -182,9 +182,9 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
    cam.getColumn(3, &camPos);
    cam.getColumn(3, &camPos);
    cam.getColumn(1, &camDir);
    cam.getColumn(1, &camDir);
 
 
-   F32 camFov;
-   conn->getControlCameraFov(&camFov);
-   camFov = mDegToRad(camFov) / 2;
+   F32 camFovCos;
+   conn->getControlCameraFov(&camFovCos);
+   camFovCos = mCos(mDegToRad(camFovCos) / 2);
 
 
    // Visible distance info & name fading
    // Visible distance info & name fading
    F32 visDistance = gClientSceneGraph->getVisibleDistance();
    F32 visDistance = gClientSceneGraph->getVisibleDistance();
@@ -236,7 +236,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
             // projection and box test.
             // projection and box test.
             shapeDir.normalize();
             shapeDir.normalize();
             F32 dot = mDot(shapeDir, camDir);
             F32 dot = mDot(shapeDir, camDir);
-            if (dot < camFov)
+            if (dot < camFovCos)
                continue;
                continue;
 
 
             // Test to see if it's behind something, and we want to
             // Test to see if it's behind something, and we want to

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

@@ -615,7 +615,7 @@ void ExplosionData::packData(BitStream* stream)
    }
    }
    U32 count;
    U32 count;
    for(count = 0; count < EC_NUM_TIME_KEYS; count++)
    for(count = 0; count < EC_NUM_TIME_KEYS; count++)
-      if(times[i] >= 1)
+      if(times[count] >= 1)
          break;
          break;
    count++;
    count++;
    if(count > EC_NUM_TIME_KEYS)
    if(count > EC_NUM_TIME_KEYS)

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

@@ -355,7 +355,7 @@ bool ParticleData::protectedSetSizes( void *object, const char *index, const cha
    U32 i;
    U32 i;
 
 
    if (!index)
    if (!index)
-      i = 0;
+      return (val >= 0.f && val <= MaxParticleSize);
    else
    else
       i = dAtoui(index);
       i = dAtoui(index);
 
 
@@ -371,7 +371,7 @@ bool ParticleData::protectedSetTimes( void *object, const char *index, const cha
    U32 i;
    U32 i;
 
 
    if (!index)
    if (!index)
-      i = 0;
+      return (val >= 0.f && val <= 1.f);
    else
    else
       i = dAtoui(index);
       i = dAtoui(index);
 
 

+ 4 - 4
Engine/source/T3D/fx/particleEmitter.cpp

@@ -1833,22 +1833,22 @@ void ParticleEmitter::setupOriented( Particle *part,
    lVerts->point = start + crossDir;
    lVerts->point = start + crossDir;
    lVerts->color = partCol;
    lVerts->color = partCol;
    // Here and below, we copy UVs from particle datablock's texCoords (oriented)
    // Here and below, we copy UVs from particle datablock's texCoords (oriented)
-   lVerts->texCoord = part->dataBlock->texCoords[0];
+   lVerts->texCoord = part->dataBlock->texCoords[1];
    ++lVerts;
    ++lVerts;
 
 
    lVerts->point = start - crossDir;
    lVerts->point = start - crossDir;
    lVerts->color = partCol;
    lVerts->color = partCol;
-   lVerts->texCoord = part->dataBlock->texCoords[1];
+   lVerts->texCoord = part->dataBlock->texCoords[2];
    ++lVerts;
    ++lVerts;
 
 
    lVerts->point = end - crossDir;
    lVerts->point = end - crossDir;
    lVerts->color = partCol;
    lVerts->color = partCol;
-   lVerts->texCoord = part->dataBlock->texCoords[2];
+   lVerts->texCoord = part->dataBlock->texCoords[3];
    ++lVerts;
    ++lVerts;
 
 
    lVerts->point = end + crossDir;
    lVerts->point = end + crossDir;
    lVerts->color = partCol;
    lVerts->color = partCol;
-   lVerts->texCoord = part->dataBlock->texCoords[3];
+   lVerts->texCoord = part->dataBlock->texCoords[0];
    ++lVerts;
    ++lVerts;
 }
 }
 
 

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

@@ -228,7 +228,7 @@ void GameUpdateCameraFov()
       F32 delta = time - CameraAndFOV::sLastCameraUpdateTime;
       F32 delta = time - CameraAndFOV::sLastCameraUpdateTime;
 
 
       // snap zoom?
       // snap zoom?
-      if((CameraAndFOV::sZoomSpeed == 0) || (delta <= 0.f))
+      if((CameraAndFOV::sZoomSpeed == 0) || (delta <= 0.0f))
          CameraAndFOV::sCameraFov = CameraAndFOV::sTargetFov;
          CameraAndFOV::sCameraFov = CameraAndFOV::sTargetFov;
       else
       else
       {
       {

+ 27 - 37
Engine/source/T3D/lightFlareData.cpp

@@ -26,16 +26,18 @@
 #include "core/stream/bitStream.h"
 #include "core/stream/bitStream.h"
 #include "console/engineAPI.h"
 #include "console/engineAPI.h"
 #include "lighting/lightInfo.h"
 #include "lighting/lightInfo.h"
+#include "lighting/lightQuery.h"
 #include "math/mathUtils.h"
 #include "math/mathUtils.h"
 #include "math/mathIO.h"
 #include "math/mathIO.h"
 #include "scene/sceneRenderState.h"
 #include "scene/sceneRenderState.h"
 #include "gfx/gfxOcclusionQuery.h"
 #include "gfx/gfxOcclusionQuery.h"
 #include "gfx/gfxDrawUtil.h"
 #include "gfx/gfxDrawUtil.h"
+#include "gfx/gfxTextureManager.h"
 #include "renderInstance/renderPassManager.h"
 #include "renderInstance/renderPassManager.h"
 #include "T3D/gameBase/gameConnection.h"
 #include "T3D/gameBase/gameConnection.h"
 #include "T3D/gameBase/processList.h"
 #include "T3D/gameBase/processList.h"
 #include "collision/collision.h"
 #include "collision/collision.h"
-
+#include "lighting/lightManager.h"
 
 
 const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
 const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
                                     ShapeBaseObjectType |
                                     ShapeBaseObjectType |
@@ -45,8 +47,6 @@ const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
 
 
 LightFlareState::~LightFlareState()
 LightFlareState::~LightFlareState()
 {
 {
-   delete occlusionQuery;
-   delete fullPixelQuery;
 }
 }
 
 
 void LightFlareState::clear()
 void LightFlareState::clear()
@@ -59,8 +59,6 @@ void LightFlareState::clear()
    lightInfo = NULL;
    lightInfo = NULL;
    worldRadius = -1.0f;
    worldRadius = -1.0f;
    occlusion = -1.0f;
    occlusion = -1.0f;
-   occlusionQuery = NULL;
-   fullPixelQuery = NULL;
 }
 }
 
 
 Point3F LightFlareData::sBasePoints[] =
 Point3F LightFlareData::sBasePoints[] =
@@ -296,47 +294,39 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
    // for one-shot initialization of LightFlareState
    // for one-shot initialization of LightFlareState
    if ( useOcclusionQuery )
    if ( useOcclusionQuery )
    {
    {
-      if ( flareState->occlusionQuery == NULL )
-         flareState->occlusionQuery = GFX->createOcclusionQuery();
-      if ( flareState->fullPixelQuery == NULL )
-         flareState->fullPixelQuery = GFX->createOcclusionQuery();
-
       // Always treat light as onscreen if using HOQ
       // Always treat light as onscreen if using HOQ
       // it will be faded out if offscreen anyway.
       // it will be faded out if offscreen anyway.
       onScreen = true;
       onScreen = true;
-
-      // NOTE: These queries frame lock us as we block to get the
-      // results.  This is ok as long as long as we're not too GPU
-      // bound... else we waste CPU time here waiting for it when
-      // we could have been doing other CPU work instead.
+	  needsRaycast = false;
 
 
       // Test the hardware queries for rendered pixels.
       // Test the hardware queries for rendered pixels.
       U32 pixels = 0, fullPixels = 0;
       U32 pixels = 0, fullPixels = 0;
-      GFXOcclusionQuery::OcclusionQueryStatus status = flareState->occlusionQuery->getStatus( true, &pixels );
-      flareState->fullPixelQuery->getStatus( true, &fullPixels );
-      if ( status != GFXOcclusionQuery::Occluded && fullPixels != 0 )
+      GFXOcclusionQuery::OcclusionQueryStatus status;
+      flareState->occlusionQuery.getLastStatus( false, &status, &pixels );      
+      flareState->fullPixelQuery.getLastStatus( false, NULL, &fullPixels );
+      
+      if ( status == GFXOcclusionQuery::NotOccluded && fullPixels != 0 )
          *outOcclusionFade = mClampF( (F32)pixels / (F32)fullPixels, 0.0f, 1.0f );
          *outOcclusionFade = mClampF( (F32)pixels / (F32)fullPixels, 0.0f, 1.0f );
 
 
-      // If we got a result then we don't need to fallback to the raycast.
-      if ( status != GFXOcclusionQuery::Unset )
-         needsRaycast = false;
-
-      // Setup the new queries.
-      RenderPassManager *rpm = state->getRenderPass();
-      OccluderRenderInst *ri = rpm->allocInst<OccluderRenderInst>();   
-      ri->type = RenderPassManager::RIT_Occluder;
-      ri->query = flareState->occlusionQuery;   
-      ri->query2 = flareState->fullPixelQuery;
-      ri->isSphere = true;
-      ri->position = lightPos;
-      if ( isVectorLight && flareState->worldRadius > 0.0f )         
-         ri->scale.set( flareState->worldRadius );
-      else
-         ri->scale.set( mOcclusionRadius );
-      ri->orientation = rpm->allocUniqueXform( lightInfo->getTransform() );         
+        if( !flareState->occlusionQuery.isWaiting() )
+        {
+            // Setup the new queries.
+            RenderPassManager *rpm = state->getRenderPass();
+            OccluderRenderInst *ri = rpm->allocInst<OccluderRenderInst>();   
+            ri->type = RenderPassManager::RIT_Occluder;
+            ri->query = flareState->occlusionQuery.getQuery();
+            ri->query2 = flareState->fullPixelQuery.getQuery();
+            ri->isSphere = true;
+            ri->position = lightPos;
+            if ( isVectorLight && flareState->worldRadius > 0.0f )         
+                ri->scale.set( flareState->worldRadius );
+            else
+                ri->scale.set( mOcclusionRadius );
+            ri->orientation = rpm->allocUniqueXform( lightInfo->getTransform() );         
       
       
-      // Submit the queries.
-      state->getRenderPass()->addInst( ri );
+            // Submit the queries.
+            state->getRenderPass()->addInst( ri );
+        }
    }
    }
 
 
    const Point3F &camPos = state->getCameraPosition();
    const Point3F &camPos = state->getCameraPosition();

+ 5 - 3
Engine/source/T3D/lightFlareData.h

@@ -41,12 +41,14 @@
 #ifndef _GFXSTATEBLOCK_H_
 #ifndef _GFXSTATEBLOCK_H_
 #include "gfx/gfxStateBlock.h"
 #include "gfx/gfxStateBlock.h"
 #endif
 #endif
+#ifndef _GFXOCCLUSIONQUERY_H_
+#include "gfx/gfxOcclusionQuery.h"
+#endif
 
 
 class LightInfo;
 class LightInfo;
 struct ObjectRenderInst;
 struct ObjectRenderInst;
 class SceneRenderState;
 class SceneRenderState;
 class BaseMatInstance;
 class BaseMatInstance;
-class GFXOcclusionQuery;
 
 
 struct LightFlareState
 struct LightFlareState
 {  
 {  
@@ -65,8 +67,8 @@ struct LightFlareState
    bool visible;   
    bool visible;   
    F32 occlusion;
    F32 occlusion;
    GFXVertexBufferHandle<GFXVertexPCT> vertBuffer;   
    GFXVertexBufferHandle<GFXVertexPCT> vertBuffer;   
-   GFXOcclusionQuery *occlusionQuery;
-   GFXOcclusionQuery *fullPixelQuery;   
+   GFXOcclusionQueryHandle occlusionQuery;
+   GFXOcclusionQueryHandle fullPixelQuery;
 };
 };
 
 
 class LightFlareData : public SimDataBlock
 class LightFlareData : public SimDataBlock

+ 6 - 3
Engine/source/T3D/player.cpp

@@ -6152,13 +6152,16 @@ U32 Player::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
          stream->writeInt((S32)len, 13);
          stream->writeInt((S32)len, 13);
       }
       }
       stream->writeFloat(mRot.z / M_2PI_F, 7);
       stream->writeFloat(mRot.z / M_2PI_F, 7);
-      stream->writeSignedFloat(mHead.x / mDataBlock->maxLookAngle, 6);
+      stream->writeSignedFloat(mHead.x / (mDataBlock->maxLookAngle - mDataBlock->minLookAngle), 6);
       stream->writeSignedFloat(mHead.z / mDataBlock->maxFreelookAngle, 6);
       stream->writeSignedFloat(mHead.z / mDataBlock->maxFreelookAngle, 6);
       delta.move.pack(stream);
       delta.move.pack(stream);
       stream->writeFlag(!(mask & NoWarpMask));
       stream->writeFlag(!(mask & NoWarpMask));
    }
    }
    // Ghost need energy to predict reliably
    // Ghost need energy to predict reliably
-   stream->writeFloat(getEnergyLevel() / mDataBlock->maxEnergy,EnergyLevelBits);
+   if (mDataBlock->maxEnergy > 0.f)
+      stream->writeFloat(getEnergyLevel() / mDataBlock->maxEnergy, EnergyLevelBits);
+   else
+      stream->writeFloat(0.f, EnergyLevelBits);
    return retMask;
    return retMask;
 }
 }
 
 
@@ -6250,7 +6253,7 @@ void Player::unpackUpdate(NetConnection *con, BitStream *stream)
       
       
       rot.y = rot.x = 0.0f;
       rot.y = rot.x = 0.0f;
       rot.z = stream->readFloat(7) * M_2PI_F;
       rot.z = stream->readFloat(7) * M_2PI_F;
-      mHead.x = stream->readSignedFloat(6) * mDataBlock->maxLookAngle;
+      mHead.x = stream->readSignedFloat(6) * (mDataBlock->maxLookAngle - mDataBlock->minLookAngle);
       mHead.z = stream->readSignedFloat(6) * mDataBlock->maxFreelookAngle;
       mHead.z = stream->readSignedFloat(6) * mDataBlock->maxFreelookAngle;
       delta.move.unpack(stream);
       delta.move.unpack(stream);
 
 

+ 1 - 42
Engine/source/T3D/shapeBase.cpp

@@ -940,8 +940,6 @@ ShapeBase::ShapeBase()
 
 
    for (i = 0; i < MaxTriggerKeys; i++)
    for (i = 0; i < MaxTriggerKeys; i++)
       mTrigger[i] = false;
       mTrigger[i] = false;
-
-   mWeaponCamShake = NULL;
 }
 }
 
 
 
 
@@ -1063,15 +1061,7 @@ void ShapeBase::onRemove()
 
 
    if ( isClientObject() )   
    if ( isClientObject() )   
    {
    {
-      mCubeReflector.unregisterReflector();      
-
-      if ( mWeaponCamShake )
-      {
-         if ( mWeaponCamShake->isAdded )
-            gCamFXMgr.removeFX( mWeaponCamShake );
-
-         SAFE_DELETE( mWeaponCamShake );
-      }
+      mCubeReflector.unregisterReflector();
    }
    }
 }
 }
 
 
@@ -3161,40 +3151,9 @@ void ShapeBase::unpackUpdate(NetConnection *con, BitStream *stream)
                {
                {
                   if ( imageData->lightType == ShapeBaseImageData::WeaponFireLight )                     
                   if ( imageData->lightType == ShapeBaseImageData::WeaponFireLight )                     
                      image.lightStart = Sim::getCurrentTime();                     
                      image.lightStart = Sim::getCurrentTime();                     
-                  
-                  // HACK: Only works properly if you are in control
-                  // of the one and only shapeBase object in the scene
-                  // which fires an image that uses camera shake.
-                  if ( imageData->shakeCamera )
-                  {
-                     if ( !mWeaponCamShake )
-                     {
-                        mWeaponCamShake = new CameraShake();
-                        mWeaponCamShake->remoteControlled = true;
-                     }
-
-                     mWeaponCamShake->init();
-                     mWeaponCamShake->setFrequency( imageData->camShakeFreq );
-                     mWeaponCamShake->setAmplitude( imageData->camShakeAmp );  
-                     
-                     if ( !mWeaponCamShake->isAdded )
-                     {
-                        gCamFXMgr.addFX( mWeaponCamShake );
-                        mWeaponCamShake->isAdded = true;
-                     }
-                  }
                }
                }
                
                
                updateImageState(i,0);
                updateImageState(i,0);
-
-               if ( !image.triggerDown && !image.altTriggerDown )
-               {
-                  if ( mWeaponCamShake && mWeaponCamShake->isAdded )
-                  {
-                     gCamFXMgr.removeFX( mWeaponCamShake );
-                     mWeaponCamShake->isAdded = false;
-                  }
-               }
             }
             }
             else
             else
             {               
             {               

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

@@ -324,7 +324,10 @@ struct ShapeBaseImageData: public GameBaseData {
    /// @{
    /// @{
    bool              shakeCamera;
    bool              shakeCamera;
    VectorF           camShakeFreq;
    VectorF           camShakeFreq;
-   VectorF           camShakeAmp;         
+   VectorF           camShakeAmp;
+   F32               camShakeDuration;
+   F32               camShakeRadius;
+   F32               camShakeFalloff;
    /// @}
    /// @}
 
 
    /// Maximum number of sounds this image can play at a time.
    /// Maximum number of sounds this image can play at a time.
@@ -903,9 +906,6 @@ protected:
 
 
    bool mFlipFadeVal;
    bool mFlipFadeVal;
 
 
-   /// Camera shake caused by weapon fire.
-   CameraShake *mWeaponCamShake;
-
  public:
  public:
 
 
    /// @name Collision Notification
    /// @name Collision Notification
@@ -1101,6 +1101,7 @@ protected:
    virtual void onImageAnimThreadChange(U32 imageSlot, S32 imageShapeIndex, ShapeBaseImageData::StateData* lastState, const char* anim, F32 pos, F32 timeScale, bool reset=false);
    virtual void onImageAnimThreadChange(U32 imageSlot, S32 imageShapeIndex, ShapeBaseImageData::StateData* lastState, const char* anim, F32 pos, F32 timeScale, bool reset=false);
    virtual void onImageAnimThreadUpdate(U32 imageSlot, S32 imageShapeIndex, F32 dt);
    virtual void onImageAnimThreadUpdate(U32 imageSlot, S32 imageShapeIndex, F32 dt);
    virtual void ejectShellCasing( U32 imageSlot );
    virtual void ejectShellCasing( U32 imageSlot );
+   virtual void shakeCamera( U32 imageSlot );
    virtual void updateDamageLevel();
    virtual void updateDamageLevel();
    virtual void updateDamageState();
    virtual void updateDamageState();
    virtual void onImpact(SceneObject* obj, VectorF vec);
    virtual void onImpact(SceneObject* obj, VectorF vec);

+ 80 - 5
Engine/source/T3D/shapeImage.cpp

@@ -44,6 +44,7 @@
 #include "sfx/sfxTypes.h"
 #include "sfx/sfxTypes.h"
 #include "scene/sceneManager.h"
 #include "scene/sceneManager.h"
 #include "core/stream/fileStream.h"
 #include "core/stream/fileStream.h"
+#include "T3D/fx/cameraFXMgr.h"
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 
 
@@ -297,6 +298,9 @@ ShapeBaseImageData::ShapeBaseImageData()
    shakeCamera = false;
    shakeCamera = false;
    camShakeFreq = Point3F::Zero;
    camShakeFreq = Point3F::Zero;
    camShakeAmp = Point3F::Zero;
    camShakeAmp = Point3F::Zero;
+   camShakeDuration = 1.5f;
+   camShakeRadius = 3.0f;
+   camShakeFalloff = 10.0f;
 }
 }
 
 
 ShapeBaseImageData::~ShapeBaseImageData()
 ShapeBaseImageData::~ShapeBaseImageData()
@@ -739,10 +743,7 @@ void ShapeBaseImageData::initPersistFields()
       "@see lightType");
       "@see lightType");
 
 
    addField( "shakeCamera", TypeBool, Offset(shakeCamera, ShapeBaseImageData),
    addField( "shakeCamera", TypeBool, Offset(shakeCamera, ShapeBaseImageData),
-      "@brief Flag indicating whether the camera should shake when this Image fires.\n\n"
-      "@note Camera shake only works properly if the player is in control of "
-      "the one and only shapeBase object in the scene which fires an Image that "
-      "uses camera shake." );
+      "@brief Flag indicating whether the camera should shake when this Image fires.\n\n" );
 
 
    addField( "camShakeFreq", TypePoint3F, Offset(camShakeFreq, ShapeBaseImageData),
    addField( "camShakeFreq", TypePoint3F, Offset(camShakeFreq, ShapeBaseImageData),
       "@brief Frequency of the camera shaking effect.\n\n"
       "@brief Frequency of the camera shaking effect.\n\n"
@@ -752,6 +753,16 @@ void ShapeBaseImageData::initPersistFields()
       "@brief Amplitude of the camera shaking effect.\n\n"
       "@brief Amplitude of the camera shaking effect.\n\n"
       "@see shakeCamera" );
       "@see shakeCamera" );
 
 
+   addField( "camShakeDuration", TypeF32, Offset(camShakeDuration, ShapeBaseImageData),
+      "Duration (in seconds) to shake the camera." );
+
+   addField( "camShakeRadius", TypeF32, Offset(camShakeRadius, ShapeBaseImageData),
+      "Radial distance that a camera's position must be within relative to the "
+      "center of the explosion to be shaken." );
+
+   addField( "camShakeFalloff", TypeF32, Offset(camShakeFalloff, ShapeBaseImageData),
+      "Falloff value for the camera shake." );
+
    addField( "casing", TYPEID< DebrisData >(), Offset(casing, ShapeBaseImageData),
    addField( "casing", TYPEID< DebrisData >(), Offset(casing, ShapeBaseImageData),
       "@brief DebrisData datablock to use for ejected casings.\n\n"
       "@brief DebrisData datablock to use for ejected casings.\n\n"
       "@see stateEjectShell" );
       "@see stateEjectShell" );
@@ -1028,6 +1039,9 @@ void ShapeBaseImageData::packData(BitStream* stream)
    {      
    {      
       mathWrite( *stream, camShakeFreq );
       mathWrite( *stream, camShakeFreq );
       mathWrite( *stream, camShakeAmp );
       mathWrite( *stream, camShakeAmp );
+      stream->write( camShakeDuration );
+      stream->write( camShakeRadius );
+      stream->write( camShakeFalloff );
    }
    }
 
 
    mathWrite( *stream, shellExitDir );
    mathWrite( *stream, shellExitDir );
@@ -1208,7 +1222,10 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
    if ( shakeCamera )
    if ( shakeCamera )
    {
    {
       mathRead( *stream, &camShakeFreq );
       mathRead( *stream, &camShakeFreq );
-      mathRead( *stream, &camShakeAmp );      
+      mathRead( *stream, &camShakeAmp );
+      stream->read( &camShakeDuration );
+      stream->read( &camShakeRadius );
+      stream->read( &camShakeFalloff );
    }
    }
 
 
    mathRead( *stream, &shellExitDir );
    mathRead( *stream, &shellExitDir );
@@ -2596,6 +2613,10 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
       ejectShellCasing( imageSlot );
       ejectShellCasing( imageSlot );
    }
    }
 
 
+   // Shake camera on client.
+   if (isGhost() && nextStateData.fire && image.dataBlock->shakeCamera) {
+      shakeCamera( imageSlot );
+   }
 
 
    // Server must animate the shape if it is a firestate...
    // Server must animate the shape if it is a firestate...
    if (isServerObject() && (image.dataBlock->state[newState].fire || image.dataBlock->state[newState].altFire))
    if (isServerObject() && (image.dataBlock->state[newState].fire || image.dataBlock->state[newState].altFire))
@@ -3342,3 +3363,57 @@ void ShapeBase::ejectShellCasing( U32 imageSlot )
    else
    else
       casing->init( shellPos, shellVel );
       casing->init( shellPos, shellVel );
 }
 }
+
+void ShapeBase::shakeCamera( U32 imageSlot )
+{
+   MountedImage& image = mMountedImageList[imageSlot];
+   ShapeBaseImageData* imageData = image.dataBlock;
+
+   if (!imageData->shakeCamera)
+      return;
+
+   // Warning: this logic was duplicated from Explosion.
+
+   // first check if explosion is near camera
+   GameConnection* connection = GameConnection::getConnectionToServer();
+   ShapeBase *obj = dynamic_cast<ShapeBase*>(connection->getControlObject());
+
+   bool applyShake = true;
+
+   if (obj)
+   {
+      ShapeBase* cObj = obj;
+      while ((cObj = cObj->getControlObject()) != 0)
+      {
+         if (cObj->useObjsEyePoint())
+         {
+            applyShake = false;
+            break;
+         }
+      }
+   }
+
+   if (applyShake && obj)
+   {
+      VectorF diff;
+      getMuzzlePoint(imageSlot, &diff);
+      diff = obj->getPosition() - diff;
+      F32 dist = diff.len();
+      if (dist < imageData->camShakeRadius)
+      {
+         CameraShake *camShake = new CameraShake;
+         camShake->setDuration(imageData->camShakeDuration);
+         camShake->setFrequency(imageData->camShakeFreq);
+
+         F32 falloff =  dist / imageData->camShakeRadius;
+         falloff = 1.0f + falloff * 10.0f;
+         falloff = 1.0f / (falloff * falloff);
+
+         VectorF shakeAmp = imageData->camShakeAmp * falloff;
+         camShake->setAmplitude(shakeAmp);
+         camShake->setFalloff(imageData->camShakeFalloff);
+         camShake->init();
+         gCamFXMgr.addFX(camShake);
+      }
+   }
+}

+ 2 - 2
Engine/source/app/version.h

@@ -41,10 +41,10 @@
 /// code version, the game name, and which type of game it is (TGB, TGE, TGEA, etc.).
 /// code version, the game name, and which type of game it is (TGB, TGE, TGEA, etc.).
 ///
 ///
 /// Version number is major * 1000 + minor * 100 + revision * 10.
 /// Version number is major * 1000 + minor * 100 + revision * 10.
-#define TORQUE_GAME_ENGINE          3620
+#define TORQUE_GAME_ENGINE          3630
 
 
 /// Human readable engine version string.
 /// Human readable engine version string.
-#define TORQUE_GAME_ENGINE_VERSION_STRING  "3.6.2"
+#define TORQUE_GAME_ENGINE_VERSION_STRING  "3.6.3"
 
 
 /// Gets the engine version number.  The version number is specified as a global in version.cc
 /// Gets the engine version number.  The version number is specified as a global in version.cc
 U32 getVersionNumber();
 U32 getVersionNumber();

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

@@ -1599,8 +1599,7 @@ void SimObject::unlinkNamespaces()
 
 
    // Handle object name.
    // Handle object name.
 
 
-   StringTableEntry objectName = getName();
-   if( objectName && objectName[ 0 ] )
+   if (mNameSpace && mNameSpace->mClassRep == NULL)
       mNameSpace->decRefCountToParent();
       mNameSpace->decRefCountToParent();
 
 
    mNameSpace = NULL;
    mNameSpace = NULL;

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

@@ -666,6 +666,11 @@ void ScatterSky::prepRenderImage( SceneRenderState *state )
       mFlareState.lightMat.identity();
       mFlareState.lightMat.identity();
       mFlareState.lightMat.setPosition( lightPos );
       mFlareState.lightMat.setPosition( lightPos );
 
 
+      F32 dist = ( lightPos - state->getCameraPosition( ) ).len( );
+      F32 coronaScale = 0.5f;
+      F32 screenRadius = GFX->getViewport( ).extent.y * coronaScale * 0.5f;
+      mFlareState.worldRadius = screenRadius * dist / state->getWorldToScreenScale( ).y;
+
       mFlareData->prepRender( state, &mFlareState );
       mFlareData->prepRender( state, &mFlareState );
    }
    }
 
 

+ 1 - 0
Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.cpp

@@ -130,6 +130,7 @@ GFXD3D9OcclusionQuery::OcclusionQueryStatus GFXD3D9OcclusionQuery::getStatus( bo
           //If we're stalled out, proceed with worst-case scenario -BJR
           //If we're stalled out, proceed with worst-case scenario -BJR
           if(GFX->mFrameTime->getElapsedMs()>4)
           if(GFX->mFrameTime->getElapsedMs()>4)
           {
           {
+              this->begin();
               this->end();
               this->end();
               return NotOccluded;
               return NotOccluded;
           }
           }

+ 67 - 0
Engine/source/gfx/gfxOcclusionQuery.h

@@ -82,4 +82,71 @@ public:
    virtual const String describeSelf() const = 0;
    virtual const String describeSelf() const = 0;
 };
 };
 
 
+/// Handle for GFXOcclusionQuery than store last valid state
+class GFXOcclusionQueryHandle
+{
+public:
+
+    GFXOcclusionQueryHandle() 
+        : mLastStatus(GFXOcclusionQuery::Unset), mLastData(0), mQuery(NULL), mWaiting(false) 
+    {}
+
+    ~GFXOcclusionQueryHandle()
+    {
+        SAFE_DELETE(mQuery);
+    }
+
+    bool getLastStatus( bool block, GFXOcclusionQuery::OcclusionQueryStatus *statusPtr = NULL, U32 *data = NULL );
+    GFXOcclusionQuery* getQuery() const { return mQuery; }
+
+    void clearLastStatus()
+    {
+        mLastStatus = GFXOcclusionQuery::Unset;
+        mLastData = 0;
+        mWaiting = false;
+
+        if( !mQuery )
+            return;
+
+        mQuery->begin();
+        mQuery->end();
+    }
+
+    bool isWaiting() const { return mWaiting; }
+protected:
+    GFXOcclusionQuery::OcclusionQueryStatus mLastStatus;
+    U32 mLastData;
+    bool mWaiting;
+    GFXOcclusionQuery *mQuery;
+};
+
+inline bool GFXOcclusionQueryHandle::getLastStatus( bool block, GFXOcclusionQuery::OcclusionQueryStatus *statusPtr, U32 *data )
+{
+    if( !mQuery )
+        mQuery = GFX->createOcclusionQuery();
+
+    GFXOcclusionQuery::OcclusionQueryStatus status = mQuery->getStatus( block, data );
+
+    if( status == GFXOcclusionQuery::Waiting )
+    {
+        mWaiting = true;
+        if( statusPtr )
+            *statusPtr = mLastStatus;
+        if( data )
+            *data = mLastData;
+
+        return true;
+    }
+
+    if( statusPtr )
+        *statusPtr = status;
+
+    mWaiting = false;
+    mLastStatus = status;
+    mLastData = *data;
+
+    return true;
+}
+
+
 #endif // _GFXOCCLUSIONQUERY_H_
 #endif // _GFXOCCLUSIONQUERY_H_

+ 2 - 0
Engine/source/gui/controls/guiTreeViewCtrl.cpp

@@ -1785,6 +1785,8 @@ bool GuiTreeViewCtrl::onWake()
       // make sure it's big enough for both bitmap AND font...
       // make sure it's big enough for both bitmap AND font...
       mItemHeight = getMax((S32)mFont->getHeight(), (S32)mProfile->mBitmapArrayRects[0].extent.y);
       mItemHeight = getMax((S32)mFont->getHeight(), (S32)mProfile->mBitmapArrayRects[0].extent.y);
    }
    }
+   
+   mFlags.set(RebuildVisible);
 
 
    return true;
    return true;
 }
 }

+ 3 - 0
Engine/source/lighting/common/projectedShadow.cpp

@@ -230,6 +230,9 @@ bool ProjectedShadow::_updateDecal( const SceneRenderState *state )
       lightCount++;
       lightCount++;
    }
    }
 
 
+   if (mShapeBase)
+      fade *= mShapeBase->getFadeVal();
+
    lightDir.normalize();
    lightDir.normalize();
    
    
    // No light... no shadow.
    // No light... no shadow.

+ 6 - 0
Engine/source/materials/matInstance.cpp

@@ -290,6 +290,12 @@ bool MatInstance::init( const FeatureSet &features,
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 bool MatInstance::reInit()
 bool MatInstance::reInit()
 {
 {
+   if (!mVertexFormat)
+   {
+      mIsValid = false;
+      return mIsValid;
+   }
+
    SAFE_DELETE(mProcessedMaterial);
    SAFE_DELETE(mProcessedMaterial);
    deleteAllHooks();
    deleteAllHooks();
    mIsValid = processMaterial();
    mIsValid = processMaterial();

+ 1 - 1
Engine/source/materials/processedMaterial.h

@@ -73,7 +73,7 @@ public:
    /// The cubemap to use when the texture type is
    /// The cubemap to use when the texture type is
    /// set to Material::Cube.
    /// set to Material::Cube.
    /// @see mTexType
    /// @see mTexType
-   GFXCubemap *mCubeMap;
+   GFXCubemapHandle mCubeMap;
 
 
    U32 mNumTex;
    U32 mNumTex;
 
 

+ 4 - 3
Engine/source/math/mPlane.h

@@ -383,9 +383,10 @@ inline PlaneF::Side PlaneF::whichSide( const OrientedBox3F& obb ) const
    // Project the box onto the line defined by the plane center and normal.
    // Project the box onto the line defined by the plane center and normal.
    // See "3D Game Engine Design" chapter 4.3.2.
    // See "3D Game Engine Design" chapter 4.3.2.
 
 
-   const F32 r = obb.getHalfExtents().x * mFabs( mDot( obb.getAxis( 0 ), *this ) ) +
-                 obb.getHalfExtents().y * mFabs( mDot( obb.getAxis( 1 ), *this ) ) +
-                 obb.getHalfExtents().z * mFabs( mDot( obb.getAxis( 2 ), *this ) );
+   Point3F mObbHalf = obb.getHalfExtents();
+   const F32 r = mObbHalf.x * mFabs( mDot( obb.getAxis( 0 ), *this ) ) +
+                 mObbHalf.y * mFabs( mDot( obb.getAxis( 1 ), *this ) ) +
+                 mObbHalf.z * mFabs( mDot( obb.getAxis( 2 ), *this ) );
 
 
    const F32 dist = distToPlane( obb.getCenter() );
    const F32 dist = distToPlane( obb.getCenter() );
    if( dist > r )
    if( dist > r )

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

@@ -458,7 +458,7 @@ U32 PlaneSet< T >::clipPolygon( const Point3F* inVertices, U32 inNumVertices, Po
       // to indicate we haven't clipped anything.
       // to indicate we haven't clipped anything.
 
 
       if( !numClippedPolygonVertices )
       if( !numClippedPolygonVertices )
-         return false;
+         return 0;
 
 
       // On first iteration, replace the inVertices with the
       // On first iteration, replace the inVertices with the
       // outVertices buffer.
       // outVertices buffer.

+ 2 - 2
Engine/source/platform/nativeDialogs/msgBox.h

@@ -32,7 +32,7 @@
 
 
 enum MBButtons
 enum MBButtons
 {
 {
-   MBOk,
+   MBOk = 0,
    MBOkCancel,
    MBOkCancel,
    MBRetryCancel,
    MBRetryCancel,
    MBSaveDontSave,
    MBSaveDontSave,
@@ -42,7 +42,7 @@ enum MBButtons
 
 
 enum MBIcons
 enum MBIcons
 {
 {
-   MIWarning,
+   MIWarning = 0,
    MIInformation,
    MIInformation,
    MIQuestion,
    MIQuestion,
    MIStop,
    MIStop,

+ 7 - 2
Engine/source/shaderGen/HLSL/depthHLSL.cpp

@@ -25,7 +25,7 @@
 
 
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureData.h"
 #include "materials/materialFeatureData.h"
-
+#include "terrain/terrFeatureTypes.h"
 
 
 void EyeSpaceDepthOutHLSL::processVert(   Vector<ShaderComponent*> &componentList, 
 void EyeSpaceDepthOutHLSL::processVert(   Vector<ShaderComponent*> &componentList, 
                                           const MaterialFeatureData &fd )
                                           const MaterialFeatureData &fd )
@@ -85,7 +85,12 @@ void EyeSpaceDepthOutHLSL::processPix( Vector<ShaderComponent*> &componentList,
    LangElement *depthOutDecl = new DecOp( depthOut );
    LangElement *depthOutDecl = new DecOp( depthOut );
 
 
    meta->addStatement( new GenOp( "#ifndef CUBE_SHADOW_MAP\r\n" ) );
    meta->addStatement( new GenOp( "#ifndef CUBE_SHADOW_MAP\r\n" ) );
-   meta->addStatement( new GenOp( "   @ = dot(@, (@.xyz / @.w));\r\n", depthOutDecl, vEye, wsEyeVec, wsEyeVec ) );
+
+   if (fd.features.hasFeature(MFT_TerrainBaseMap))
+      meta->addStatement(new GenOp("   @ =min(0.9999, dot(@, (@.xyz / @.w)));\r\n", depthOutDecl, vEye, wsEyeVec, wsEyeVec));
+   else
+      meta->addStatement(new GenOp("   @ = dot(@, (@.xyz / @.w));\r\n", depthOutDecl, vEye, wsEyeVec, wsEyeVec));
+
    meta->addStatement( new GenOp( "#else\r\n" ) );
    meta->addStatement( new GenOp( "#else\r\n" ) );
 
 
    Var *farDist = (Var*)Var::find( "oneOverFarplane" );
    Var *farDist = (Var*)Var::find( "oneOverFarplane" );

+ 3 - 3
README.md

@@ -1,4 +1,4 @@
-Torque 3D v3.6.2
+Torque 3D v3.6.3
 ================
 ================
 
 
 MIT Licensed Open Source version of [Torque 3D](http://www.garagegames.com/products/torque-3d) from [GarageGames](http://www.garagegames.com)
 MIT Licensed Open Source version of [Torque 3D](http://www.garagegames.com/products/torque-3d) from [GarageGames](http://www.garagegames.com)
@@ -23,7 +23,7 @@ In addition to GitHub we also have a couple of pre-packaged files for you to dow
  
  
 * [Torque 3D 3.6 Full template](http://mit.garagegames.com/Torque3D-3-6-1-FullTemplate.zip), which contains precompiled binaries.
 * [Torque 3D 3.6 Full template](http://mit.garagegames.com/Torque3D-3-6-1-FullTemplate.zip), which contains precompiled binaries.
 * [Complete Torque 3D 3.6 zip package](http://mit.garagegames.com/Torque3D-3-6-1.zip) containing the contents of this repository.
 * [Complete Torque 3D 3.6 zip package](http://mit.garagegames.com/Torque3D-3-6-1.zip) containing the contents of this repository.
-* [Windows binaries for 3.6.2](https://github.com/GarageGames/Torque3D/releases/tag/v3.6.2) which you can drop into your existing script projects.
+* [Windows binaries for 3.6.3](https://github.com/GarageGames/Torque3D/releases/tag/v3.6.3) which you can drop into your existing script projects.
 * [Torque 3D Project Manager v2.1](http://mit.garagegames.com/T3DProjectManager-2-1.zip) on its own for use in your T3D forks.
 * [Torque 3D Project Manager v2.1](http://mit.garagegames.com/T3DProjectManager-2-1.zip) on its own for use in your T3D forks.
 
 
 If you're looking for an older release see the [Torque 3D Archive](https://github.com/GarageGames/Torque3D/wiki/Torque-3D-Archive)
 If you're looking for an older release see the [Torque 3D Archive](https://github.com/GarageGames/Torque3D/wiki/Torque-3D-Archive)
@@ -137,4 +137,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 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
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
+IN THE SOFTWARE.

+ 1 - 1
Templates/Full/game/art/datablocks/player.cs

@@ -482,7 +482,7 @@ datablock DebrisData( PlayerDebris )
 datablock PlayerData(DefaultPlayerData)
 datablock PlayerData(DefaultPlayerData)
 {
 {
    renderFirstPerson = false;
    renderFirstPerson = false;
-
+   firstPersonShadows = true;
    computeCRC = false;
    computeCRC = false;
 
 
    // Third person shape
    // Third person shape

+ 4 - 3
Templates/Full/game/art/datablocks/weapons/Ryder.cs

@@ -192,9 +192,9 @@ datablock ShapeBaseImageData(RyderWeaponImage)
    lightBrightness = 2;
    lightBrightness = 2;
 
 
    // Shake camera while firing.
    // Shake camera while firing.
-   shakeCamera = false;
-   camShakeFreq = "0 0 0";
-   camShakeAmp = "0 0 0";
+   shakeCamera = "1";
+   camShakeFreq = "10 10 10";
+   camShakeAmp = "5 5 5";
 
 
    // Images have a state system which controls how the animations
    // Images have a state system which controls how the animations
    // are run, which sounds are played, script callbacks, etc. This
    // are run, which sounds are played, script callbacks, etc. This
@@ -361,4 +361,5 @@ datablock ShapeBaseImageData(RyderWeaponImage)
    stateSequenceTransitionOut[13]   = true;
    stateSequenceTransitionOut[13]   = true;
    stateAllowImageChange[13]        = false;
    stateAllowImageChange[13]        = false;
    stateSequence[13]                = "sprint";
    stateSequence[13]                = "sprint";
+   camShakeDuration = "0.2";
 };
 };

+ 4 - 1
Templates/Full/game/scripts/server/aiPlayer.cs

@@ -212,7 +212,10 @@ function AIPlayer::singleShot(%this)
    // The shooting delay is used to pulse the trigger
    // The shooting delay is used to pulse the trigger
    %this.setImageTrigger(0, true);
    %this.setImageTrigger(0, true);
    %this.setImageTrigger(0, false);
    %this.setImageTrigger(0, false);
-   %this.trigger = %this.schedule(%this.shootingDelay, singleShot);
+   %delay = %this.getDataBlock().shootingDelay;
+   if (%delay $= "")
+      %delay = 1000;
+   %this.trigger = %this.schedule(%delay, singleShot);
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------