diff --git a/Engine/source/T3D/aiPlayer.cpp b/Engine/source/T3D/aiPlayer.cpp index f553cfb0c..31a49d469 100644 --- a/Engine/source/T3D/aiPlayer.cpp +++ b/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; @@ -701,7 +701,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), diff --git a/Engine/source/T3D/fps/guiShapeNameHud.cpp b/Engine/source/T3D/fps/guiShapeNameHud.cpp index 9ec1afac4..0609bbd0e 100644 --- a/Engine/source/T3D/fps/guiShapeNameHud.cpp +++ b/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 diff --git a/Engine/source/T3D/fx/explosion.cpp b/Engine/source/T3D/fx/explosion.cpp index 3fd5b4a2c..462c0d38a 100644 --- a/Engine/source/T3D/fx/explosion.cpp +++ b/Engine/source/T3D/fx/explosion.cpp @@ -615,7 +615,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) diff --git a/Engine/source/T3D/fx/particle.cpp b/Engine/source/T3D/fx/particle.cpp index 5b794748e..bf9e987f8 100644 --- a/Engine/source/T3D/fx/particle.cpp +++ b/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); diff --git a/Engine/source/T3D/fx/particleEmitter.cpp b/Engine/source/T3D/fx/particleEmitter.cpp index 6890f3c77..2391cfe9d 100644 --- a/Engine/source/T3D/fx/particleEmitter.cpp +++ b/Engine/source/T3D/fx/particleEmitter.cpp @@ -1833,22 +1833,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; } diff --git a/Engine/source/T3D/gameFunctions.cpp b/Engine/source/T3D/gameFunctions.cpp index 010cc9e5e..a6a51a57d 100644 --- a/Engine/source/T3D/gameFunctions.cpp +++ b/Engine/source/T3D/gameFunctions.cpp @@ -228,7 +228,7 @@ void GameUpdateCameraFov() F32 delta = time - CameraAndFOV::sLastCameraUpdateTime; // snap zoom? - if((CameraAndFOV::sZoomSpeed == 0) || (delta <= 0.f)) + if((CameraAndFOV::sZoomSpeed == 0) || (delta <= 0.0f)) CameraAndFOV::sCameraFov = CameraAndFOV::sTargetFov; else { diff --git a/Engine/source/T3D/lightFlareData.cpp b/Engine/source/T3D/lightFlareData.cpp index 4a2b9c355..2fae80fa9 100644 --- a/Engine/source/T3D/lightFlareData.cpp +++ b/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(); - 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(); + 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(); diff --git a/Engine/source/T3D/lightFlareData.h b/Engine/source/T3D/lightFlareData.h index a450d4e56..333bf1bf5 100644 --- a/Engine/source/T3D/lightFlareData.h +++ b/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 vertBuffer; - GFXOcclusionQuery *occlusionQuery; - GFXOcclusionQuery *fullPixelQuery; + GFXOcclusionQueryHandle occlusionQuery; + GFXOcclusionQueryHandle fullPixelQuery; }; class LightFlareData : public SimDataBlock diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 241be2c2f..f9278e62b 100644 --- a/Engine/source/T3D/player.cpp +++ b/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); diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index f1d787f08..e5266b855 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/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 { diff --git a/Engine/source/T3D/shapeBase.h b/Engine/source/T3D/shapeBase.h index a46a41580..55499a8e7 100644 --- a/Engine/source/T3D/shapeBase.h +++ b/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); diff --git a/Engine/source/T3D/shapeImage.cpp b/Engine/source/T3D/shapeImage.cpp index e4752019c..cc8022b24 100644 --- a/Engine/source/T3D/shapeImage.cpp +++ b/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 ) else 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(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); + } + } +} diff --git a/Engine/source/app/version.h b/Engine/source/app/version.h index 9f68b2cbc..4a03f5ddc 100644 --- a/Engine/source/app/version.h +++ b/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(); diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 9d35bd0d1..550027a63 100644 --- a/Engine/source/console/simObject.cpp +++ b/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; diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 4155ce7ac..5b5b6df5c 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -666,6 +666,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 ); } diff --git a/Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.cpp b/Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.cpp index 99e664652..8d36776ca 100644 --- a/Engine/source/gfx/D3D9/gfxD3D9OcclusionQuery.cpp +++ b/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; } diff --git a/Engine/source/gfx/gfxOcclusionQuery.h b/Engine/source/gfx/gfxOcclusionQuery.h index 9bf87c46d..ac6b0bf07 100644 --- a/Engine/source/gfx/gfxOcclusionQuery.h +++ b/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_ \ No newline at end of file diff --git a/Engine/source/gui/controls/guiTreeViewCtrl.cpp b/Engine/source/gui/controls/guiTreeViewCtrl.cpp index 4b2fed88f..dd4d9a037 100644 --- a/Engine/source/gui/controls/guiTreeViewCtrl.cpp +++ b/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; } diff --git a/Engine/source/lighting/common/projectedShadow.cpp b/Engine/source/lighting/common/projectedShadow.cpp index 8918ddf5a..1ad88cd10 100644 --- a/Engine/source/lighting/common/projectedShadow.cpp +++ b/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. diff --git a/Engine/source/materials/matInstance.cpp b/Engine/source/materials/matInstance.cpp index 2bb8e52ed..273a4cb3d 100644 --- a/Engine/source/materials/matInstance.cpp +++ b/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(); diff --git a/Engine/source/materials/processedMaterial.h b/Engine/source/materials/processedMaterial.h index 5fb4075a5..a77908959 100644 --- a/Engine/source/materials/processedMaterial.h +++ b/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; diff --git a/Engine/source/math/mPlane.h b/Engine/source/math/mPlane.h index cb83788e1..a67d5c60b 100644 --- a/Engine/source/math/mPlane.h +++ b/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 ) diff --git a/Engine/source/math/mPlaneSet.h b/Engine/source/math/mPlaneSet.h index abeebd4dc..8d0a919bb 100644 --- a/Engine/source/math/mPlaneSet.h +++ b/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. diff --git a/Engine/source/platform/nativeDialogs/msgBox.h b/Engine/source/platform/nativeDialogs/msgBox.h index 218e76f7a..4c81e7715 100644 --- a/Engine/source/platform/nativeDialogs/msgBox.h +++ b/Engine/source/platform/nativeDialogs/msgBox.h @@ -32,7 +32,7 @@ enum MBButtons { - MBOk, + MBOk = 0, MBOkCancel, MBRetryCancel, MBSaveDontSave, @@ -42,7 +42,7 @@ enum MBButtons enum MBIcons { - MIWarning, + MIWarning = 0, MIInformation, MIQuestion, MIStop, diff --git a/Engine/source/shaderGen/HLSL/depthHLSL.cpp b/Engine/source/shaderGen/HLSL/depthHLSL.cpp index 9f5726a51..ecb23d676 100644 --- a/Engine/source/shaderGen/HLSL/depthHLSL.cpp +++ b/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 &componentList, const MaterialFeatureData &fd ) @@ -85,7 +85,12 @@ void EyeSpaceDepthOutHLSL::processPix( Vector &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" ); diff --git a/README.md b/README.md index e121b7443..1ef223d89 100644 --- a/README.md +++ b/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) @@ -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 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. \ No newline at end of file +IN THE SOFTWARE. diff --git a/Templates/Full/game/art/datablocks/player.cs b/Templates/Full/game/art/datablocks/player.cs index 27933628c..e920b3cce 100644 --- a/Templates/Full/game/art/datablocks/player.cs +++ b/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 diff --git a/Templates/Full/game/art/datablocks/weapons/Ryder.cs b/Templates/Full/game/art/datablocks/weapons/Ryder.cs index a94bfa8d6..7e0436aa0 100644 --- a/Templates/Full/game/art/datablocks/weapons/Ryder.cs +++ b/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"; }; diff --git a/Templates/Full/game/scripts/server/aiPlayer.cs b/Templates/Full/game/scripts/server/aiPlayer.cs index b9f5a66a6..70d7a2453 100644 --- a/Templates/Full/game/scripts/server/aiPlayer.cs +++ b/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); } //-----------------------------------------------------------------------------