Browse Source

Merge pull request #1087 from GarageGames/development-3.6

Version 3.6.3
Daniel Buckmaster 10 years ago
parent
commit
cda70972d1

+ 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
    // 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);
 
    mLastLocation = location;
@@ -703,7 +703,7 @@ bool AIPlayer::checkInFoV(GameBase* target, F32 camFov, bool _checkEnabled)
    // projection and box test.
    shapeDir.normalize();
    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),

+ 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(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
    F32 visDistance = gClientSceneGraph->getVisibleDistance();
@@ -236,7 +236,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
             // projection and box test.
             shapeDir.normalize();
             F32 dot = mDot(shapeDir, camDir);
-            if (dot < camFov)
+            if (dot < camFovCos)
                continue;
 
             // Test to see if it's behind something, and we want to

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

@@ -606,7 +606,7 @@ void ExplosionData::packData(BitStream* stream)
    }
    U32 count;
    for(count = 0; count < EC_NUM_TIME_KEYS; count++)
-      if(times[i] >= 1)
+      if(times[count] >= 1)
          break;
    count++;
    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;
 
    if (!index)
-      i = 0;
+      return (val >= 0.f && val <= MaxParticleSize);
    else
       i = dAtoui(index);
 
@@ -371,7 +371,7 @@ bool ParticleData::protectedSetTimes( void *object, const char *index, const cha
    U32 i;
 
    if (!index)
-      i = 0;
+      return (val >= 0.f && val <= 1.f);
    else
       i = dAtoui(index);
 

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

@@ -1825,22 +1825,22 @@ void ParticleEmitter::setupOriented( Particle *part,
    lVerts->point = start + crossDir;
    lVerts->color = partCol;
    // 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->point = start - crossDir;
    lVerts->color = partCol;
-   lVerts->texCoord = part->dataBlock->texCoords[1];
+   lVerts->texCoord = part->dataBlock->texCoords[2];
    ++lVerts;
 
    lVerts->point = end - crossDir;
    lVerts->color = partCol;
-   lVerts->texCoord = part->dataBlock->texCoords[2];
+   lVerts->texCoord = part->dataBlock->texCoords[3];
    ++lVerts;
 
    lVerts->point = end + crossDir;
    lVerts->color = partCol;
-   lVerts->texCoord = part->dataBlock->texCoords[3];
+   lVerts->texCoord = part->dataBlock->texCoords[0];
    ++lVerts;
 }
 

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

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

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

@@ -26,16 +26,18 @@
 #include "core/stream/bitStream.h"
 #include "console/engineAPI.h"
 #include "lighting/lightInfo.h"
+#include "lighting/lightQuery.h"
 #include "math/mathUtils.h"
 #include "math/mathIO.h"
 #include "scene/sceneRenderState.h"
 #include "gfx/gfxOcclusionQuery.h"
 #include "gfx/gfxDrawUtil.h"
+#include "gfx/gfxTextureManager.h"
 #include "renderInstance/renderPassManager.h"
 #include "T3D/gameBase/gameConnection.h"
 #include "T3D/gameBase/processList.h"
 #include "collision/collision.h"
-
+#include "lighting/lightManager.h"
 
 const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
                                     ShapeBaseObjectType |
@@ -45,8 +47,6 @@ const U32 LightFlareData::LosMask = STATIC_COLLISION_TYPEMASK |
 
 LightFlareState::~LightFlareState()
 {
-   delete occlusionQuery;
-   delete fullPixelQuery;
 }
 
 void LightFlareState::clear()
@@ -59,8 +59,6 @@ void LightFlareState::clear()
    lightInfo = NULL;
    worldRadius = -1.0f;
    occlusion = -1.0f;
-   occlusionQuery = NULL;
-   fullPixelQuery = NULL;
 }
 
 Point3F LightFlareData::sBasePoints[] =
@@ -296,47 +294,39 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
    // for one-shot initialization of LightFlareState
    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
       // it will be faded out if offscreen anyway.
       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.
       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 );
 
-      // 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();

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

@@ -41,12 +41,14 @@
 #ifndef _GFXSTATEBLOCK_H_
 #include "gfx/gfxStateBlock.h"
 #endif
+#ifndef _GFXOCCLUSIONQUERY_H_
+#include "gfx/gfxOcclusionQuery.h"
+#endif
 
 class LightInfo;
 struct ObjectRenderInst;
 class SceneRenderState;
 class BaseMatInstance;
-class GFXOcclusionQuery;
 
 struct LightFlareState
 {  
@@ -65,8 +67,8 @@ struct LightFlareState
    bool visible;   
    F32 occlusion;
    GFXVertexBufferHandle<GFXVertexPCT> vertBuffer;   
-   GFXOcclusionQuery *occlusionQuery;
-   GFXOcclusionQuery *fullPixelQuery;   
+   GFXOcclusionQueryHandle occlusionQuery;
+   GFXOcclusionQueryHandle fullPixelQuery;
 };
 
 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->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);
       delta.move.pack(stream);
       stream->writeFlag(!(mask & NoWarpMask));
    }
    // 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;
 }
 
@@ -6250,7 +6253,7 @@ void Player::unpackUpdate(NetConnection *con, BitStream *stream)
       
       rot.y = rot.x = 0.0f;
       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;
       delta.move.unpack(stream);
 

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

@@ -940,8 +940,6 @@ ShapeBase::ShapeBase()
 
    for (i = 0; i < MaxTriggerKeys; i++)
       mTrigger[i] = false;
-
-   mWeaponCamShake = NULL;
 }
 
 
@@ -1063,15 +1061,7 @@ void ShapeBase::onRemove()
 
    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 )                     
                      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);
-
-               if ( !image.triggerDown && !image.altTriggerDown )
-               {
-                  if ( mWeaponCamShake && mWeaponCamShake->isAdded )
-                  {
-                     gCamFXMgr.removeFX( mWeaponCamShake );
-                     mWeaponCamShake->isAdded = false;
-                  }
-               }
             }
             else
             {               

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

@@ -324,7 +324,10 @@ struct ShapeBaseImageData: public GameBaseData {
    /// @{
    bool              shakeCamera;
    VectorF           camShakeFreq;
-   VectorF           camShakeAmp;         
+   VectorF           camShakeAmp;
+   F32               camShakeDuration;
+   F32               camShakeRadius;
+   F32               camShakeFalloff;
    /// @}
 
    /// Maximum number of sounds this image can play at a time.
@@ -903,9 +906,6 @@ protected:
 
    bool mFlipFadeVal;
 
-   /// Camera shake caused by weapon fire.
-   CameraShake *mWeaponCamShake;
-
  public:
 
    /// @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 onImageAnimThreadUpdate(U32 imageSlot, S32 imageShapeIndex, F32 dt);
    virtual void ejectShellCasing( U32 imageSlot );
+   virtual void shakeCamera( U32 imageSlot );
    virtual void updateDamageLevel();
    virtual void updateDamageState();
    virtual void onImpact(SceneObject* obj, VectorF vec);

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

@@ -44,6 +44,7 @@
 #include "sfx/sfxTypes.h"
 #include "scene/sceneManager.h"
 #include "core/stream/fileStream.h"
+#include "T3D/fx/cameraFXMgr.h"
 
 //----------------------------------------------------------------------------
 
@@ -297,6 +298,9 @@ ShapeBaseImageData::ShapeBaseImageData()
    shakeCamera = false;
    camShakeFreq = Point3F::Zero;
    camShakeAmp = Point3F::Zero;
+   camShakeDuration = 1.5f;
+   camShakeRadius = 3.0f;
+   camShakeFalloff = 10.0f;
 }
 
 ShapeBaseImageData::~ShapeBaseImageData()
@@ -739,10 +743,7 @@ void ShapeBaseImageData::initPersistFields()
       "@see lightType");
 
    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),
       "@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"
       "@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),
       "@brief DebrisData datablock to use for ejected casings.\n\n"
       "@see stateEjectShell" );
@@ -1028,6 +1039,9 @@ void ShapeBaseImageData::packData(BitStream* stream)
    {      
       mathWrite( *stream, camShakeFreq );
       mathWrite( *stream, camShakeAmp );
+      stream->write( camShakeDuration );
+      stream->write( camShakeRadius );
+      stream->write( camShakeFalloff );
    }
 
    mathWrite( *stream, shellExitDir );
@@ -1208,7 +1222,10 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
    if ( shakeCamera )
    {
       mathRead( *stream, &camShakeFreq );
-      mathRead( *stream, &camShakeAmp );      
+      mathRead( *stream, &camShakeAmp );
+      stream->read( &camShakeDuration );
+      stream->read( &camShakeRadius );
+      stream->read( &camShakeFalloff );
    }
 
    mathRead( *stream, &shellExitDir );
@@ -2596,6 +2613,10 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
       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...
    if (isServerObject() && (image.dataBlock->state[newState].fire || image.dataBlock->state[newState].altFire))
@@ -3342,3 +3363,57 @@ void ShapeBase::ejectShellCasing( U32 imageSlot )
 
    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.).
 ///
 /// Version number is major * 1000 + minor * 100 + revision * 10.
-#define TORQUE_GAME_ENGINE          3620
+#define TORQUE_GAME_ENGINE          3630
 
 /// 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
 U32 getVersionNumber();

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

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

+ 19 - 2
Engine/source/environment/meshRoad.cpp

@@ -49,6 +49,7 @@
 #include "collision/concretePolyList.h"
 #include "T3D/physics/physicsPlugin.h"
 #include "T3D/physics/physicsBody.h"
+#include "T3D/physics/physicsCollision.h"
 #include "environment/nodeListManager.h"
 
 #define MIN_METERS_PER_SEGMENT 1.0f
@@ -1722,6 +1723,8 @@ void MeshRoad::_generateSlices()
 
 void MeshRoad::_generateSegments()
 {
+   SAFE_DELETE( mPhysicsRep );
+
    mSegments.clear();
 
    for ( U32 i = 0; i < mSlices.size() - 1; i++ )
@@ -1736,8 +1739,22 @@ void MeshRoad::_generateSegments()
 
    if ( PHYSICSMGR )
    {
-      SAFE_DELETE( mPhysicsRep );
-      //mPhysicsRep = PHYSICSMGR->createBody();
+      ConcretePolyList polylist;
+      if ( buildPolyList( PLC_Collision, &polylist, getWorldBox(), getWorldSphere() ) )
+      {
+         polylist.triangulate();
+
+         PhysicsCollision *colShape = PHYSICSMGR->createCollision();
+         colShape->addTriangleMesh( polylist.mVertexList.address(),
+            polylist.mVertexList.size(),
+            polylist.mIndexList.address(),
+            polylist.mIndexList.size() / 3,
+            MatrixF::Identity );
+
+         PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
+         mPhysicsRep = PHYSICSMGR->createBody();
+         mPhysicsRep->init( colShape, 0, 0, this, world );
+      }
    }
 }
 

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

@@ -658,6 +658,11 @@ void ScatterSky::prepRenderImage( SceneRenderState *state )
       mFlareState.lightMat.identity();
       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 );
    }
 

+ 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(GFX->mFrameTime->getElapsedMs()>4)
           {
+              this->begin();
               this->end();
               return NotOccluded;
           }

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

@@ -82,4 +82,71 @@ public:
    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_

+ 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...
       mItemHeight = getMax((S32)mFont->getHeight(), (S32)mProfile->mBitmapArrayRects[0].extent.y);
    }
+   
+   mFlags.set(RebuildVisible);
 
    return true;
 }

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

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

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

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

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

@@ -73,7 +73,7 @@ public:
    /// The cubemap to use when the texture type is
    /// set to Material::Cube.
    /// @see mTexType
-   GFXCubemap *mCubeMap;
+   GFXCubemapHandle mCubeMap;
 
    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.
    // 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() );
    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.
 
       if( !numClippedPolygonVertices )
-         return false;
+         return 0;
 
       // On first iteration, replace the inVertices with the
       // outVertices buffer.

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

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

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

@@ -25,7 +25,7 @@
 
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureData.h"
-
+#include "terrain/terrFeatureTypes.h"
 
 void EyeSpaceDepthOutHLSL::processVert(   Vector<ShaderComponent*> &componentList, 
                                           const MaterialFeatureData &fd )
@@ -85,7 +85,12 @@ void EyeSpaceDepthOutHLSL::processPix( Vector<ShaderComponent*> &componentList,
    LangElement *depthOutDecl = new DecOp( depthOut );
 
    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" ) );
 
    Var *farDist = (Var*)Var::find( "oneOverFarplane" );

+ 2 - 2
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)
@@ -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.
 * [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.
 
 If you're looking for an older release see the [Torque 3D Archive](https://github.com/GarageGames/Torque3D/wiki/Torque-3D-Archive)

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

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

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

@@ -192,9 +192,9 @@ datablock ShapeBaseImageData(RyderWeaponImage)
    lightBrightness = 2;
 
    // 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
    // are run, which sounds are played, script callbacks, etc. This
@@ -361,4 +361,5 @@ datablock ShapeBaseImageData(RyderWeaponImage)
    stateSequenceTransitionOut[13]   = true;
    stateAllowImageChange[13]        = false;
    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
    %this.setImageTrigger(0, true);
    %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);
 }
 
 //-----------------------------------------------------------------------------